0

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)

4

1 回答 1

1

@LamonteCristo,这些都是好问题。

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

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

哪些工作负载(表、队列、Blob)将从该缓存中受益?

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

我应该在哪些(可测量的)条件下实现 IBufferManager?

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

BufferManager 线程安全吗?我可以根据需要分配一个运行时服务器端缓冲区池吗?

根据我的经验,如果我们在 multiple-threads 中使用同一个实例,这不是线程安全的。请参考本文档(https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.buffermanager(v=vs.110).aspx#Thread Safety)

我应该/不应该如何实现这个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("**");

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

于 2017-01-18T07:17:31.087 回答