sql >> Databáze >  >> NoSQL >> Redis

Dávková sada dat ze slovníku do Redis

„jen“ je velmi relativní pojem a ve skutečnosti nedává smysl bez dalšího kontextu, zejména:jak velké jsou tyto užitečné zatížení?

abychom však objasnili několik bodů, které vám pomohou při vyšetřování:

  • není potřeba zamykat IDatabase pokud to není čistě pro vaše vlastní účely; SE.Redis se interně zabývá bezpečností vláken a je určen pro použití konkurenčními vlákny
  • v tuto chvíli bude vaše načasování zahrnovat veškerý serializační kód (JsonConvert.SerializeObject ); to se přidá, zejména pokud jsou vaše předměty velké; abyste získali slušnou míru, důrazně doporučuji načasovat serializaci a časy redis samostatně
  • batch.Execute() metoda používá pipeline API a nečeká na odpovědi mezi voláními, takže:čas, který vidíte, není kumulativní účinek latence; to ponechává pouze místní CPU (pro serializaci), šířku pásma sítě a CPU serveru; nástroje klientské knihovny nemohou žádnou z těchto věcí ovlivnit
  • existuje StringSet přetížení, které přijímá KeyValuePair<RedisKey, RedisValue>[]; mohli zvolte použít toto místo dávky, ale jediný rozdíl je v tom, že je to varadic MSET spíše než více SET; v každém případě po dobu trvání blokujete spojení pro ostatní volající (protože účelem dávky je zajistit souvislé příkazy)
  • ve skutečnosti ne musíte použít CreateBatch zde, zejména protože zamykáte databázi (ale přesto vám doporučuji, abyste to nemuseli dělat); účel CreateBatch je vytvořit sekvenci příkazů sekvenčně , ale nevidím, že to tady potřebujete; stačí použít _database.StringSetAsync pro každý příkaz v pořadí, což by také mají výhodu, že byste spouštěli serializaci paralelně s odesílání předchozího příkazu - umožnilo by vám to překrýt serializaci (vázáno na CPU) a redis ops (vázáno na vstup) bez jakékoli práce kromě odstranění CreateBatch volání; to bude také znamenat, že nebudete monopolizovat připojení od ostatních volajících

Tak; první co bych udělal, by bylo odstranit nějaký kód:

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());
}

Druhá věc, kterou bych udělal, by bylo načasovat serializaci odděleně od práce redis.

Třetí věcí, kterou bych udělal, by bylo zjistit, zda mohu serializovat do MemoryStream místo toho ideálně takovou, kterou mohu znovu použít – abych se vyhnul string alokace a kódování 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. Proč nemohu spustit lua skript v redis po restartu redis?

  2. Najděte v Double Nested Array MongoDB

  3. MongoDB jako databáze časových řad

  4. Jak používat šifrování k ochraně dat MongoDB