2017-08-10 64 views
1

在使用我们的中心RavenDb遇到大量中断后,我们正在寻找在Azure Blob存储中缓存某些对象。 Redis没有与ABS相同的SLA保证,因此Redis已被排除从Azure Blob存储中反序列化对象的最快方法?

这些对象的检索和反序列化每分钟都会发生,并且需要非常快地发生。

这是我们试图用来反序列化的代码,但它比从Raven中检索对象要慢5-6倍。无论如何要优化它?目标大小约为8mb

var blob = container.GetBlockBlobReference(entityId + ".json"); 

var serializer = new JsonSerializer 
{ 
    ObjectCreationHandling = ObjectCreationHandling.Reuse, 
    NullValueHandling = NullValueHandling.Include, 
    ReferenceLoopHandling = ReferenceLoopHandling.Serialize, 
    PreserveReferencesHandling = PreserveReferencesHandling.All, 
    TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, 
    TypeNameHandling = TypeNameHandling.All 
}; 

using (var stream = new MemoryStream()) 
{ 
    blob.DownloadToStream(stream); 
    stream.Position = 0; 

    using (var sr = new StreamReader(stream)) 
    using (var jsonTextReader = new JsonTextReader(sr)) 
    { 
     var accountOut = serializer.Deserialize<Account>(jsonTextReader); 
    } 
} 
+0

您是否确定什么是5-6倍慢?是否是反序列化的东西?如果是这样,你如何与Raven进行反序列化? (我不知道它是什么)还是它'GetBlockBlobReference'?如果是这样,我恐怕没有什么可以用ABS做。可能会切换为Azure SQL数据库? – fharreau

+0

最快的方法应该是用BinaryFormatter存储和读取二进制数据,或者你自己做。 – user743414

+0

@fharreau我不知道是什么导致5-6倍的差异,但我认为这是关于序列化。但是,RavenDb在内部将其对象存储为JSON。 GetBlockBlobReference不调用Azure,只是创建一个内存中的对象 – Igorek

回答

0

事实证明,使用单个序列化器对象,无需在循环的每个循环中重新创建,都可以解决问题。有一次,我们开始缓存JsonSerializer对象并重新使用它,Blob存储的反序列化性能成为RavenDb的50%。

+0

一个想法 - 序列化,还应该考虑内存成本,非常频繁的序列化会导致更多的GC循环 – Michael

0

想要速度并且无法使用Redis(无论出于何种原因)?只有一个正确答案:CosmosDB

速度非常快,它由SSD存储支持。 单个区域内99.99%的可用性(如果需要,只需点击Portal UI即可实现地理复制)。

+0

我的印象是CosmosDb对每个对象的限制为2mb? – Igorek

+0

是的,你是对的 - https://docs.microsoft.com/en-us/azure/cosmos-db/documentdb-resources#documents也许你可以在语义上拆分这些JSON?愚蠢的建议,我知道。你为什么放弃Redis? Premium级别具有主/从节点和持久性(RDB)。 – evilSnobu