3

Linear Congruential Generators ( http://en.wikipedia.org/wiki/Linear_congruential_generator ) を使用して、ユーザーに公開される ID を生成します。

nextID = (a * LastID + c) % m

今、Redis で LCG を実装したいと考えています。ここに問題があります: 現在の ID を取得し、Redis の外部で次の ID を生成することは、マルチユーザーに対して安全ではありません。Redis には単純なカウンターに使用できる 2 つのコマンドがあります: INCRBY と INCRBYFLOAT ですが、残念ながら Redis はモジュロ操作をネイティブでサポートしていません。現時点では、EVAL コマンドを使用して lua スクリプトを作成する方法しかありません。

更新1:

いくつかの lua アナログ

INCRBY LCG_Value ((LCG_Value*a+c)%m)-LCG_Value

これを達成するためのきちんとした方法のようです。

4

1 に答える 1

3

サーバー側の Lua スクリプトは、おそらく最も簡単で効率的な方法です。

multi/exec ブロックを使用した Redis プリミティブ操作を使用して実行することもできます。ここに疑似コードがあります:

while not successful:
   WATCH LCG_Value
      $LastID = GET LCG_value
      $NextID = (a*$LastID+c)%m
   MULTI
      SET LCG_value $NextID
   EXEC

もちろん、次の Lua スクリプトよりも効率的ではありません。

# Set the initial value
SET LCG_value 1

# Execute Lua script with on LCG_value with a, c, and m parameters
EVAL "local last = tonumber(redis.call( 'GET', KEYS[1]));
      local ret = (last*ARGV[1] + ARGV[2])%ARGV[3];
      redis.call('SET',KEYS[1], ret);
      return ret;
" 1 LCG_value 1103515245 12345 2147483648

注: スクリプトの実行全体はアトミックです。EVALのドキュメントを参照してください。

于 2013-06-11T06:59:44.720 に答える