„просто“ е много относително понятие и всъщност няма смисъл без повече контекст, по-специално:колко големи са тези полезни товари?
обаче, за да изясня няколко точки, които да ви помогнат да проучите:
- няма нужда да заключвате
IDatabase
освен ако това не е само за ваши собствени цели; SE.Redis се занимава с вътрешна безопасност на нишките и е предназначен да се използва от конкурентни нишки - в момента времето ви за това ще включва целия код за сериализация (
JsonConvert.SerializeObject
); това ще се добави, особено ако вашите предмети са големи; за да получите прилична мярка, силно ви препоръчвам да отчитате времето за сериализиране и редис отделно batch.Execute()
методът използва API на конвейера и не чака отговори между повикванията, така че:времето, което виждате, е не кумулативният ефект на латентността; което оставя само локален CPU (за сериализация), мрежова честотна лента и сървърен CPU; инструментите на клиентската библиотека не могат да повлияят на никое от тези неща- има
StringSet
претоварване, което приемаKeyValuePair<RedisKey, RedisValue>[]
; ти можеш изберете да използвате това вместо пакет, но единствената разлика тук е, че това е varadicMSET
вместо множествоSET
; така или иначе, ще блокирате връзката за други обаждащи се за цялото времетраене (тъй като целта на пакета е да направи командите последователни) - не всъщност трябва да използвате
CreateBatch
тук, особено тъй като заключвате базата данни (но все пак ви предлагам да не е необходимо да правите това); целта наCreateBatch
е да направите последователност от команди последователна , но не виждам, че имате нужда от това тук; можете просто да използвате_database.StringSetAsync
за всяка команда на свой ред, което би също имат предимството, че ще изпълнявате сериализация успоредно с предишната команда се изпраща - тя ще ви позволи да припокривате сериализация (свързана с процесора) и redis ops (обвързана с IO) без никаква работа, освен да изтриетеCreateBatch
обадете се; това също ще означава, че не монополизирате връзката от други обаждащи се
Така; първият нещо, което бих направил е да премахна някакъв код:
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 кодиране:
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));
}
}