sql >> データベース >  >> NoSQL >> Redis

辞書からRedisへのバッチセットデータ

    「ちょうど」は非常に相対的な用語であり、特にコンテキストがなければ意味がありません。これらのペイロードの大きさはどれくらいですか?

    ただし、調査に役立ついくつかのポイントを明確にするために:

    • IDatabaseをロックする必要はありません それが純粋にあなた自身の目的でない限り; SE.Redisは内部でスレッドセーフを扱い、競合するスレッドで使用することを目的としています
    • 現時点では、このタイミングにはすべてのシリアル化コード(JsonConvert.SerializeObject)が含まれます。 );これは合計されます、特に オブジェクトが大きい場合。適切な測定値を取得するには、シリアル化の時間を計り、時間を別々に再実行することを強くお勧めします
    • batch.Execute() メソッドはパイプラインAPIを使用し、呼び出し間の応答を待機しないため、表示される時間はないです。 レイテンシーの累積効果。これにより、ローカルCPU(シリアル化用)、ネットワーク帯域幅、およびサーバーCPUのみが残ります。クライアントライブラリツールは、これらのいずれにも影響を与えることはできません
    • StringSetがあります KeyValuePair<RedisKey, RedisValue>[]を受け入れるオーバーロード;あなたはできた バッチの代わりにこれを使用することを選択しますが、ここでの唯一の違いは、それがvaradic MSETであるということです。 複数のSETではなく;いずれの場合も、他の発信者の接続をその間ブロックします(バッチの目的はコマンドを連続させることであるため)
    • 実際には CreateBatchを使用する必要があります ここでは、特に データベースをロックしているので(ただし、これを行う必要はないことをお勧めします)。 CreateBatchの目的 コマンドのシーケンスをシーケンシャルにすることです 、しかし、ここでこれが必要だとは思いません。 _database.StringSetAsyncを使用するだけです。 コマンドごとに順番に、また シリアル化を並行して実行するという利点があります。 送信される前のコマンド-CreateBatchを削除する以外の作業なしで、シリアル化(CPUバウンド)とredis ops(IOバウンド)をオーバーラップさせることができます 電話;これは、他の発信者からの接続を独占しないことも意味します

    それで; 最初 私がすることは削除することです いくつかのコード:

    private static StackExchange.Redis.IDatabase _database;
    static JsonSerializerSettings _redisJsonSettings = new JsonSerializerSettings {
        ContractResolver = new SerializeAllContractResolver(),
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
    
    public void SetAll<T>(Dictionary<string, T> data, int cacheTime)
    {
        TimeSpan expiration = new TimeSpan(0, cacheTime, 0);
        var list = new List<Task<bool>>();
        foreach (var item in data)
        {
            string serializedObject = JsonConvert.SerializeObject(
                item.Value, Formatting.Indented, _redisJsonSettings);
    
            list.Add(_database.StringSetAsync(item.Key, serializedObject, expiration));
        }
        Task.WhenAll(list.ToArray());
    }
    

    2番目に行うことは、シリアル化のタイミングをredis作業とは別にすることです。

    私がする3番目のことは、MemoryStreamにシリアル化できるかどうかを確認することです。 代わりに、理想的には、stringを避けるために再利用できるものです。 割り当てとUTF-8エンコード:

    using(var ms = new MemoryStream())
    {
        foreach (var item in data)
        {
            ms.Position = 0;
            ms.SetLength(0); // erase existing data
            JsonConvert.SerializeObject(ms,
                item.Value, Formatting.Indented, _redisJsonSettings);
    
            list.Add(_database.StringSetAsync(item.Key, ms.ToArray(), expiration));
        }
    }
    


    1. AmazonEC2にMongoDBをデプロイするための6つのベストプラクティス

    2. rediscliを使用してコマンドのバッチを実行する

    3. 集約されたカタログツリー検索結果をRedisに保存する方法

    4. .find()マングースで何も見つからない場合は何かをします