Pipelining vs Dosierung bei Stackexchange.Redis
Ich versuche zu legen, die eine große(-ish) Anzahl der Elemente in der kürzest möglichen Zeit und ich habe versucht, diese beiden alternativen:
1) Pipelining:
List<Task> addTasks = new List<Task>();
for (int i = 0; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
Task<bool> addAsync = redisDB.SetAddAsync(string.Format(keyFormat, row.Field<int>("Id")), row.Field<int>("Value"));
addTasks.Add(addAsync);
}
Task[] tasks = addTasks.ToArray();
Task.WaitAll(tasks);
2) Dosierung:
List<Task> addTasks = new List<Task>();
IBatch batch = redisDB.CreateBatch();
for (int i = 0; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
Task<bool> addAsync = batch.SetAddAsync(string.Format(keyFormat, row.Field<int>("Id")), row.Field<int>("Value"));
addTasks.Add(addAsync);
}
batch.Execute();
Task[] tasks = addTasks.ToArray();
Task.WaitAll(tasks);
Ich bin nicht bemerken keine signifikante Zeitdifferenz (eigentlich habe ich erwartet, dass die batch-Methode schneller zu sein): für ca 250K-Einsätze, die ich bekommen ca 7 sec für pipelining vs ca 8 sec für die Batchverarbeitung.
Lesung aus der Dokumentation auf pipelining,
"Mit pipelining ermöglicht es uns, sowohl die Anforderungen an das Netzwerk
sofort, wodurch die meisten die Latenz. Darüber hinaus wird es auch
hilft bei der Reduzierung Paket-Fragmentierung: 20 Anfragen individuell
(Wartezeit für jede Antwort), benötigen Sie mindestens 20 Pakete, aber 20
Anfragen, die gesendet werden in eine Rohrleitung, die passen könnte in viel weniger Pakete (vielleicht
sogar nur eins)."
Mir, das klingt wie eine Menge, die eine Dosierungs-Verhalten. Ich Frage mich, ob hinter den kulissen, es gibt einen großen Unterschied zwischen den beiden, da bei einem einfachen check mit procmon
ich sehe fast die gleiche Anzahl von TCP Send
s auf beiden Versionen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hinter den kulissen, SE.Redis bedeutet einiges an Arbeit, um zu versuchen zu vermeiden, packet fragmentation, so ist es nicht verwunderlich, dass es ziemlich ähnlich wie in deinem Fall. Der wesentliche Unterschied zwischen Gemenge und flach pipelining sind:
multi
/exec
Transaktion oder ein Lua-Skript)In den meisten Fällen werden Sie besser tun durch die Vermeidung von Dosierungs -, da SE.Redis erreicht das meiste, was es tut automatisch, wenn Sie einfach das hinzufügen von Arbeit.
Als ein letzter Hinweis, wenn Sie wollen, um zu vermeiden, lokale overhead, ein letzter Ansatz könnte sein:
Dieser sendet alles nach unten den Draht, weder zu warten, für Antworten noch die Zuweisung unvollständig
Task
s zu repräsentieren zukünftige Werte. Möchten Sie vielleicht etwas tun, wie einPing
am Ende ohne Feuer-und-vergessen, um zu überprüfen, der server ist immer noch mit Ihnen zu reden. Beachten Sie, dass die Verwendung von Feuer-und-vergessen heißt nicht, dass Sie nicht bemerken, die server-Fehler gemeldet bekommen.