Redis主从模式下,当对一个key设定过期时间,到期之后从库依然能够读取到数据。这个问题困扰了我很久,相信很多人都遇到过这种问题了。(前提是你不去读主库,并且redis版本在3.2以下)。
经过一番搜寻,发现很多人遇到的问题和我一样。
主Redis
setex test 20 1 +OK get test $1 1 ttl test :18
从Redis
get test $1 1 ttl test :7
以上都没问题,然而过几秒再看从Redis
ttl test :-1 get test $1 1
test这个key已经过期了,然而还是可以获取到test的值。
在使用Redis做锁的时候,如果直接取读从库的值,这就有大问题了。
为什么从库不删除数据?
redis删除过期数据有以下几个策略:
1.惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key,很明显,这是被动的!
2.定期删除:由于惰性删除策略无法保证冷数据被及时删掉,所以 redis 会定期主动淘汰一批已过期的key。(在第二节中会具体说明)
3.主动删除:当前已用内存超过maxMemory限定时,触发主动清理策略。主动设置的前提是设置了maxMemory的值
int expireIfNeeded(redisDb *db, robj *key) { time_t when = getExpire(db,key); if (when < 0) return 0; /* No expire for this key */ /* Don't expire anything while loading. It will be done later. */ if (server.loading) return 0; /* If we are running in the context of a slave, return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. * * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */ if (server.masterhost != NULL) { return time(NULL) > when; } /* Return when this key has not expired */ if (time(NULL) <= when) return 0; /* Delete the key */ server.stat_expiredkeys++; propagateExpire(db,key); return dbDelete(db,key); }
你可能还喜欢下面这些文章
作为一个博客系统,wordpress在易用性和可扩展性上都非常出色。后题用户体验是非友好,插件众多。然而由于定位的问题,wordpress无法支撑大量文章。当文章数量达到上万的时候,有些主题的前台可能会非常卡。当文章数量达到数十万的时候,wordpress后台可能会特别卡。更何况大部分插件并没有在性能上下功夫,插件越多,wordpress越卡。那么有没有什么方案能让wordpress支撑大量文章?十万,百万,甚至更多?支撑百万数据并不是存入一百万文章就可以了。实际上百万文章对mysql来说毫无压力。在mysql中,百万文章仅仅是百万条记录而已。导致缓慢的是mysql的查询。对于百万条记录的数据
在制作一个页面的时候,有需要前台js保存用户自定义的样式的需求,但是保存之后,重新刷新页面,会显示原来的样式,然后再变更为现在的自定义的样式。这是一个有闪烁的例子,点击打开保存样式之后,再重新强制刷新几次,可以看到页面在载入的时候会出现闪烁的情况。强迫症患者表示这不能接受,页面这么小的情况都闪烁的这么厉害,这页面大了,加载速度慢了,自定义样式还得等着加载完成之后才能显示,就失去了自定义的意义了。上面的闪烁是可以理解的,css渲染完成之后,js给body增加了一个class,浏览器又会重新渲染,因此会出现短暂的闪烁那么在渲染到head的时候,此时再用js给head标签里面增加css呢?这样不就在
bash 4.1.2 版本增加了map数据结构。map是一种常用的数据结构,通过map可以将key映射到一个value。使用方法map在使用之前需要先声明,声明的方式如下declare -A map_namemap需要先声明再使用。参数-A表示声明的变量是一个map。需要注意的是这里的A是大写的字母A。赋值操作map的赋值有两种方式,一种是直接给map赋值,如下:map_name=([“foo”]=”bar” [“hello”]=”world”)另一种是使用下标给map添加key-value对map_name[“foo”]=”bar”map_name[“hello”]=”world”输出所有的
赞赏微信赞赏
支付宝赞赏