sql >> Databáze >  >> NoSQL >> Redis

Jak zlepšit využití CPU serveru Redis?

Pochybuji, že maximalizace využití procesoru Redis prospěje vašemu backendovému designu. Správná otázka spíše zní, zda je Redis dostatečně efektivní, aby udržel vaši propustnost při dané latenci. Redis je jednovláknový server:při 80% spotřebě CPU bude latence pravděpodobně velmi špatná.

Navrhuji, abyste změřili latenci, zatímco redis-benchmark pracuje, abyste zjistili, zda je přijatelná pro vaše potřeby, než se pokusíte zvýšit spotřebu procesoru Redis. K tomu lze použít volbu --latency redis-cli:

  • spusťte redis-server
  • zkuste redis-cli --latency, poznamenejte si hodnotu avg, zastavte to
  • v dalším okně spusťte srovnávací test a ujistěte se, že chvíli běží
  • zkuste redis-cli --latency, poznamenejte si hodnotu avg, zastavte to
  • zastavit benchmark
  • porovnejte dvě průměrné hodnoty

Nyní, pokud opravdu chcete zvýšit spotřebu procesoru Redis, potřebujete buď efektivní klientský program (jako je redis-benchmark), schopný zpracovávat více připojení současně, nebo více instancí vašeho klientského programu.

Lua je rychle interpretovaný jazyk, ale stále je to interpretovaný jazyk. Bude o jeden nebo dva řády pomalejší než C kód. Redis je mnohem rychlejší při analýze/generování svého protokolu než lua-redis, takže nebudete moci nasytit Redis jedinečným Lua klientem (kromě případů, kdy používáte příkazy O(n) Redis – viz dále).

webdis je implementován v C s efektivní klientskou knihovnou, ale musí analyzovat protokoly http/json, které jsou shodou okolností podrobnější a složitější než protokol Redis. Pravděpodobně spotřebovává více CPU než samotný Redis pro většinu operací. Takže znovu, Redis nenasytíte jedinou instancí webdis.

Zde je několik příkladů nasycení Redis více klienty Lua.

Pokud jste to ještě neudělali, doporučuji, abyste se nejprve podívali na stránku srovnávacích testů Redis.

Pokud srovnávací test spustíte na stejném poli jako Redis:

Klíčovým bodem je vyhradit jádro Redis a spouštět klientské programy na ostatních jádrech. V systému Linux k tomu můžete použít příkaz 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 by měl používat zřetězení k maximalizaci propustnosti a snížení aktivity systému.

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

V mém systému zabírá program Lua více než 4krát více CPU než Redis, takže k nasycení Redis touto metodou potřebujete více než 4 jádra (6jádrový box by měl být v pořádku).

Pokud srovnávací test spustíte na jiném boxu než Redis:

Kromě případů, kdy běžíte na virtuálních počítačích s nedostatkem CPU, bude v tomto případě úzkým hrdlem pravděpodobně síť. Nemyslím si, že můžete Redis nasytit ničím menším než 1 GbE spojením.

Ujistěte se, že zřetězení vašich dotazů tak daleko, jak jen můžete (viz předchozí program Lua), abyste se vyhnuli úzkému místu latence sítě a snížili náklady na síťová přerušení na CPU (vyplňování ethernetových paketů). Zkuste spustit Redis na jádře, které není vázáno na síťovou kartu (a zpracovává přerušení sítě). Ke kontrole tohoto posledního bodu můžete použít nástroje jako htop.

Pokud můžete, zkuste své klienty Lua spustit na různých jiných počítačích v síti. K nasycení Redis budete opět potřebovat velký počet Lua klientů (6-10 by mělo být v pořádku).

V některých případech stačí unikátní Lua proces:

Nyní je možné nasytit Redis jediným klientem Lua, pokud je každý dotaz dostatečně drahý. Zde je příklad:

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

Tento program naplní seznam 1 milionem položek a poté pomocí příkazů lrange načte 10 položek ze středu seznamu (nejhorší případ pro Redis). Při každém provedení dotazu je tedy serverem naskenováno 500 tisíc položek. Protože je vráceno pouze 10 položek, lze je rychle analyzovat pomocí lua-redis, což nespotřebovává CPU. V této situaci bude veškerá spotřeba CPU na straně serveru.

Poslední slova

Pravděpodobně existují rychlejší klienti Redis než redis-lua:

  • https://github.com/agladysh/lua-hiredis (založeno na rentaldis)
  • https://github.com/agladysh/ljffi-hiredis (založeno na rentaldis, pomocí luajit FFI)

Možná je budete chtít vyzkoušet.




  1. Mongodb concat int a řetězec

  2. Redis se neaktualizuje při mnoha žádostech najednou

  3. Unikátní index v mongoose nefunguje

  4. Upozornění na ukončení podpory MongoDB mongoose