1

Ruby 1.8.7 と redis-rb gem を使用しています。Redis リストに 100 万件のレコードを書き込むために、さまざまな方法を試しました。

スレッドを使用しているときにパフォーマンスが低下していることに気付きました。その理由は何ですか?どうすればそれを防ぐことができますか? スレッド化された環境で本番用にRedisを使用するので、心配です。

ここに私の結果があります:

1_000_000.times do
  $r.rpush "test_list", rand(1_000_000)
end
# Took: 74.2986769676208 sec.

threads = []
1_000.times do
  threads << Thread.new {
    1_000.times {
      $r.rpush "test_list", rand(1_000_000)
    }
  }
end
threads.each { |k| k.join }
# Took: 391.705540895462 sec.

mutex = Mutex.new
threads = []
1_000.times do
  threads << Thread.new {
    1_000.times {
      mutex.synchronize {
        $r.rpush "test_list", rand(1_000_000)
      }
    }
  }
end
threads.each { |k| k.join }
# Took: 308.474660873413 sec.

mutex = Mutex.new
threads = []
10.times do
  threads << Thread.new {
    100_000.times {
      mutex.synchronize {
        $r.rpush "test_list", rand(1_000_000)
      }
    }
  }
end
threads.each { |k| k.join }
# Took: 109.103996992111 sec.

forks = []
8.times do
  forks << fork {
    125_000.times {
      $r.rpush "test_list", rand(1_000_000)
    }
  }
end
forks.each { |k| Process.wait(k) }
# Took: 23.7934968471527 sec.
4

1 に答える 1

0

バンプ!

多くのシナリオを示しているため、これは非常に良い例です。最初の例について疑問に思っているので、正しい数のエントリが redis の "test_list" にあると想定する必要がありますか? (カウントは、スレッドが結合された後に確認すると便利です)

だから、私の解釈:

1 スレッド、それぞれ 100 万回の書き込み

実行時間: 74 秒

シリアル化された書き込みによる redis への単一接続

1000 スレッド、それぞれ 100 回の書き込み、Ruby ミューテックスなし

実行時間: 380 秒

Redis が書き込みに独自のミューテックスを使用していると仮定する必要があると思うので、ここでの「オーバーヘッド」は Redis 独自のミューテックスの結果になります。これは、各スレッドが書き込み対象の同じクライアント オブジェクトを共有していることが原因である可能性があります - 1000 個の redis クライアントを作成しようとしましたか? :)

1000 スレッド、それぞれ 1000 書き込み、Ruby ミューテックス

実行時間: 308 秒

ミューテックスが ruby​​ スレッド内にあるため、Redis への書き込み (「設定」) がより整然と行われているようです。ここでのオーバーヘッドは、1 つのスレッドが Redis に書き込むのを待たなければならない 999 のスレッドです...

10 スレッド、それぞれ 100,000 回の書き込み、ローカル ミューテックス

実行時間: 108 秒

毎回ミューテックスを待機するスレッドが少なくなるため、書き込みのサイクルが速くなります。

8 フォーク、それぞれ 125,000 回の書き込み

実行時間: 23 秒

ここにはまだ少しオーバーヘッドがありますが、それ以外の場合は、8 つの異なる Redis 接続がそれぞれ 125,000 個のキーを書き込みます。Redisはそれをラップします...「オーバーヘッド」はルビープロセスの分岐にあると思います(そうでなければ、10秒程度の時間がかかると予想されます)

テストを用意していただきありがとうございます。これは非常に教育的なものであり、トレーニングの演習として開発者に見せるつもりです。

于 2014-10-01T00:35:19.053 に答える