Redis
 sql >> база данни >  >> NoSQL >> Redis

Паралелно изпълнение със StackExchange.Redis?

В момента вашият код използва синхронния API (StringSet ) и се зарежда от 10 нишки едновременно. Това няма да представлява значително предизвикателство за SE.Redis - тук работи добре. подозирам че това наистина е изчакване, при което сървърът е отнел повече време, отколкото бихте искали да обработи някои от данните, най-вероятно също свързани с разпределителя на сървъра. Една от възможностите е просто да увеличите малко времето за изчакване . Не много... опитайте 5 секунди вместо 1 секунда по подразбиране. Вероятно повечето от операциите работят много бързо.

По отношение на ускоряването:една от опциите тук е да не чакате - т.е. продължавайте да предавате данни. Ако сте доволни да не проверявате всяко съобщение за състояние на грешка, тогава един лесен начин да направите това е да добавите , flags: CommandFlags.FireAndForget до края на вашия StringSet обадете се. В моето локално тестване това ускори примера 1M с 25% (и подозирам, че голяма част от останалото време всъщност се изразходва в сериализиране на низове).

Най-големият проблем, който имах с примера 10M, беше просто режийните разходи за работата с примера 10M - особено след като това отнема огромни количества памет и за redis-server и приложението, които (за да емулират вашата настройка) са на една и съща машина. Това създава конкурентен натиск в паметта, с GC паузи и т.н. в управлявания код. Но може би по-важното е:просто отнема цяла вечност, за да започнете да правите каквото и да било . Следователно преструктурирах кода, за да използвам паралелно yield return генератори, а не единичен списък. Например:

    static IEnumerable<Person> InventPeople(int seed, int count)
    {
        for(int i = 0; i < count; i++)
        {
            int f = 1 + seed + i;
            var item = new Person
            {
                Id = f,
                Name = Path.GetRandomFileName().Replace(".", "").Substring(0, appRandom.Value.Next(3, 6)) + " " + Path.GetRandomFileName().Replace(".", "").Substring(0, new Random(Guid.NewGuid().GetHashCode()).Next(3, 6)),
                Age = f % 90,
                Friends = ParallelEnumerable.Range(0, 100).Select(n => appRandom.Value.Next(1, f)).ToArray()
            };
            yield return item;
        }
    }

    static IEnumerable<T> Batchify<T>(this IEnumerable<T> source, int count)
    {
        var list = new List<T>(count);
        foreach(var item in source)
        {
            list.Add(item);
            if(list.Count == count)
            {
                foreach (var x in list) yield return x;
                list.Clear();
            }
        }
        foreach (var item in list) yield return item;
    }

с:

foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD).Batchify(1000))

Ето целта на Batchify е да гарантираме, че не помагаме твърде много на сървъра, като отделяме значително време между всяка операция - данните се измислят на партиди от 1000 и всяка партида се предоставя много бързо.

Бях загрижен и за производителността на JSON, затова преминах към JIL:

    public static string ToJSON<T>(this T obj)
    {
        return Jil.JSON.Serialize<T>(obj);
    }

и след това просто за забавление преместих JSON работата в пакетирането (така че действителната обработка се завърта :

 foreach (var element in InventPeople(PER_THREAD * counter1, PER_THREAD)
     .Select(x => new { x.Id, Json = x.ToJSON() }).Batchify(1000))

Това намали времето малко повече, така че мога да заредя 10M за 3 минути 57 секунди, скорост от 42 194 оборота. Повечето от това време всъщност е локална обработка в приложението. Ако го променя така, че всяка нишка да зарежда същото елемент ITEMS / THREADS пъти, след това това се променя на 1 минута 48 секунди - скорост от 92 592 оборота.

Не съм сигурен дали наистина съм отговорил на нещо, но кратката версия може да бъде просто „опитайте с по-дълго време за изчакване; помислете за използването на „запали и забрави“.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Да слушате за промени в Redis?

  2. производителност на redis, съхранявайте json обект като низ

  3. Какъв е най-добрият начин да използвате Redis в многонишкова Rails среда? (Пума / Сидекик)

  4. Свържете се с AWS ElastiCache с шифроване при транспортиране + удостоверяване от клиент, различен от redis-cli+stunnel

  5. Въведение в Redis Data Structures:Bitmaps