web-dev-qa-db-ja.com

StackExchange.Redis server.Keys(pattern: "IsVerySlow *")

私はredisを初めて使用するので、何か間違ったことをしていると確信しています。

AzureRedisに約16,000のキー/値を格納しました。

私は以下を使用してキー/値を記述しました

      foreach (var worksheet in wksList)
      {
        var wksYYMM = string.Format("{0}{1:00}", worksheet.ReviewDt.Year, worksheet.ReviewDt.Month);
        var wksKey = string.Format("{0}:{1}:{2}", provCode, wksYYMM, worksheet.AcctNbr);
        string jsonStr = JsonConvert.SerializeObject( MakeWsListDto(worksheet, provCoderList, rvrList));
        cache.StringSet(wksKey, jsonStr);
      }

だから私のキーは次のようになります: "AP:201401:AZ5798BK"

次のようなルックアップを試みると:

    var keys = server.Keys(pattern: "AP:201401:*"); // returns in milliseconds
    var keyAry = keys.ToArray(); // returns in over one minute
    (note: this returns 12 keys)

キーを返すのに1分12秒かかります。キーを取得したら、それらの値を取得するのに数ミリ秒かかります。キーの値を繰り返し処理して値を返すと、同様の結果が得られます。問題を特定するためだけにToArray()を実行しました。

Redis-cli.exeで同じクエリを実行すると、ミリ秒単位で返されます。

このコマンドを間違って使用していますか?

15
Weej

server.Keysは、サーバーのバージョンに基づいて、KEYSと優先SCANのどちらかを自動的に選択します。したがって、ページサイズが小さすぎるSCANを使用していることが何が起こっているのかと思います。ページサイズのオプションのパラメータがあります。デフォルトよりもかなり大きいもの(数百、数千など)を指定してみてください。指定しない場合、ページサイズはRedis SCANのデフォルトである10を使用します。これにより、多くのラウンドトリップが発生する可能性があります。必要とされている。

23
Marc Gravell

KEYSは使用しないでください。これは、実行中にRedisサーバーを他のリクエストで使用できないようにするブロッキングコマンドです。 コマンドのドキュメントからの引用

警告:KEYSは、本番環境でのみ使用する必要があるコマンドと見なしてください。大規模なデータベースに対して実行すると、パフォーマンスが低下する可能性があります。このコマンドは、デバッグと、キースペースレイアウトの変更などの特別な操作を目的としています。通常のアプリケーションコードではKEYSを使用しないでください。キースペースのサブセットでキーを見つける方法を探している場合は、SCANまたはセットの使用を検討してください。

警告をよく読むと、段落の最後に推奨されるアプローチ、つまり [〜#〜] scan [〜#〜] またはRedisのセットを使用していることがわかります。 SCANはノンブロッキングですが、あなたの質問はあなたがパフォーマンスに興味があることを示唆しているので、セットを使用することをお勧めします。

アイデアは、その「パターン」に関連付けられているすべてのキー名でRedisセットを維持することです。したがって、この例では、SADD AP:201401 AP:201401:AZ5798BKを呼び出した後、StackExchange.Redisと同等のcache.SetStringを実行する必要があります。例:

cache.SetAdd(wksYYMM, wksKey);

免責事項:私はC#プログラマーではなく、StackExchange.Redisに精通していません(申し訳ありませんがMarc;))

さて、キーを取得するためにKEYSまたはSCANの代わりに、SMEMBERS AP:201401を実行するか、おそらく次のようにします。

var keys = cache.Members(wksYYMM);

ボーナス:これらのキーの値に実際に関心があるので、RedisのLuaスクリプトを使用して、セットの値に基づいてキーの値をフェッチできます。メンバー、または単に [〜#〜] sort [〜#〜] を使用します。

Pure Redis:

SORT AP:201401 BY nosort GET *`

C#&StackExchange.Redis:

vals = cache.Sort(wksYYMM, by = "nosort", get = "*");
8
Itamar Haber