memcache应对缓存失效问题
.两个key,一个key用来存放数据,另一个用来标记失效时间
比如key是aaa,设置失效时间为30s,则另一个key为expire_aaa,失效时间为25s。
在取数据时,用multiget,同时取出aaa和expire_aaa,如果expire_aaa的value == null,则后台启动一个任务去查询DB,更新缓存。和上面类似。
对于后台启动一个任务去查询DB,更新缓存,要保证一个key只有一个线程在执行,这个如何实现?
对于同一个进程,简单加锁即可。拿到锁的就去更新DB,没拿到锁的直接返回。
对于集群式的部署的,如何实现只允许一个任务执行?
这里就要用到memcached的add命令了。
add命令是如果不存在key,则设置成功,返回true,如果已存在key,则不存储,返回false。
当get expired_aaa是null时,则add expired_aaa 过期时间由自己灵活处理。比如设置为3秒。
如果成功了,再去查询DB,查到数据后,再set expired_aaa为25秒。set aaa 为30秒。
综上所述,来梳理下流程:
比如一个key是aaa,失效时间是30s。查询DB在1s内。
- put数据时,设置aaa过期时间30s,设置expire_aaa过期时间25s;
- get数据时,multiget aaa 和 expire_aaa,如果expired_aaa对应的value != null,则直接返回aaa对应的数据给用户。如果expire_aaa返回value == null,则后台启动一个任务,尝试add expire_aaa,并设置超时过间为3s。这里设置为3s是为了防止后台任务失败或者阻塞,如果这个任务执行失败,那么3秒后,如果有另外的用户访问,那么可以再次尝试查询DB。如果add执行成功,则查询DB,再更新aaa的缓存,并设置expire_aaa的超时时间为25s。