Wir verwenden die Stream-Funktionalität in RavenDB zu laden, zu transformieren und Migration von Daten zwischen zwei Datenbanken wie folgt:RavenDB-Stream für Unbounded Ergebnisse - Anschluss Resilience
var query = originSession.Query<T>(IndexForQuery);
using (var stream = originSession.Advanced.Stream(query))
{
while (stream.MoveNext())
{
var streamedDocument = stream.Current.Document;
OpenSessionAndMigrateSingleDocument(streamedDocument);
}
}
Das Problem ist, dass eine der Sammlungen hat Millionen Zeilen, und halten wir ein IOException
in folgendem Format empfangen:
Application: MigrateToNewSchema.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
Stack:
at System.Net.ConnectStream.Read(Byte[], Int32, Int32)
at System.IO.Compression.DeflateStream.Read(Byte[], Int32, Int32)
at System.IO.Compression.GZipStream.Read(Byte[], Int32, Int32)
at System.IO.StreamReader.ReadBuffer(Char[], Int32, Int32, Boolean ByRef)
at System.IO.StreamReader.Read(Char[], Int32, Int32)
at Raven.Imports.Newtonsoft.Json.JsonTextReader.ReadData(Boolean, Int32)
at Raven.Imports.Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char)
at Raven.Imports.Newtonsoft.Json.JsonTextReader.ParseString(Char)
at Raven.Imports.Newtonsoft.Json.JsonTextReader.ParseValue()
at Raven.Imports.Newtonsoft.Json.JsonTextReader.ReadInternal()
at Raven.Imports.Newtonsoft.Json.JsonTextReader.Read()
at Raven.Json.Linq.RavenJObject.Load(Raven.Imports.Newtonsoft.Json.JsonReader)
at Raven.Json.Linq.RavenJObject.Load(Raven.Imports.Newtonsoft.Json.JsonReader)
at Raven.Json.Linq.RavenJToken.ReadFrom(Raven.Imports.Newtonsoft.Json.JsonReader)
at Raven.Client.Connection.ServerClient+<YieldStreamResults>d__6b.MoveNext()
at Raven.Client.Document.DocumentSession+<YieldQuery>d__c`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MoveNext()
at MigrateToNewSchema.Migrator.DataMigratorBase`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].MigrateCollection()
at MigrateToNewSchema.Program.MigrateData(MigrateToNewSchema.Enums.CollectionToMigrate, Raven.Client.IDocumentStore, Raven.Client.IDocumentStore)
at MigrateToNewSchema.Program.Main(System.String[])
Dies geschieht ziemlich langen Weg in Streaming und natürlich vorübergehende Verbindungsprobleme über diese Art von Zeit auftreten werden (es Stunden in Anspruch nimmt).
Wenn wir jedoch versuchen, wie wir eine Query
verwenden, müssen wir von vorne anfangen. Also, wenn es schließlich einen Verbindungsfehler während der gesamten Stream
gibt, dann müssen wir es erneut versuchen, und wieder, bis es Ende zu Ende funktioniert.
Ich weiß, dass Sie ETag
mit Stream verwenden können, um effektiv an einem bestimmten Punkt neu zu starten, jedoch gibt es keine Überladung, dies mit einer Query
zu tun, die wir die migrierten Ergebnisse filtern und die richtige Sammlung angeben müssen.
Gibt es also in RavenDB eine Möglichkeit, die interne Ausfallsicherheit der Verbindung (Verbindungszeichenfolgeneigenschaft, interne Einstellungen usw.) zu verbessern oder einen Stream bei einem Fehler effektiv "wiederherzustellen"?
ich entdeckt habe [Data Abonnements] (http://ravendb.net/docs/article-page/3.0/csharp/client-api/data- Subscriptions/how-to-create-data-subscription), eine Funktion von RavenDb 3.0, die einen zuverlässigen Mechanismus für die Iteration über eine Sammlung von Dokumenten mit bestimmten Kriterien bietet und es Ihnen ermöglicht, einfach dort weiterzumachen, wo Sie aufgehört haben. Wenn jemand bereit wäre, einige Codebeispiele zusammenzustellen, die zeigen, wie diese Funktion diese Frage beantworten könnte, würde ich das für das Kopfgeld halten. – StriplingWarrior
Sind Sie an die Verwendung einer Abfrage gebunden? Obwohl es ineffizienter ist, ist dies eine Migration, daher ist Speicher kein Problem - warum nicht die rohen doc-Sammlungen iterieren und In-Memory filtern, so dass Sie an einem Etag fortfahren können? So handle ich mit allem Streaming, ich benutze nie Abfragen. – kamranicus
@StriplingWarrior Es ist eine Weile her :-) Ich arbeite nicht mehr für das Unternehmen mit RavenDB, aber das interessiert mich immer noch, also werde ich eine Antwort mit dem Datenabonnement-Code heute stecken –