17

私はredisが初めてなので、何か間違っていると確信しています:

Azure Redis には約 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 で同じクエリを実行すると、ミリ秒単位で返されます。

このコマンドの使い方は間違っていますか?

4

2 に答える 2

31

server.Keysサーバーのバージョンに基づいてKEYS、 と のいずれかを自動的に選択します。このように小さすぎるページサイズでSCAN使用していると思われます。SCANページ サイズのオプション パラメータがあります。デフォルトよりもかなり大きいものを指定してみてください - 数百、数千など。 指定しない場合、ページサイズは Redis のSCAN デフォルトの を使用します10

于 2014-10-18T13:17:03.737 に答える
11

使用しないでください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を使用できます。

純粋な Redis:

SORT AP:201401 BY nosort GET *`

C# & StackExchange.Redis:

vals = cache.Sort(wksYYMM, by = "nosort", get = "*");
于 2014-10-18T11:50:06.847 に答える