"hanya" adalah istilah yang sangat relatif, dan tidak terlalu masuk akal tanpa konteks lebih lanjut, khususnya:seberapa besar muatan ini?
namun, untuk memperjelas beberapa poin untuk membantu Anda menyelidiki:
- tidak perlu mengunci
IDatabase
kecuali itu murni untuk tujuan Anda sendiri; SE.Redis berurusan dengan keamanan utas secara internal dan dimaksudkan untuk digunakan oleh utas yang bersaing - saat ini, pengaturan waktu Anda akan mencakup semua kode serialisasi (
JsonConvert.SerializeObject
); ini akan bertambah, terutama jika objek Anda besar; untuk mendapatkan ukuran yang layak, saya sangat menyarankan Anda mengatur waktu serialisasi dan mengulang waktu secara terpisah batch.Execute()
metode menggunakan API pipa dan tidak menunggu tanggapan di antara panggilan, jadi:waktu yang Anda lihat tidak efek kumulatif dari latensi; yang hanya menyisakan CPU lokal (untuk serialisasi), bandwidth jaringan, dan CPU server; alat pustaka klien tidak dapat memengaruhi hal-hal tersebut- ada
StringSet
kelebihan yang menerimaKeyValuePair<RedisKey, RedisValue>[]
; kamu bisa pilih untuk menggunakan ini daripada batch, tetapi satu-satunya perbedaan di sini adalah bahwa ini adalahMSET
varadic daripada beberapaSET
; apa pun itu, Anda akan memblokir koneksi untuk penelepon lain selama durasi tersebut (karena tujuan batch adalah untuk membuat perintah bersebelahan) - Anda tidak sebenarnya perlu menggunakan
CreateBatch
di sini, terutama karena Anda mengunci database (tapi saya tetap menyarankan Anda tidak perlu melakukan ini); tujuanCreateBatch
adalah membuat urutan perintah berurutan , tetapi saya tidak melihat Anda membutuhkan ini di sini; Anda bisa menggunakan_database.StringSetAsync
untuk setiap perintah secara bergantian, yang akan juga memiliki keuntungan bahwa Anda akan menjalankan serialisasi secara paralel dengan perintah sebelumnya sedang dikirim - itu akan memungkinkan Anda untuk tumpang tindih serialisasi (CPU terikat) dan redis ops (IO terikat) tanpa pekerjaan apa pun kecuali untuk menghapusCreateBatch
panggilan; ini juga berarti Anda tidak memonopoli sambungan dari penelepon lain
Jadi; yang pertama hal yang akan saya lakukan adalah menghapus beberapa kode:
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());
}
Hal kedua yang akan saya lakukan adalah mengatur waktu serialisasi secara terpisah untuk pekerjaan redis.
Hal ketiga yang akan saya lakukan adalah melihat apakah saya dapat membuat serial ke MemoryStream
sebagai gantinya, idealnya yang dapat saya gunakan kembali - untuk menghindari string
alocation dan encode 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));
}
}