2

Redisでいくつかの書き込み制約を設定したいので、これらの制約をハッシュに格納することを考えていました。

私の最初のアイデアは、setコマンドを変更して、Redisに書き込む前にルールをチェックすることでした。そうすればチェックが超高速になると思っていました。もちろん、そのようなアプローチでは、Redisが変更されるたびに、より多くの変更が必要になります。これは、学校の割り当てに関するものだと考えると、少しハードコアだと思います。

2番目のアイデアは、Redisクライアントには2つのタイプがあるということです。1つはWebアプリケーション側(Webアプリケーションの複数のインスタンスである可能性があります)にあり、もう1つはRedisマシンにあります。この考えに基づいて私の質問が来ます。

  1. 2つのクライアント(ローカルとリモート)は、最初に制約をチェックしてからRedisに書き込む1つのクライアントと比較して、パフォーマンスが向上しますか?または、すべてを実行する1つのクライアントに固執する必要がありますか(phpredisまたはpredis、アプリケーションはPHP上にあり、制約チェックのためにいくつかの変更が加えられています)?

  2. 2つのクライアントを試すことができれば、ローカルクライアント(C、Lua、またはその他)を実装するのにどちらのプログラミング言語が適していますか?

4

1 に答える 1

2

Redisの動作自体を変更しようとするのではなく、最初にサーバー側のLuaスクリプトに制約を実装しようとします(Redis 2.6ブランチが必要です)。

Lua EVALスクリプトは、実際の書き込み操作を実行する前に、Redisにすでに保存されているデータを使用していくつかのチェックを簡単に実行できます。

これが例です。銀行口座を表す2つのキーがあり、口座間に安全なトランザクションを実装する必要があるとします。たとえば、両方のアカウントが存在し、ソースアカウントに必要な資金が含まれていることを確認する必要があります。

# set 2 accounts for John and Bob
set account:john 100
set account:bob 20

# transfer $10 from John to Bob, checking all constraints
eval "if redis.call('exists',KEYS[2])==1 and redis.call('get',KEYS[1])>=ARGV[1] then
         redis.call( 'incrby', KEYS[2], ARGV[1] )
         redis.call( 'incrby', KEYS[1], - ARGV[1] )
         return 1
      else
         error('invalid transaction')
      end" 2 account:john account:bob 10

Redisスクリプト機能に関するドキュメントは、http: //redis.io/commands#scriptingにあります(最初にEVALコマンドを参照してください)。

最初の質問に答えるために(そしてRedis 2.6を使用できない場合)、ローカルクライアントはUNIXドメインソケットを使用してRedisに接続し(TCPオーバーヘッドをバイパスする)、ネットワークラウンドトリップを節約できるため、パフォーマンスがわずかに向上します。しかし、これは非常に複雑になるという代償を伴います。

于 2012-04-23T10:20:35.273 に答える