我有一大堆對象,我需要稍後存儲和檢索。該列表將始終用作單元,列表項不會單獨檢索。該列表包含約7000條總計大約1GB的內容,但可以輕鬆升級至十倍或更多。使用C#序列化一個非常大的項目列表到Azure blob存儲中使用C#
我們一直在使用BinaryFormatter.Serialize()
做序列化(System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
)。然後,該字符串作爲一個blob上傳到Azure blob存儲。我們發現它通常是快速和高效的,但是它變得不夠充分,因爲我們正在用更大的文件大小來測試它,並拋出OutOfMemoryException
。據我所知,雖然我使用流,但我的問題是,BinaryFormatter.Serialize()
方法必須先將所有內容序列化到內存中,然後才能上傳blob,導致我的異常。
的二進制序列如下所示:在formatter.Serialize(stream, value)
線上發生
public void Upload(object value, string blobName, bool replaceExisting)
{
CloudBlockBlob blockBlob = BlobContainer.GetBlockBlobReference(blobName);
var formatter = new BinaryFormatter()
{
AssemblyFormat = FormatterAssemblyStyle.Simple,
FilterLevel = TypeFilterLevel.Low,
TypeFormat = FormatterTypeStyle.TypesAlways
};
using (var stream = blockBlob.OpenWrite())
{
formatter.Serialize(stream, value);
}
}
的OutOfMemoryException異常。
因此,我試圖使用不同的協議,協議緩衝區。我嘗試在Nuget包protobuf-net和Google.Protobuf中使用這兩種實現,但序列化速度非常慢(大約30分鐘),從我讀過的內容來看,Protobuf沒有針對大於1MB的數據進行序列化優化。於是,我回到了繪圖板,並遇到了Cap'n Proto,它承諾通過使用內存映射來解決我的速度問題。我正在嘗試使用@ marc-gravell的C#綁定,但由於該項目還沒有全面的文檔,因此在實現序列化程序時遇到了一些困難。此外,我並不十分確定Cap'n Proto是協議的正確選擇 - 但我正在努力在網上找到其他建議。
如何將一大批項目序列化到blob存儲,而不會遇到內存問題,並且以相當快的方式?
上傳批次工作超過一個斑點,而不是一次序列化的一切嗎? – spender
謝謝,這是我正在考慮的選項。每個列表在我們的域中已經是一個塊,儘管如此,blob會在某種程度上丟失上下文,這會讓事情變得複雜一點。好的建議,但如果沒有任何其他協議或方法的建議,我會給它一個鏡頭。 – Ivan