Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Zestaw wsadowy danych ze słownika do Redis

„tylko” jest terminem bardzo względnym i nie ma sensu bez większego kontekstu, w szczególności:jak duże są te ładunki?

jednak, aby wyjaśnić kilka punktów, które pomogą Ci zbadać:

  • nie ma potrzeby blokowania IDatabase chyba że służy to wyłącznie twoim własnym celom; SE.Redis zajmuje się wewnętrznie bezpieczeństwem wątków i jest przeznaczony do użytku przez konkurencyjne wątki
  • w tej chwili czas wykonania tej czynności będzie obejmował cały kod serializacji (JsonConvert.SerializeObject ); to się zsumuje, zwłaszcza jeśli twoje przedmioty są duże; aby uzyskać przyzwoitą miarę, zdecydowanie sugeruję, abyś czasy serializacji i redis były oddzielnie
  • batch.Execute() Metoda wykorzystuje API potoku i nie czeka na odpowiedzi między wywołaniami, więc:czas, który widzisz, to nie skumulowany efekt utajenia; to pozostawia tylko lokalny procesor (do serializacji), przepustowość sieci i procesor serwera; narzędzia biblioteki klienta nie mogą wpływać na żadną z tych rzeczy
  • istnieje StringSet przeciążenie, które akceptuje KeyValuePair<RedisKey, RedisValue>[]; mogłeś zdecydować się na użycie tego zamiast partii, ale jedyną różnicą jest to, że jest to varadic MSET zamiast wielokrotnego SET; tak czy inaczej, będziesz blokować połączenie dla innych rozmówców na czas (ponieważ celem partii jest, aby polecenia były ciągłe)
  • nie właściwie trzeba użyć CreateBatch tutaj, zwłaszcza ponieważ blokujesz bazę danych (ale nadal sugeruję, że nie musisz tego robić); cel CreateBatch jest wykonanie sekwencji poleceń sekwencyjnych , ale nie widzę, że potrzebujesz tego tutaj; możesz po prostu użyć _database.StringSetAsync dla każdego polecenia po kolei, co również mieć tę zaletę, że będziesz uruchamiać serializację równolegle z poprzednie wysyłane polecenie - pozwoliłoby to na nakładanie się serializacji (związane z procesorem) i operacji redis (związane z IO) bez żadnej pracy, z wyjątkiem usunięcia CreateBatch połączenie; oznacza to również, że nie zmonopolizujesz połączenia od innych rozmówców

Więc; pierwszy co bym zrobił, to usunąć jakiś kod:

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

Drugą rzeczą, którą bym zrobił, to zsynchronizowanie serializacji oddzielnie z pracą nad redisem.

Trzecią rzeczą, którą bym zrobił, byłoby sprawdzenie, czy mogę serializować do MemoryStream zamiast tego najlepiej taki, którego mogę użyć ponownie - aby uniknąć string alokacja i kodowanie 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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Redis Memcache v/s do utrzymywania trwałych sesji?

  2. Konfigurowanie redis, aby najpierw konsekwentnie eksmitować starsze dane

  3. Korzystanie z replikacji Redis na różnych komputerach (multi master)

  4. Nie można połączyć się z Redis o 127.0.0.1:6379:Połączenie odrzucone z homebrew

  5. Czy mogę używać Tornado+ Celery+ RabbitMQ + Redis?