4

私の目標は、Redis サーバーが本番環境で約 80% の CPU 使用率に達することです。これにより、CPU の使用率が低くならないようにすると同時に、成長やスパイクに備えて余裕を持たせることができるため、バックエンド サーバーの設計にメリットがあります。

Redis 独自のベンチマーク ツールを使用するredis-benchmarkと、CPU 使用率が約 100% に達するのは非常に簡単です。

    $ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50

このベンチマークでは、50 のクライアントを割り当てて、1,000,000 のリクエストを Redis サーバーにプッシュしました。

ただし、他のクライアント ツール ( redis-luawebdisなど) を使用している場合、最大 CPU 使用率は 60% 未満です。

と でいくつかのコードを参照webdisしましredis-luaた。webdisに依存しhiredisredis-luaLua で実装され、socket( lua-socket) に依存します。

これらのクライアントは、Redis ベンチマークと比較して遅すぎて、Redis CPU 消費を最大化できませんか?

でいくつかのコードも参照しましたredis-benchmark.c。ベンチマークの主な作業は で行われaeMainます。redis-benchmarkは Redis の高速コードを使用しているようですが、私のテスト クライアント (webdisおよびredis-lua) はそうではありません。

現在、私のクライアントには 2 つの選択肢があります。

  1. 使用するredis-lua
  2. 次のようなツールを使用しますwebdis

ただし、これら 2 つは Redis の CPU 使用率を最大化するものではありません (60% 未満)。他に選択肢はありますか?

または、redis-benchmarkツール自体の外で redis-server を完全に利用することは可能ですか?

4

1 に答える 1

9

Redis の CPU 使用率を最大化することがバックエンドの設計に役立つとは思えません。正しい質問は、特定のレイテンシーでスループットを維持するのに Redis が十分に効率的であるかどうかです。Redis はシングルスレッド サーバーです。80% の CPU 消費では、レイテンシーが非常に悪くなる可能性があります。

Redis の CPU 消費量を増やす前に、redis-benchmark が動作している間にレイテンシを測定して、ニーズに合っているかどうかを確認することをお勧めします。これには、redis-cli の --latency オプションを使用できます。

  • redis-server を起動
  • redis-cli --latency を試して、平均値に注意して、停止してください
  • 別のウィンドウで、ベンチマークを開始し、しばらく実行されることを確認します
  • redis-cli --latency を試して、平均値に注意して、停止してください
  • ベンチマークを停止します
  • 2 つの平均値を比較する

ここで、本当に Redis の CPU 消費量を増やしたい場合は、複数の接続を同時に処理できる効率的なクライアント プログラム (redis-benchmark など)、またはクライアント プログラムの複数のインスタンスが必要です。

Lua は高速なインタープリター言語ですが、それでもインタープリター言語です。C コードよりも 1 ~ 2 桁遅くなります。Redis は lua-redis よりもプロトコルの解析/生成がはるかに高速であるため、一意の Lua クライアントで Redis を飽和させることはできません (O(n) Redis コマンドを使用する場合を除く - 後述)。

webdis は効率的なクライアント ライブラリを使用して C で実装されていますが、Redis プロトコルよりも冗長で複雑な http/json プロトコルを解析する必要があります。ほとんどの操作で、Redis 自体よりも多くの CPU を消費する可能性があります。繰り返しますが、単一の webdis インスタンスで Redis を飽和状態にすることはありません。

複数の Lua クライアントで Redis を飽和させる例を次に示します。

まだ行っていない場合は、最初に 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 プログラムは Redis の 4 倍以上の CPU を使用するため、この方法で Redis を飽和させるには 4 コア以上が必要です (6 コアのボックスで問題ありません)。

Redis とは異なるボックスでベンチマークを実行する場合:

CPU 不足の仮想マシンで実行する場合を除いて、その場合のボトルネックはおそらくネットワークです。1 GbE リンクよりも少ないもので Redis を飽和させることはできないと思います。

ネットワーク遅延のボトルネックを回避し、CPU でのネットワーク割り込みのコストを削減する (イーサネット パケットを満たす) ために、できる限りクエリをパイプライン処理してください (前の Lua プログラムを参照してください)。ネットワーク カードにバインドされていない (そしてネットワーク割り込みを処理する) コアで Redis を実行してみてください。htop などのツールを使用して、この最後の点を確認できます。

可能であれば、ネットワークの他のさまざまなマシンで Lua クライアントを実行してみてください。繰り返しになりますが、Redis を飽和させるにはかなりの数の Lua クライアントが必要になります (6 ~ 10 で十分です)。

場合によっては、固有の Lua プロセスで十分です。

現在、各クエリのコストが十分に高い場合、単一の Lua クライアントで Redis を飽和させることができます。以下に例を示します。

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

このプログラムは、リストに 100 万個のアイテムを入力し、lrange コマンドを使用してリストの中央から 10 個のアイテムをフェッチします (Redis の場合は最悪のケース)。そのため、クエリが実行されるたびに、サーバーによって 50 万個のアイテムがスキャンされます。返される項目は 10 個のみであるため、CPU を消費しない lua-redis による解析が高速です。この状況では、すべての CPU 消費はサーバー側で発生します。

最後の言葉

おそらく redis-lua よりも高速な Redis クライアントがあります。

あなたはそれらを試してみることをお勧めします。

于 2013-04-25T12:19:37.323 に答える