Согласованность кэша при использовании memcached и rdbms, таких как MySQL - PullRequest
10 голосов
/ 18 октября 2011

В этом семестре я взял класс базы данных, и мы изучаем, как поддерживать согласованность кэша между СУБД и сервером кэширования, таким как memcached. Проблемы согласованности возникают, когда есть условия гонки. Например:

  1. Предположим, я делаю get(key) из кеша, и отсутствует кеш. Из-за пропуска кэша я извлекаю данные из базы данных и затем put(key,value) в кеш.
  2. Но может возникнуть состояние гонки, когда какой-то другой пользователь может удалить данные, которые я выбрал из базы данных. Это удаление может произойти до того, как я введу put в кеш.

Таким образом, в идеале put в кеше не должно происходить, поскольку данные больше присутствуют в базе данных.

Если запись в кэше имеет TTL, срок действия записи в кэше может истечь. Но, тем не менее, есть окно, в котором данные в кеше несовместимы с базой данных.

Я искал статьи / исследовательские работы, в которых говорилось бы о проблемах такого рода. Но я не смог найти никаких полезных ресурсов.

Ответы [ 4 ]

1 голос
/ 08 сентября 2016

В этой статье содержится интересная заметка о том, как Facebook (пытается) поддерживать согласованность кэша: http://www.25hoursaday.com/weblog/2008/08/21/HowFacebookKeepsMemcachedConsistentAcrossGeoDistributedDataCenters.aspx

Вот суть статьи.

  1. Я обновляю свое имя с «Jason» до «Monkey»
  2. Мы записываем «Monkey» в основную базу данных в Калифорнии и удаляем мое имя из memcache в Калифорнии, ноне Вирджиния
  3. Кто-то заходит на мой профиль в Вирджинии
  4. Мы находим мое имя в memcache и возвращаем "Jason"
  5. Репликация догоняет и мыобновите базу данных подчиненных с моим именем «Обезьяна». Мы также удаляем мое имя из memcache Вирджинии, потому что этот объект кэша обнаружен в потоке репликации
  6. Кто-то другой заходит в мой профиль в Вирджинии
  7. Мы не можемне могу найти мое имя в memcache, поэтому мы читаем с раба и получаем «Обезьяна»
0 голосов
/ 03 декабря 2017

Приведенный ниже код дает некоторое представление о том, как использовать операции Memcached add, gets и cas для реализации оптимистической блокировки, чтобы обеспечить согласованность кэша с базой данных.совершенно правильно и обрабатывает все условия гонки.Кроме того, требования к согласованности могут отличаться для разных приложений.

def read(k):
  loop:
    get(k)
    if cache_value == 'updating':
      handle_too_many_retries()
      sleep()
      continue
    if cache_value == None:
      add(k, 'updating')
      gets(k)
      get_from_db(k)
      if cache_value == 'updating':
        cas(k, 'value:' + version_index(db_value) + ':' + extract_value(db_value))
      return db_value
    return extract_value(cache_value)

def write(k, v):
  set_to_db(k, v)
  loop:
    gets(k)
    if cache_value != 'updated' and cache_value != None and version_index(cache_value) >= version_index(db_value):
      break
    if cas(k, v):
      break
    handle_too_many_retries()

# for deleting we can use some 'tumbstone' as a cache value
0 голосов
/ 29 декабря 2015

Когда вы читаете, происходит следующее:

if(Key is not in cache){
  fetch data from db
  put(key,value);
}else{
  return get(key)
}

Когда вы пишете, происходит следующее:

1 delete/update data from db
2 clear cache
0 голосов
/ 27 марта 2013

Как насчет использования переменной save в memcache в качестве сигнала блокировки?

каждая отдельная команда memcache является атомарной

после того, как вы получили данные из базы данных, переключите блокировку на

после помещения данных в memcache отключите блокировку

перед удалением из базы данных, проверьте состояние блокировки

...