Redis
 sql >> база данни >  >> NoSQL >> Redis

Как да подобрим използването на процесора на Redis сървъра?

Съмнявам се, че максимизирането на използването на процесора на Redis ще бъде от полза за вашия бекенд дизайн. Правилният въпрос е по-скоро дали Redis е достатъчно ефективен, за да поддържа вашата пропускателна способност при дадена латентност. Redis е еднонишков сървър:при 80% консумация на процесора латентността вероятно ще бъде много лоша.

Предлагам ви да измервате латентността, докато redis-benchmark работи, за да видите дали е приемливо за вашите нужди, преди да се опитате да увеличите консумацията на Redis CPU. Опцията --latency на redis-cli може да се използва за това:

  • стартирайте redis-сървър
  • опитайте redis-cli --latency, обърнете внимание на средната стойност, спрете го
  • в друг прозорец стартирайте бенчмарка и се уверете, че работи известно време
  • опитайте redis-cli --latency, обърнете внимание на средната стойност, спрете го
  • спрете бенчмарка
  • сравнете двете средни стойности

Сега, ако наистина искате да увеличите консумацията на Redis CPU, имате нужда или от ефективна клиентска програма (като redis-benchmark), която може да обработва множество връзки едновременно, или няколко екземпляра на вашата клиентска програма.

Lua е бързо интерпретиран език, но все пак е интерпретиран език. Той ще бъде с един или два порядъка по-бавен от C кода. Redis е много по-бърз при анализиране/генериране на своя протокол от lua-redis, така че няма да можете да наситите Redis с уникален клиент на Lua (освен ако използвате O(n) команди Redis – вижте по-късно).

webdis е внедрен в C, с ефективна клиентска библиотека, но трябва да анализира http/json протоколите, които се оказват по-подробни и сложни от протокола Redis. Вероятно консумира повече CPU от самия Redis за повечето операции. Така че отново няма да наситите Redis с един екземпляр на webdis.

Ето няколко примера за насищане на Redis с множество Lua клиенти.

Ако все още не е направено, предлагам първо да разгледате страницата за сравнителен анализ на Redis.

Ако стартирате своя бенчмарк в същото поле като Redis:

Ключовият момент е да посветите ядрото на Redis и да стартирате клиентските програми на другите ядра. В Linux можете да използвате командата 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

Програмата Lua трябва да използва конвейер, за да увеличи максимално пропускателната способност и да намали системната активност.

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

В моята система програмата Lua заема повече от 4 пъти CPU от Redis, така че имате нужда от повече от 4 ядра, за да наситите Redis с този метод (кутия с 6 ядра трябва да е добре).

Ако стартирате своя бенчмарк в кутия, различна от Redis:

Освен ако работите на виртуални машини с недостатъчен процесор, тясното място вероятно ще бъде мрежата в този случай. Не мисля, че можете да наситите Redis с нещо по-малко от 1 GbE връзка.

Уверете се, че сте изпълнили заявките си, доколкото можете (вижте предишната програма Lua), за да избегнете тесното място на мрежовата латентност и да намалите цената на мрежовите прекъсвания на процесора (запълване на Ethernet пакети). Опитайте да стартирате Redis на ядро, което не е свързано с мрежовата карта (и обработва прекъсвания на мрежата). Можете да използвате инструменти като htop, за да проверите тази последна точка.

Опитайте се да стартирате вашите Lua клиенти на различни други машини в мрежата, ако можете. Отново ще ви трябва голям брой клиенти на Lua, за да наситите Redis (6-10 трябва да са добре).

В някои случаи е достатъчен уникален процес на Lua:

Сега е възможно да наситите Redis с един клиент на Lua, ако всяка заявка е достатъчно скъпа. Ето един пример:

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

Тази програма попълва списък с 1M елемента и след това използва команди lrange, за да извлече 10 елемента от средата на списъка (най-лошият случай за Redis). Така че всеки път, когато се изпълни заявка, 500K елемента се сканират от сървъра. Тъй като се връщат само 10 елемента, те се анализират бързо от lua-redis, което няма да изразходва процесора. В тази ситуация цялото потребление на процесора ще бъде от страна на сървъра.

Последни думи

Вероятно има по-бързи клиенти на Redis от redis-lua:

  • https://github.com/agladysh/lua-hiredis (базирано на hiredis)
  • https://github.com/agladysh/ljffi-hiredis (базирано на hiredis, с помощта на luajit FFI)

Може да искате да ги опитате.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Комуникация в реално време между приложение и уеб страница

  2. Redis/Jedis няма единична точка на отказ и автоматично преминаване при отказ

  3. C#/.NET клиент за Redis

  4. Кой е най-ефективният във времето начин за сериализиране/десериализиране на DataTable към/от Redis?

  5. има ли начин да получа IP на клиента в redis?