12

I have taken a database class this semester and we are studying about maintaining cache consistency between the RDBMS and a cache server such as memcached. The consistency issues arise when there are race conditions. For example:

  1. Suppose I do a get(key) from the cache and there is a cache miss. Because I get a cache miss, I fetch the data from the database, and then do a put(key,value) into the cache.
  2. But, a race condition might happen, where some other user might delete the data I fetched from the database. This delete might happen before I do a put into the cache.

Thus, ideally the put into the cache should not happen, since the data is longer present in the database.

If the cache entry has a TTL, the entry in the cache might expire. But still, there is a window where the data in the cache is inconsistent with the database.

I have been searching for articles/research papers which speak about this kind of issues. But, I could not find any useful resources.

4

4 回答 4

2

本文为您提供了有关 Facebook(尝试)如何保持缓存一致性的有趣说明:http ://www.25hoursaday.com/weblog/2008/08/21/HowFacebookKeepsMemcachedConsistentAcrossGeoDistributedDataCenters.aspx

这是文章的要点。

  1. 我将我的名字从“Jason”更新为“Monkey”
  2. 我们将“Monkey”写入加利福尼亚的主数据库,并从加利福尼亚的内存缓存中删除我的名字,而不是弗吉尼亚
  3. 有人访问我在弗吉尼亚州的个人资料
  4. 我们在 memcache 中找到我的名字并返回“Jason”
  5. 复制赶上了,我们用我的名字“Monkey”更新了从数据库。我们还从 Virginia memcache 中删除了我的名字,因为该缓存对象出现在复制流中
  6. 其他人访问了我在弗吉尼亚州的个人资料
  7. 我们在 memcache 中找不到我的名字,所以我们从奴隶读取并得到“猴子”
于 2016-09-08T16:38:00.203 回答
0

使用内存缓存中的变量保存作为锁定信号怎么样?

每个 memcache 命令都是原子的

从数据库检索数据后,打开锁定

将数据放入内存缓存后,关闭锁定

从数据库中删除之前,检查锁定状态

于 2013-03-27T02:10:27.070 回答
0

下面的代码给出了一些关于如何使用 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
于 2017-12-03T19:10:40.660 回答
-1

当您阅读时,会发生以下情况:

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
于 2015-12-29T17:39:10.213 回答