Что делает Azure Storage BufferManager и как / когда я его реализую?

Документация по MSDN для cloudBlobClient.BufferManager описывает, что этот диспетчер буфера повышает производительность для крупномасштабных приложений.

Насколько я понимаю, этот диспетчер буфера уменьшает нагрузку на GC для многих небольших транзакций (как это происходит во многих вызовах сущностей таблицы Azure),

Затем я прочитал ссылку на использование рабочего стола, и профиль использования рабочего стола / мобильного устройства, похоже, вряд ли столкнется с фрагментацией GC:

Интерфейс IBufferManager создан по шаблону после класса BufferManager в System.ServiceModel.dll, что позволяет настольным клиентам легко использовать существующую реализацию, предоставляемую платформой.

Вопрос

  1. Является ли единственной целью IBufferManager снизить давление на ГХ?

  2. Какие рабочие нагрузки (таблица, очередь, BLOB-объекты) выиграют от использования этого кэша?

  3. Каковы (измеримые) условия, в которых я должен реализовать IBufferManager?

  4. Безопасен ли поток BufferManager? Могу ли я иметь пул буферов на сервере времени выполнения, который я выделяю при необходимости?

  5. Как я должен / не должен реализовать этот bufferManager? (например, потоки, IDisposable, предварительное распределение в статическом методе, Redis)

1 ответ

@LamonteCristo, это хорошие вопросы.

Является ли единственной целью IBufferManager снизить давление на ГХ?

BufferManager не только снижает нагрузку на ГХ, но также может повысить производительность сервера хранения. GC может создавать и уничтожать буферный пул, и этот процесс требует затрат на каждое выделение ресурсов компьютера. BufferManager может хранить буферный пул и работает быстрее, чем GC каждый раз. Между тем, я рекомендую вам обратиться к этим ответам.

Какие рабочие нагрузки (таблица, очередь, BLOB-объекты) выиграют от использования этого кэша?

Ответ - да. SDK хранилища Azure предоставил эту функцию для этих трех служб хранения. И это одни и те же методы.

Каковы (измеримые) условия, в которых я должен реализовать IBufferManager?

Теоретически мы можем делать параллельные запросы с большим разным MaxBufferSize, чтобы получить время отклика сервера. А затем снова отправьте эти запросы, чтобы снова получить время ответа. Мы можем сравнить эти два времени ответа. На самом деле, это баланс между временем и памятью.

Безопасен ли поток BufferManager? Могу ли я иметь пул буферов на сервере времени выполнения, который я выделяю при необходимости?

По моему опыту, это не безопасно для потоков, если мы используем один и тот же экземпляр в нескольких потоках. Пожалуйста, обратитесь к этому документу ( https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.buffermanager(v=vs.110).aspx 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' в вашем коде. Любые проблемы, пожалуйста, дайте мне знать.

Другие вопросы по тегам