「ちょうど」は非常に相対的な用語であり、特にコンテキストがなければ意味がありません。これらのペイロードの大きさはどれくらいですか?
ただし、調査に役立ついくつかのポイントを明確にするために:
-
IDatabase
をロックする必要はありません それが純粋にあなた自身の目的でない限り; SE.Redisは内部でスレッドセーフを扱い、競合するスレッドで使用することを目的としています - 現時点では、このタイミングにはすべてのシリアル化コード(
JsonConvert.SerializeObject
)が含まれます。 );これは合計されます、特に オブジェクトが大きい場合。適切な測定値を取得するには、シリアル化の時間を計り、時間を別々に再実行することを強くお勧めします -
batch.Execute()
メソッドはパイプラインAPIを使用し、呼び出し間の応答を待機しないため、表示される時間はないです。 レイテンシーの累積効果。これにより、ローカルCPU(シリアル化用)、ネットワーク帯域幅、およびサーバーCPUのみが残ります。クライアントライブラリツールは、これらのいずれにも影響を与えることはできません -
StringSet
がありますKeyValuePair<RedisKey, RedisValue>[]
を受け入れるオーバーロード;あなたはできた バッチの代わりにこれを使用することを選択しますが、ここでの唯一の違いは、それがvaradicMSET
であるということです。 複数の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));
}
}