/ / Która metoda buforowania jest najszybsza / najlżejsza w przypadku Node / Mongo / NginX? - node.js, caching, nginx, redis, varnish

Która metoda buforowania jest najszybsza / najlżejsza dla Node / Mongo / NginX? - node.js, caching, nginx, redis, varnish

Otrzymałem zadanie pracy nad projektem dlaklient, który ma witrynę, którą szacuje, otrzyma 1-2 mln odwiedzin dziennie. Ma istniejącą bazę danych 58 milionów użytkowników, którzy muszą zostać rozstawieni na podstawie jednej rejestracji dla nowej marki. Większość treści witryny jest obsługiwana z danych dostarczonych przez zewnętrzny interfejs API, a większość danych przechowywanych w naszej konfiguracji Mongo to informacje o profilu i zapisane parametry API.

NginX będzie na porcie 80 i będzie równoważony obciążeniem do klastra węzłów na portach 8000 - 8010.

Moje pytanie brzmi, co zrobić z buforowaniem. Pochodzę z tła LAMP, więc jestem przyzwyczajony do pisania statycznych plików HTML za pomocą PHP i udostępniania ich w celu zminimalizowania obciążenia MySQL lub używania Memcached w witrynach, które wymagają wyższego poziomu buforowania. Ta konfiguracja jest dla mnie trochę obca.

Co jest najbardziej idealne pod względem minimalny czas odpowiedzi i obciążenie procesora?

1: Buforowanie na poziomie strony za pomocą NginX

Odniesienie: http://andytson.com/blog/2010/04/page-level-caching-with-nginx/

server {
listen            80;
servername        mysite.com;

proxy_set_header  X-Real-IP  $remote_addr;
proxy_set_header  Host       $host;

location / {
proxy_pass    http://localhost:8080/;
proxy_cache   anonymous;
}

# don"t cache admin folder, send all requests through the proxy
location /admin {
proxy_pass    http://localhost:8080/;
}

# handle static files directly. Set their expiry time to max, so they"ll
# always use the browser cache after first request
location ~* (css|js|png|jpe?g|gif|ico)$ {
root          /var/www/${host}/http;
expires       max;
}
}


2: Redis jako zasobnik pamięci podręcznej

The hash() funkcja to numbers() funkcja na tej stronie: http://jsperf.com/hashing-strings

function hash(str) {
var res = 0,
len = str.length;
for (var i = 0; i < len; i++) {
res = res * 31 + str.charCodeAt(i);
}
return res;
}

var apiUrl = "https://www.myexternalapi.com/rest/someparam/someotherparam/?auth=3dfssd6s98d7f09s8df98sdef";
var key    = hash(apiUrl).toString(); // 1.8006908172911553e+136

myRedisClient.set(key,theJSONresponse, function(err) {...});


3: Węzeł zapisuje pliki JSON

The hash() funkcja to numbers() funkcja na tej stronie: http://jsperf.com/hashing-strings

function hash(str) {
var res = 0,
len = str.length;
for (var i = 0; i < len; i++) {
res = res * 31 + str.charCodeAt(i);
}
return res;
}

var fs     = require("fs");
var apiUrl = "https://www.myexternalapi.com/rest/someparam/someotherparam/?auth=3dfssd6s98d7f09s8df98sdef";
var key    = hash(apiUrl).toString(); // 1.8006908172911553e+136

fs.writeFile("/var/www/_cache/" + key + ".json", theJSONresponse, function(err) {...});


4: Lakier z przodu

Zrobiłem kilka badań i testy porównawcze, takie jak te pokazane na tej stronie, odciągają mnie od tego rozwiązania, ale nadal jestem otwarty na rozważenie tego, jeśli ma to największy sens: http://todsul.com/nginx-varnish

Odpowiedzi:

17 dla odpowiedzi nr 1

Zrobiłbym kombinację i użyłbym Redis do buforowaniawywołania interfejsu API użytkownika sesji, które mają krótki TTL i używają Nginx do buforowania długoterminowych danych RESTless i zasobów statycznych. Nie zapisałbym plików JSON, ponieważ wyobrażam sobie, że IO systemu plików będzie najwolniejszym i najbardziej obciążającym procesor z wymienionych opcji.


4 dla odpowiedzi nr 2
  1. Buforowanie na poziomie strony nginx jest dobre do buforowania zawartości statycznej. Ale w przypadku zawartości dynamicznej nie jest to dobre. Na przykład, jak unieważnić pamięć podręczną, jeśli zawartość zostanie zmieniona w źródle?

  2. Redis jest idealny do przechowywania danych w pamięci. Ale nie lubię używać go jako pamięci podręcznej. Przy ograniczonej ilości pamięci muszę ciągle martwić się, że zabraknie pamięci. Tak, możesz ustawić strategię utraty ważności kluczy w redis. Ale to dodatkowa praca i nadal nie tak dobry, jak chcę, aby był dostawcą pamięci podręcznej.

Nie mam doświadczenia w wyborze 3 i 4.

Dziwię się, że nie dołączasz memcachetutaj jako opcja. Z mojego doświadczenia wynika, że ​​jest solidnym dostawcą pamięci podręcznej. Jedną z funkcji memcache, której nie ma w Redis, jest to, że nie gwarantuje ona, że ​​klucz nie wygaśnie przed upływem podanego czasu. Jest to złe dla magazynu danych, ale sprawia, że ​​memcache jest idealnym kandydatem do buforowania: nie musisz martwić się o zużycie pamięci przypisanej do memcache. Memcache usunie rzadziej używane klucze (pamięć podręczna rzadziej używana), nawet jeśli wygaśnie czas tych kluczy nie został jeszcze osiągnięty.

Nginx zapewnia tę wbudowaną moduł memcache. Jest solidna. Wiele samouczków, jeśli korzystasz z wyszukiwarki Google.

Ten, który mi się najbardziej podoba (patrz link poniżej). Unieważnienie pamięci podręcznej jest łatwe: na przykład, jeśli strona jest aktualizowana nadrzędnie, po prostu usuń klucz memcache z nadrzędnego serwera aplikacji. Autor stwierdził czterokrotny wzrost czasu odpowiedzi. Uwierz, że jest wystarczająco dobry dla twojego przypadku użycia.

http://www.igvita.com/2008/02/11/nginx-and-memcached-a-400-boost/


1 dla odpowiedzi nr 3

Co do lakieru to nie mam zamiaru rozszyfrowaćtesty porównawcze w witrynie, którą znalazłeś, ale mogę powiedzieć, że są to okropnie złe liczby i nie mają nic wspólnego z implementacją o dużym natężeniu ruchu (wyszukaj w Google optymalizację lakieru i zobacz testy pokazujące 100-200 000 żądań / s zamiast 8 000).

Nginx jest również dobrym wyborem dla pamięci podręcznej stron, a przy 1-2 milionach trafień dziennie nie potrzebujesz ekstremalnej wydajności. Wybierz więc to, z czym czujesz się bardziej komfortowo podczas pracy.

Te dwa rozwiązania węzłowe są naprawdę gorszym wyborem. Pamięć podręczna stron powinna być oddzielona od aplikacji dynamicznej, aby zapewnić zarówno niezawodność, jak i wydajność.

Ponadto redis / memcached najlepiej pomoże w skalowaniu aplikacji, jeśli używasz jej jako pamięci podręcznej obiektów lub pamięci podręcznej dla powszechnie używanych danych deserializowanych.