当前位置: 首页 > 科技观察

Redis敢于在线做Keys正则匹配操作!你可以辞职了!

时间:2023-03-19 02:04:11 科技观察

业界铁律,redis开发规范中有一条铁律如下图OnlineRedis禁止使用Keys正则匹配操作。然而,谁都知道,总是忘记,所以意外会不断发生。下面说一下线上执行正则匹配操作,导致缓存雪崩,最终导致数据库宕机的原因。分析原因就OK了,先说几句废话。1、Redis是单线程的,所有的操作都是原子的,不会因为并发而产生数据异常。2、使用耗时的Redis命令是非常危险的,会占用一个线程大量的处理时间,导致所有的请求变慢。(比如时间复杂度为O(N)的KEYS命令在生产环境中是严禁使用的。)有了上面两句话的铺垫,道理就很明显了。(1)运维人员进行keys*操作,比较耗时,而且由于redis是单线程的,redis是有锁的。(2)此时QPS比较高,对redis的读写请求有几万,因为redis是加锁的,所以都是hang。(3)由于挂在那里的线程太多,导致CPU飙升严重,导致redis所在服务器宕机。需要注意的是,同样危险的命令不仅包括keys*,还包括以下几组Flushdb命令,用于清除当前数据库中的所有keys。Flushall命令用于清除整个Redis服务器的数据(删除所有数据库中的所有key)CONFIG客户端连接终端后,即可对服务器进行配置。所以,一个合格的redis运维或者开发应该知道如何禁用上面的命令。所以我一直觉得,新闻中出现这种情况的原因,一般都是人员水平问题。如何禁用这些命令?在redis.conf中,在SECURITY项中,我们添加如下命令:rename-commandFLUSHALL""rename-commandFLUSHDB""rename-commandCONFIG""rename-commandKEYS""另外,对于FLUSHALL命令,需要设置appendonlynoin配置文件,否则服务器不会启动。注意上面的命令可能会遗漏,可以查看官方文档。除了Flushdb等与redis安全风险相关的命令外,凡是时间复杂度为O(N)的命令都要慎重,生产中不要随便使用。比如hgetall、lrange、smembers、zrange、sinter等命令并不是不能用,但是这些命令的时间复杂度是O(N)。要使用这些命令,需要指定N的值,否则也会发生缓存崩溃。改进建议业界推荐使用scan命令来改进keys和SMEMBERS命令。redis2.8之后新增了一个命令scan,可以用来批量扫描redis记录。这样肯定会增加整个查询消耗的总时间,但不会影响redis服务卡顿,影响服务使用。