Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Jak poprawić wykorzystanie procesora przez serwer Redis?

Wątpię, aby maksymalizacja wykorzystania procesora przez Redis była korzystna dla twojego projektu zaplecza. Właściwym pytaniem jest raczej, czy Redis jest wystarczająco wydajny, aby utrzymać przepustowość przy danym opóźnieniu. Redis jest serwerem jednowątkowym:przy 80% zużyciu procesora opóźnienie będzie prawdopodobnie bardzo złe.

Proponuję zmierzyć opóźnienie, gdy test Redis działa, aby sprawdzić, czy jest on akceptowalny dla twoich potrzeb, zanim spróbujesz zwiększyć zużycie procesora Redis. W tym celu można użyć opcji --latency z redis-cli:

  • uruchom serwer redis
  • spróbuj redis-cli --latency, zanotuj średnią wartość, zatrzymaj ją
  • w innym oknie uruchom test porównawczy i upewnij się, że działa przez chwilę
  • spróbuj redis-cli --latency, zanotuj średnią wartość, zatrzymaj ją
  • zatrzymaj test porównawczy
  • porównaj dwie średnie wartości

Teraz, jeśli naprawdę chcesz zwiększyć zużycie procesora Redis, potrzebujesz wydajnego programu klienckiego (takiego jak redis-benchmark), zdolnego do obsługi wielu połączeń jednocześnie, albo wielu wystąpień programu klienckiego.

Lua jest językiem szybko tłumaczonym, ale nadal jest językiem tłumaczonym. Będzie o jeden lub dwa rzędy wielkości wolniejszy niż kod C. Redis jest znacznie szybszy w przetwarzaniu/generowaniu swojego protokołu niż lua-redis, więc nie będziesz w stanie nasycić Redisa unikalnym klientem Lua (z wyjątkiem sytuacji, gdy używasz poleceń O(n) Redis – zobacz dalej).

Webdis jest zaimplementowany w C, z wydajną biblioteką kliencką, ale musi analizować protokoły http/json, które są bardziej szczegółowe i złożone niż protokół Redis. Prawdopodobnie zużywa więcej procesora niż sam Redis dla większości operacji. Więc znowu, nie nasycisz Redisa pojedynczą instancją webdis.

Oto kilka przykładów nasycenia Redis wieloma klientami Lua.

Jeśli jeszcze tego nie zrobiono, sugeruję, abyś najpierw zajrzał na stronę testu Redis.

Jeśli uruchamiasz test porównawczy na tym samym polu, co Redis:

Kluczowym punktem jest dedykowanie rdzenia Redis i uruchamianie programów klienckich na pozostałych rdzeniach. W systemie Linux możesz użyć do tego polecenia taskset.

# Start Redis on core 0
taskset -c 0 redis-server redis.conf

# Start Lua programs on the other cores
for x in `seq 1 10` ; do taskset -c 1,2,3 luajit example.lua & done

Program Lua powinien wykorzystywać potokowanie, aby zmaksymalizować przepustowość i zmniejszyć aktywność systemu.

local redis = require 'redis'
local client = redis.connect('127.0.0.1', 6379)
for i=1,1000000 do
    local replies = client:pipeline(function(p)
    for j=1,1000 do
            local key = 'counter:'..tostring(j)
            p:incrby(key,1)
        end
    end)
end

W moim systemie program Lua zajmuje więcej niż 4 razy więcej procesora niż Redis, więc potrzebujesz więcej niż 4 rdzeni, aby nasycić Redis tą metodą (pole 6 rdzeni powinno wystarczyć).

Jeśli uruchamiasz test porównawczy na innym polu niż Redis:

Z wyjątkiem sytuacji, gdy korzystasz z maszyn wirtualnych pozbawionych procesora, w tym przypadku wąskim gardłem będzie prawdopodobnie sieć. Nie sądzę, że można nasycić Redis czymkolwiek mniejszym niż łącze 1 GbE.

Pamiętaj, aby potokować zapytania tak daleko, jak to możliwe (zobacz poprzedni program Lua), aby uniknąć wąskiego gardła opóźnień w sieci i zmniejszyć koszt przerwań sieciowych w procesorze (wypełnianie pakietów ethernetowych). Spróbuj uruchomić Redis na rdzeniu, który nie jest powiązany z kartą sieciową (i przetwarza przerwania sieciowe). Możesz użyć narzędzi takich jak htop, aby sprawdzić ten ostatni punkt.

Spróbuj uruchomić klientów Lua na różnych innych komputerach w sieci, jeśli możesz. Ponownie będziesz potrzebować dużej liczby klientów Lua do nasycenia Redisa (6-10 powinno wystarczyć).

W niektórych przypadkach wystarczy unikalny proces Lua:

Teraz możliwe jest nasycenie Redis jednym klientem Lua, jeśli każde zapytanie jest wystarczająco drogie. Oto przykład:

local redis = require 'redis'
local client = redis.connect('127.0.0.1', 6379)

for i=1,1000 do
    local replies = client:pipeline(function(p)
        for j=1,1000 do
            p:rpush("toto",i*1000+j)
        end
    end)
end

N = 500000
for i=1,100000 do
    local replies = client:pipeline(function(p)
        for j=1,10 do
            p:lrange("toto",N, N+10)
        end
    end)
end

Ten program wypełnia listę 1 mln pozycji, a następnie używa poleceń lrange, aby pobrać 10 pozycji ze środka listy (najgorszy przypadek dla Redis). Tak więc za każdym razem, gdy wykonywane jest zapytanie, serwer skanuje 500 000 elementów. Ponieważ zwracanych jest tylko 10 elementów, można je szybko przeanalizować przez lua-redis, co nie zużywa procesora. W tej sytuacji całe zużycie procesora będzie po stronie serwera.

Końcowe słowa

Prawdopodobnie istnieją szybsze klienty Redis niż redis-lua:

  • https://github.com/agladysh/lua-hiredis (na podstawie Hiredis)
  • https://github.com/agladysh/ljffi-hiredis (na podstawie Hireddis, używając luajit FFI)

Możesz je wypróbować.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. jak przechowywać Json w redis za pomocą hashmap ( HSET )

  2. Opcja dopasowania polecenia skanowania Redis nie działa w Pythonie

  3. Łączenie się z zarządzanym redis z uwierzytelnioną nazwą użytkownika/hasłem nodejs

  4. Funkcja Google Cloud wygasa podczas łączenia się z Redis przez wewnętrzny adres IP Compute Engine

  5. Serie RedisTimeoutException przy użyciu StackExchange.Redis