Доступ к кешу в высококонкурентных системах - PullRequest
3 голосов
/ 17 ноября 2010

Предположим, у меня есть два потока (Thread1, Thread2), где потоки обращаются к кэшу для данного объекта, например, в коде ниже почти одновременно:

    Dim expensiveToGetData = Cache("ExpensiveDataKey")

    If ExpensiveToGetData is nothing then
'because the cache has expired

ExpensiveToGetData = LoadExpensiveDataFromDataSource()
       Cache("ExpensiveDataKey") = ExpensiveToGetData
    end If

    ProcessExpensiveData(ExpensiveToGetData)

Isn 'Возможно ли, чтобы оба потока загружали кеш, потому что они оба запрашивали данные из кеша, для которых ничего не было / просрочено?Я провел несколько тестов на локальной машине, и кажется, что кэш загружается более одного раза.Это нормальный паттерн?

Ответы [ 2 ]

2 голосов
/ 17 ноября 2010

Да, это возможно, и это не желаемый шаблон. В качестве быстрого исправления вы могли бы установить блокировку мьютекса кешем в качестве быстрого исправления, но в идеале лучше было бы сделать так, чтобы кеш выполнял роль посредника, загружающего сами дорогие данные. В этом шаблоне проектирования гораздо больше, чем я упоминал, но он должен помочь вам начать работу.

2 голосов
/ 17 ноября 2010

Да, используя этот код, вполне возможно, что два разных запроса ничего не получат от Cache, и, следовательно, оба перезагрузят данные.Если вы хотите избежать этого, вам нужно синхронизировать всю операцию получения данных.

Один из способов синхронизировать доступ - использовать код, подобный следующему:

Dim expensiveToGetData = Cache("ExpensiveDataKey")

If ExpensiveToGetData is nothing then
    SyncLock yourLockObject /* YourLockObject should be a Shared object. */
        expensiveToGetData = Cache("ExpensiveDataKey")
        If expensiveToGetData Is Nothing Then
            ExpensiveToGetData = LoadExpensiveDataFromDataSource()
            Cache("ExpensiveDataKey") = ExpensiveToGetData
        End If
    End SyncLock
end If

ProcessExpensiveData(ExpensiveToGetData)

Идея проверки, получили ли мы данные до получения блокировки, состоит в том, чтобы избежать чрезмерной блокировкисреда под высокой нагрузкой.Если его там нет, нам нужно еще раз проверить внутри блокировки, потому что другой поток мог получить данные во время получения блокировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...