我正在使用StackExchange Redis DB插入键值对的字典,Batch如下所示:
Batch
private static StackExchange.Redis.IDatabase _database; public void SetAll<T>(Dictionary<string, T> data, int cacheTime) { lock (_database) { TimeSpan expiration = new TimeSpan(0, cacheTime, 0); var list = new List<Task<bool>>(); var batch = _database.CreateBatch(); foreach (var item in data) { string serializedObject = JsonConvert.SerializeObject(item.Value, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new SerializeAllContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); var task = batch.StringSetAsync(item.Key, serializedObject, expiration); list.Add(task); serializedObject = null; } batch.Execute(); Task.WhenAll(list.ToArray()); } }
我的问题: 仅设置350项字典需要 7秒钟 左右。
我的问题: 这是将批量商品设置为Redis的正确方法,还是有一种更快的方法?任何帮助表示赞赏。谢谢。
“公正”是一个非常相对的术语,没有更多的上下文就没有任何意义,尤其是:这些有效载荷有多大?
但是,请澄清一些要点,以帮助您进行调查:
IDatabase
JsonConvert.SerializeObject
batch.Execute()
StringSet
KeyValuePair<RedisKey, RedisValue>[]
MSET
SET
CreateBatch
_database.StringSetAsync
所以; 我要做的 第一 件事是 删除 一些代码:
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()); }
我要做的第二件事是将序列化与redis的工作分开计时。
我要做的第三件事是看我是否可以序列化为MemoryStream一个我可以重复使用的,理想情况下可以避免重复使用- 避免string分配和UTF-8编码:
MemoryStream
string
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)); } }