Azure存储缓冲区管理器做了什么,以及如何/何时实现它?

时间:2017-01-14 23:41:43

标签: azure garbage-collection azure-storage azure-table-storage buffer-manager

MSDN上cloudBlobClient.BufferManager的文档描述了此缓冲区管理器可提高大规模应用程序的性能。

我的理解是这个缓冲管理器减少了许多小事务对GC的压力(如许多Azure Table实体调用中所示),

然后我阅读了有关桌面使用情况的参考资料,桌面/移动设备使用情况配置文件似乎不太可能遇到GC碎片:

  

IBufferManager接口在System.ServiceModel.dll中的BufferManager类之后被图案化,以允许桌面客户端轻松利用框架提供的现有实现。

问题

  1. IBufferManager的唯一目的是减轻GC的压力吗?

  2. 哪些工作负载(表,队列,Blob)会从此缓存中受益?

  3. 我应该实施IBufferManager的(可衡量的)条件是什么?

  4. BufferManager线程安全吗?我可以根据需要使用运行时服务器端缓冲池吗?

  5. 我应该/不应该如何实现这个bufferManager? (例如,线程,IDisposable,静态方法中的预分配,Redis)

1 个答案:

答案 0 :(得分:1)

@LamonteCristo, 这些都是好问题。

  

IBufferManager的唯一目的是减少GC的压力吗?

BufferManager不仅可以降低GC的压力,还可以提高存储服务器的性能。 GC可以创建和销毁缓冲池,这些过程是计算机资源上每次分配的成本。 BufferManager可以保留缓冲池,并且每次都比GC快。同时,我建议你可以参考这个answers

  

哪些工作负载(表,队列,Blob)会从此缓存中受益?

答案是肯定的。 Azure存储SDK为这3种存储服务提供了此功能。它们是相同的方法。

  

我应该实施IBufferManager的(可衡量的)条件是什么?

理论上,我们可以使用大的不同MaxBufferSize进行并发请求,以获得服务器响应时间。然后再次发送这些请求以再次获得响应时间。我们可以比较这两个响应时间。实际上,这是时间和记忆之间的平衡。

  

BufferManager线程安全吗?我可以根据需要使用运行时服务器缓冲池吗?

根据我的经验,如果我们在多线程中使用一个相同的实例,那么它不是线程安全的。请参阅此文档(https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.buffermanager(v=vs.110).aspx#Thread安全性)

  

我应该/不应该如何实现这个bufferManager? (例如,线程,IDisposable,静态方法中的预分配,Redis)

您需要实施" System.ServiceModel"进入你的项目并尝试使用这个样本:

public class WCFBufferManagerAdapter : IBufferManager
{
    private int defaultBufferSize = 0;

    public WCFBufferManagerAdapter(BufferManager manager, int defaultBufferSize)
    {
        this.Manager = manager;
        this.defaultBufferSize = defaultBufferSize;
    }

    public BufferManager Manager { get; internal set; }

    public void ReturnBuffer(byte[] buffer)
    {
        this.Manager.ReturnBuffer(buffer);
    }

    public byte[] TakeBuffer(int bufferSize)
    {
        return this.Manager.TakeBuffer(bufferSize);
    }

    public int GetDefaultBufferSize()
    {
        return this.defaultBufferSize;
    }
}

然后你可以使用这个BufferManager如下:

StorageCredentials credentials = new StorageCredentials("**", "**");
            CloudBlobClient serviceClient = new CloudBlobClient(new Uri("**"), credentials);             
            BufferManager mgr = BufferManager.CreateBufferManager(<you_can_set>, <you_can_set>);            
            serviceClient.BufferManager = new WCFBufferManagerAdapter(mgr, <you_can_set>);
            serviceClient.GetContainerReference("**");

如果您想使用多线程,则可能需要使用&#39; lock&#39;在你的代码中。 有任何疑虑,请告诉我。