前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Redis的删库与跑路

Redis的删库与跑路

作者头像
一个架构师
发布2022-06-20 19:46:21
发布2022-06-20 19:46:21
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

Redis作为最流行的内存数据库之一,几乎每个公司都对其有所依赖.而大家都会注意的问题是”mysql库的删库与跑路”,很容易忽略redis这个依赖性非常高的中间件,一旦出问题,势必对整个业务甚至整个公司有影响.

举个例子:

redis是单线程数据库,如果一个命令执行时间很长,很容易造成请求挤压,进而会造成请求的大量超时,系统熔断,业务崩溃,甚至雪崩.

再比如redis数据被误删了,缓存击穿,压垮数据库,系统雪崩.

如果redis存储的是业务处理结果或者作为队列等使用,后果会更严重.

redis危险命令

罪不在枪,而在于扣动扳机的人

这些命令确实在一定情况下会产生危害,但只要使用的合理是可以给我们很多帮助的.

1. key查找命令: keys *

因为redis是单线程的,keys操作会使其他的请求都会被堵塞,对于数据量较小时,基本没有影响;但是当数据量达到百万千万级别的时候,这个会造成数据库崩溃,使用的业务崩溃,引起雪崩.

2. 清空数据库: flushdb

清空所有记录: flushall

3. 服务关机: shutdown

4. 数据库互相交换swapdb

swapdb 0 1 这将使数据库0与数据库1交换

5. 数据持久化: save

数据持久化操作,生成rdb文件,并对键进行检查,过期键过滤掉,这时系统会被阻塞,不能接受处理客户端命令

6. 系统配置项查看修改: config

6.1 修改日志级别产生大量日志

代码语言:javascript
代码运行次数:0
复制
127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "notice"
127.0.0.1:6379> config set loglevel "debug"
ok
127.0.0.1:6379> config get loglevel
1) "loglevel"
2) "debug"

6.2 修改服务密码,所有链接全部无法正常请求,系统崩溃

代码语言:javascript
代码运行次数:0
复制
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass foobar
ok
127.0.0.1:6379> config get requirepass
(error) noauth authentication required.
127.0.0.1:6379> auth foobar
ok
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "foobar"
127.0.0.1:6379> 

7. lua脚本相关命令: eval, evalsha, script

8. 调试命令:debug

这个命令不全都包含危险选项,也有很多有用的调试选项.

8.1 危险选项

8.1.1 debug oom

极度危险命令,申请一大片内存,直接让zmalloc触发oom错误,造成服务崩溃.

8.1.2 debug reload

保存rdb文件,清空当前数据库,重新加载rdb,加载与启动时加载类似,加载过程中只能服务部分只读请求(比如info,ping等)

8.1.3 debug loadaof

清空当前数据库,重新从aof文件里加载数据库

8.1.4 debug sleep

模拟一个需指定执行时间开销的命令

debug sleep 0.1相当于执行了一条开销为100ms的命令.

8.2 调试选项

8.2.1 debug digest

对整个数据库的数据,产生一个摘要,验证两个redis数据库数据是否一致.

8.2.2 debug object

查看key的数据类型等基本信息

代码语言:javascript
代码运行次数:0
复制
127.0.0.1:6379> set key a
ok
127.0.0.1:6379> debug object key
value at:0x7f6701d2fe70 refcount:1 encoding:embstr serializedlength:2 lru:10152892 lru_seconds_idle:10

8.2.3 debug populate

快速产生大量的key

代码语言:javascript
代码运行次数:0
复制
127.0.0.1:6379> debug populate 1000
ok
127.0.0.1:6379> dbsize
(integer) 1000

如何保护你的redis

这些命令就像达摩克利斯之剑,让人战战兢兢,压力倍增.

那该如何解决呢?

1. keys命令的优化

1.1 randomkey

随机返回一个key,在数据量非常多的时候,可以初步观察库中key的构成情况.

1.2 scan

使用如下命令,相当于keys *命令

代码语言:javascript
代码运行次数:0
复制
scan 0 match * count 3

配合游标,匹配正则,返回总数可以很方便的查询想要的结果.

2. save的优化

使用bgsave命令代替save命令做数据持久化.

bgsave命令会 fork 出一个子进程,子进程负责持久化rdb文件,并在保存完成之后向主进程发送信号,通知保存已完成.redis 服务器在bgsave执行期间仍然可以继续处理客户端的请求.

3. 其他命令

对应flushdb,flushall,shutdown等命令,并没有合适的替代命令,但可以通过配置文件禁用和重命名命令

redis.conf 文件中有security 选项处,有rename-command配置.

#命令禁用

rename-command keys ""

rename-command flushall ""

rename-command flushdb ""

#命令重命名

rename-command config config_proxy

代码语言:javascript
代码运行次数:0
复制
127.0.0.1:6380> flushall
(error) err unknown command `flushall`, with args beginning with: 
127.0.0.1:6380> 
127.0.0.1:6380> 
127.0.0.1:6380> keys *
(error) err unknown command `keys`, with args beginning with: `*`, 
127.0.0.1:6380> 
127.0.0.1:6380> 
127.0.0.1:6380> config get *
(error) err unknown command `config`, with args beginning with: `get`, `*`, 
127.0.0.1:6380> config_proxy get *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""

在使用rename-command配置时,redis还有一段提示信息要注意.

代码语言:javascript
代码运行次数:0
复制
please note that changing the name of commands that are logged into theaof file or transmitted to slaves may cause problems.

这段信息的意思是:如果重命名的命令会存入在aof文件中,或者如果该重命名命令需传输到slave服务,而slave服务未进行相关配置,则会引起问题.

所以,处理重命名的最佳方法是确保将重命名命令应用于主从安装中的所有实例中.

请记住,一旦有人登录到您的服务器,就很容易规避我们已部署的redis特定的安全功能,所以防火墙很重要;

祸起萧墙,操作规范也非常重要,不要真的变成了删库跑路.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从码农的全世界路过 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档