方案一:
用一个单独的集合(Set)把一类key维护起来。当需要批量删除(或更新)时只需要取出这个集合里的所有key进行相应的操作即可。这样做起来比较简单:
首先,我们往memcached里面添加一个新的k,v时,就往那个set里加一个key,比如一条新闻在memcached里面有下面这些 对:
key_{newsid}_{prop1}:value1key_{newsid}_{prop2}:value2key_{newsid}_{prop3}:value3……key_{newsid}_{propn}:valuen在我们的集合里面,就要存放所有跟这条新闻有关key的集合:
keyset_{newsid}:key_{newsid}_{prop1},key_{newsid}_{prop2},……,key_{newsid}_{propn})这样,当我们要清除这条新闻的缓存时,就可以取出这个key的集合,然后遍历这些key,到memcached里面逐个删除,这样就达到了批量删除的目的。
在这里,我们提到的这个key set具体怎么存放和维护呢?
一种方式是,在memcached里面把所有key用逗号拼接成一个大字符串构成keyset的value或者借助开发语言提供的集合结构(set)来组织数据,系列化到memcached中。
另一种方式是,借助更方便的存储结构来保存这个key,比如redis的set结构,当然了,这种方式并不推荐,会给现有系统带来复杂度。
方案二:
通过动态更新key的方式来实现,这种方式是给每一个key都在原来key的基础上加一个版本号来组成,当需要批量删除或更新时只需升级版本号即可,具体怎么做呢?
首先,我们在memcached给这条新闻维护一个版本号,这样:
key_version_{newsid}:v1.0 (版本号可以用时间戳或其它任何有意义的内容代替)// 伪代码$memcacheClient->setVersion(key_version{newsid}, "v1.0");然后,当我们要保存或读取这条新闻相关的数据时,先取出这个版本号来生成新的key,如下:
//伪代码$version = getVersion(key_version_{newsid});$key = "key_{newsid}_{prop}_" + $version;再用这个新的key来保存(或读取)真正的内容,这样在memcached里面保存的跟这条新闻有关的 对就是下面这样了:
key_{newsid}_{prop1}_v1.0:value1 key_{newsid}_{prop2}_v1.0:value2key_{newsid}_{prop3}_v1.0:value3……key_{newsid}_{propn}_v1.0:valuen当我们需要删除(或更新)这条新闻相关的所有key时,只需要升级版本号即可,如下:
//伪代码$memcacheClient->updateVersion(key_version_{newsid},"v2.0");这样的话,当我们下次访问这条新闻的缓存时,由于版本号升级,新的key下所有内容都为空,需要从数据库加载新的内容,或者是返回空的结果。而旧的key在过期时间到了以后也就可以回收利用了。这样就达到了我们批量删除或更新的目的。