sql >> Database teknologi >  >> NoSQL >> Redis

Parallel udførelse med StackExchange.Redis?

I øjeblikket bruger din kode den synkrone API (StringSet ), og indlæses af 10 tråde samtidigt. Dette vil ikke udgøre nogen nævneværdig udfordring for SE.Redis - det fungerer fint her. Jeg mistanker at det reelt er en timeout, hvor serveren har taget længere tid, end du gerne vil have, at behandle nogle af dataene, højst sandsynligt også relateret til serverens allokator. En mulighed er derfor blot at forøge timeouten lidt . Ikke meget... prøv 5 sekunder i stedet for standard 1 sekund. Sandsynligvis fungerer de fleste af operationerne alligevel meget hurtigt.

Med hensyn til at fremskynde det:En mulighed her er at ikke vente - dvs. behold pipelining-data. Hvis du nøjes med ikke at kontrollere hver enkelt besked for en fejltilstand, så er en enkel måde at gøre dette på at tilføje , flag:CommandFlags.FireAndForget til slutningen af ​​dit StringSet opkald. I min lokale test fremskyndede dette 1M-eksemplet med 25 % (og jeg formoder, at meget af resten af ​​tiden faktisk bruges på strengserialisering).

Det største problem, jeg havde med 10M-eksemplet, var simpelthen overhead ved arbejdet med 10M-eksemplet - især da dette tager enorme mængder hukommelse til både redis-serveren og applikationen, som (for at efterligne din opsætning) er på den samme maskine. Dette skaber konkurrerende hukommelsestryk, med GC-pauser osv. i den administrerede kode. Men måske endnu vigtigere:det tager simpelthen evigheder at begynde at gøre noget . Som følge heraf refaktorerede jeg koden til at bruge parallel yield return generatorer frem for en enkelt liste. For eksempel:

static IEnumerable InventPeople(int seed, int count) { for(int i =0; i appRandom.Value.Next(1, f)).ToArray() }; udbytte returvare; } } statisk IEnumerable Batchify(denne IEnumerable kilde, int count) { var list =new List(count); foreach(var element i kilden) { list.Add(item); if(list.Count ==count) { foreach (var x in list) yield return x; liste.Slet(); } } foreach (var vare på listen) giver returvare; }

med:

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

Her er formålet med Batchify er at sikre, at vi ikke hjælper serveren for meget ved at tage betydelig tid mellem hver operation - dataene er opfundet i batches på 1000 og hver batch gøres tilgængelig meget hurtigt.

Jeg var også bekymret over JSON-ydelsen, så jeg skiftede til JIL:

 offentlig statisk streng ToJSON(dette T obj) { return Jil.JSON.Serialize(obj); } 

og så for sjov flyttede jeg JSON-arbejdet ind i batchen (så den faktiske behandling går i løkker :

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

Dette fik tiderne lidt mere ned, så jeg kan indlæse 10M på 3 minutter og 57 sekunder, en hastighed på 42.194 rops. Det meste af denne tid er faktisk lokal behandling inde i applikationen. Hvis jeg ændrer det, så hver tråd indlæser det samme vare ITEMS/THREADS gange, så ændres dette til 1 minut og 48 sekunder - en hastighed på 92.592 rops.

Jeg er ikke sikker på, om jeg har svaret noget rigtigt, men den korte version er måske ganske enkelt "prøv en længere timeout; overvej at bruge brand-og-glem).




  1. mongodb aggregering php

  2. MongoDB diakritisk følsom søgning viser ikke alle accentuerede (ord med diakritisk tegn) rækker som forventet og omvendt

  3. Forespørg MongoDB med et regex-udtryk mod et ObjectId

  4. Sådan får du alle nøgler i Redis