【Redis】开发运维中的陷阱

1.redis开发运维中的陷阱 

1.密码机制
redis的密码机制:
redis提供了 requirepass 配置为redis提供了密码功能,如果添加这个配置
客户端不能通过redis-cli -h {ip} -p {port} 直接登录。

redis提供了两种方式访问配置了密码的redis:
redis-cli -a ,写入密码,并且防止将密码写入命令行,而是写入提示符号中。
第二种方法是,先登录,然后使用 auth 命令认证。
redis-cli 
127.0.0.1:6379>auth "mypasswd"
注意设置较为复杂的密码。同时从库加入配置  masterauth "mypasswd",主库的密码。

2.危险命令的使用
redis中的危险命令:
keys :如果键值较多,存在阻塞Redis的可能性。
flushall/flushdb:数据全部被清除。
save:如果键值较多,存在阻塞redis可能性。
debug:例如:debug reload 会重启redis 
config:config应该交由管理员使用。
shutdown:停止redis;

3.linux 参数配置
vm.overcommit_memory=1 
vm.overcommit_memory 三个可选的值及说明。

0:表示内核将检查是否有足够的可用内存。如果有足够的可用内存,内存申请通过,
否则内存申请失败,并把错误返回给应用程序。
1:表示内核允许超量使用内存直到用完为止。
2:表示内核决不过量使用内存,即系统整个内存地址空间不能超过swap+50%的RAM 值,
50%是 overcommit_ratio 默认值,此参数也支持修改。

修改
cat /proc/sys/vm/overcommit_memory
0

echo "vm.overcommit_memory=1" >>/etc/sysctl.conf 
sysctl vm.overcommit_memory=1 

Redis设置合理的maxmemory,保证机器有20%-30%的闲置内存。
设置 vm.overcommit_memory=1,防止极端情况下造成fork 失败。

swapiness:
swap空间由硬盘提供,对于需要高并发,高吞吐的应用来说,磁盘IO通常会成为
系统瓶颈,系统参数 swapiness 会决定操作系统使用swap 的倾向程度。
swapiness 取值范围 0-100,swapiness 值越大,说明操作系统可能使用 
swap的概率越高,swapiness 值越大,表示操作系统更加倾向于使用物理内存。

swapiness 重要值策略说明 
0 :Linux3.5 及以上:宁愿用OMM killer也不会使用swap 
0 :Linux3.4 及更早:宁愿用swap 也不用 OOM killer  
1 :Linux3.5 以及以上:宁愿用 swap也不用 OOM killer  
60 :默认值 
100 :操作系统主动使用swap 

OOM(Out Of Memory) killer 机制是指Linux操作系统发现可用内存不足时,强制 
杀死一些用户进程(非内核进程),来保证系统有足够的可用内存进行分配。

设置swapiness的方法 
echo 1 > /proc/sys/vm/swapiness
立即生效:
echo vm.swapiness=1 >>/etc/sysctl.conf  
sysctl -p  

如果Linux>3.5 设置:vm.swapiness=1 
如果Linux<3.5 设置:vm.swapiness=0 
物理内存充足的时候,使redis足够快。
物理内存不足的时候,避免redis死掉。

THP:
linux kernel 在2.6.38 内核增加了THP特性,支持大内存页(2M)分配,默认开启。
当开启时可以加快fork子进程的速度,但fork操作之后,每个内存页从原来4KB 
变为2MB,会大幅增加重写期间父进程内存消耗。同时每次写命令引起的复制内存页单位放大
了512倍,会拖慢操作的执行时间,导致大量写操作慢查询。
禁用方法:
echo never > /sys/kernel/mm/transparent_hugepage/enabled 


OOM Killer; 
OOM Killer 进程会为每个用户进程设置一个权值,这个权值越高,被 "下手"
的概率越高,反之概率越低。
对于redis所在服务器来说,可以将所有redis的oom_adj 设置为最低值 
或者稍小的值,降低被OOM Killer杀掉的概率。

for redis_pid in $(pgrep -f "redis-server")
do 
	echo -17 > /proc/${redis_pid}/oom_adj
done  

NTP
机器需要通过NTP通过公司的时钟服务器的时间,或者自定义使用服务器。
让Redis集群节点的时钟保持一致。例如每小时同步一次公司的时钟服务器。
0 * * * * /usr/sbin/ntpdate ntp.xx.com >/dev/null 2>&1 


ulimit:
在linux中,可以通过ulimit查看和设置系统当前用户进程的资源数。其中 
ulimit -a 命令包含的 open files 参数,是单个用户同时打开的最大文件描述符个数。

redis 允许同时有多个客户端通过网络进行连接,可以通过配置 maxclients 来限制 
最大客户端连接数。对linux操作系统来说,这些网络连接都是文件句柄。

maxclients+32 ,openfiles  两个的较小值决定单个用户打开最大文件描述符的最大值。
ulimit -a  查看 openfiles; 
设置 openfiles; 
ulimit -Sn 65536

TCP backlog; 
设置 TCP backlog 与 redis的backlog 相同。
redis的默认的tcp-backlog值为511,可以通过修改配置 tcp-backlog进行调整,
如果linux的tcp-backlog小于redis设置的 tcp-backlog,redis会有警告。

linux默认的tcp-backlog是128,修改Linux的tcp-backlog; 
echo 511 > /proc/sys/net/core/somaxconn 


一、误操作flushallo/flushdb 如何进行恢复 
1.恢复前提条件 
(1)appendonly=yes  参数设置。
(2)或者有最近备份的RDB文件

2.紧急操作 
(1)调大 AOF重写参数 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size,
让 redis不能产生AOF自动重写。
(2)拒绝手动执行 bgrewriteoaf
--主从节点都修改。
config set auto-aof-rewrite-percentage=1000 
config set auto-aof-rewrite-min-size=100000000000

3.恢复
如果 appendonly=no,则没有可供恢复的AOF文件。所以生产环境建议设置:appendonly=yes
如果 appendonly=yes,只不过是在AOF文件中追加了一条记录。
AOF文件中的flush操作记录如下:
*1
$8 
flushall 

由于AOF是可编辑文件,可以删除上面的三行,使用 redis-check-aof 这个工具验证和修复一下AOF文件。
确保AOF文件格式正确,保证数据恢复正常。

重启redis主节点服务器恢复数据。

注意:如果 AOF 文件被重写,redis遍历所有数据库生成新的AOF,则无法使用AOF恢复。之前的数据丢失。

如果:appendonly=no,则需要查看redis是否开启 RDB的自动策略。
如果配置文件中有:
save 900 1
save 300 10 
save 60 10000

RDB文件会被清除,则无法恢复。
如果配置文件中没有上述配置,且未执行过 save,bgsave 等命令,RDB 文件可以用于恢复。
但是数据一致性不高。

4.自动化处理flushall/flushdb的情况。
前提开启:appendonly=yes
--主库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

--从库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

删除:AOF文件中如下三行:
*1
$8 
flushall
--验证文件 
redis-check-aof redis.aof 
--重启redis;
一、误操作flushallo/flushdb 如何进行恢复 
1.恢复前提条件 
(1)appendonly=yes  参数设置。
(2)或者有最近备份的RDB文件

2.紧急操作 
(1)调大 AOF重写参数 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size,
让 redis不能产生AOF自动重写。
(2)拒绝手动执行 bgrewriteoaf
--主从节点都修改。
config set auto-aof-rewrite-percentage=1000 
config set auto-aof-rewrite-min-size=100000000000

3.恢复
如果 appendonly=no,则没有可供恢复的AOF文件。所以生产环境建议设置:appendonly=yes
如果 appendonly=yes,只不过是在AOF文件中追加了一条记录。
AOF文件中的flush操作记录如下:
*1
$8 
flushall 

由于AOF是可编辑文件,可以删除上面的三行,使用 redis-check-aof 这个工具验证和修复一下AOF文件。
确保AOF文件格式正确,保证数据恢复正常。

重启redis主节点服务器恢复数据。

注意:如果 AOF 文件被重写,redis遍历所有数据库生成新的AOF,则无法使用AOF恢复。之前的数据丢失。

如果:appendonly=no,则需要查看redis是否开启 RDB的自动策略。
如果配置文件中有:
save 900 1
save 300 10 
save 60 10000

RDB文件会被清除,则无法恢复。
如果配置文件中没有上述配置,且未执行过 save,bgsave 等命令,RDB 文件可以用于恢复。
但是数据一致性不高。

4.自动化处理flushall/flushdb的情况。
前提开启:appendonly=yes
--主库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

--从库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

删除:AOF文件中如下三行:
*1
$8 
flushall
--验证文件 
redis-check-aof redis.aof 
--重启redis;

一、误操作flushallo/flushdb 如何进行恢复 
1.恢复前提条件 
(1)appendonly=yes  参数设置。
(2)或者有最近备份的RDB文件

2.紧急操作 
(1)调大 AOF重写参数 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size,
让 redis不能产生AOF自动重写。
(2)拒绝手动执行 bgrewriteoaf
--主从节点都修改。
config set auto-aof-rewrite-percentage=1000 
config set auto-aof-rewrite-min-size=100000000000

3.恢复
如果 appendonly=no,则没有可供恢复的AOF文件。所以生产环境建议设置:appendonly=yes
如果 appendonly=yes,只不过是在AOF文件中追加了一条记录。
AOF文件中的flush操作记录如下:
*1
$8 
flushall 

由于AOF是可编辑文件,可以删除上面的三行,使用 redis-check-aof 这个工具验证和修复一下AOF文件。
确保AOF文件格式正确,保证数据恢复正常。

重启redis主节点服务器恢复数据。

注意:如果 AOF 文件被重写,redis遍历所有数据库生成新的AOF,则无法使用AOF恢复。之前的数据丢失。

如果:appendonly=no,则需要查看redis是否开启 RDB的自动策略。
如果配置文件中有:
save 900 1
save 300 10 
save 60 10000

RDB文件会被清除,则无法恢复。
如果配置文件中没有上述配置,且未执行过 save,bgsave 等命令,RDB 文件可以用于恢复。
但是数据一致性不高。

4.自动化处理flushall/flushdb的情况。
前提开启:appendonly=yes
--主库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

--从库。
redis-cli -h {host} -p {port} config set auto-aof-rewrite-percentage=1000 
redis-cli -h {host} -p {port} config set auto-aof-rewrite-min-size=100000000000

删除:AOF文件中如下三行:
*1
$8 
flushall
--验证文件 
redis-check-aof redis.aof 
--重启redis;

Redis的安全。
2015年11月,全球数万个redis节点遭受了攻击,所有数据都被清除了,只有一个叫
crackit 的键存在。
被攻击的机器有如下特点:
redis所在的机器有外网IP;
redis以默认端口6379为启动端口,并且是对外网开放的。
redis是以root用户启动的。
redis没有设置密码。
redis的bind 设置为 0.0.0.0 或者 ""

--防火墙。
可以使用防火墙限制输入和输出的IP或者IP范围,端口或者端口范围,在比较成熟的公司
都会对外网IP的服务器做一些端口限制,例如只允许80端口对外开放。防火墙是限制
外网访问redis的必杀技。

bind:
bind 参数指定的是redis和哪个网卡进行绑定,和客户端是什么网段没有关系。

--定期备份 
虽然redis有持久化机制,还是建议定期备份redis的RDB或者AOF文件。

--不适用默认端口。
redis的默认端口是6379,不使用默认端口从一定程度上可降低被入侵者发现的可能性。
MySQL的默认端口是3306,Memcache的默认端口是11211,Jetty的默认端口是8080,
这些默认端口都是容易被攻击的。所以需要设置非默认端口。

--非root用户启动。
建议使用非root用户启动。防止入侵者获取到root权限造成致命伤害。
Resin,Jetty,HBase,Hadoop都建议使用非root启动。

--处理bigkey 
bigkey 是指key对应的value所占的内存空间比较大,例如一个字符串类型的value
最大可以存512M,一个列表类型最多可以存储2^32-1 个元素。
字符串类型:一般认为超过10Kb就是bigkey;
非字符串类型:哈希,列表,集合,有序集合,体现在元素个数过多。

bigkey造成的危害:
内存空间不均匀 
超时阻塞。
网络拥堵。

bigkey 在高并发的场景下,会造成网络拥堵,应该尽可能减少bigkey的使用。
优化bigkey;
加入一个bigkey 1M,每秒访问1000次,那么每秒产生1000M的流量。
对于普通的千兆网卡的服务器就是灭顶之灾。

发现bigkey;
redis-cli --bigkeys 
另外,判断一个key是否为bigkey,只需要执行debug object key 查看serializedlength
属性即可,它表示key对应的value序列化之后的字节数。
127.0.0.1:6379>debug object key  

字符串可以使用:
127.0.0.1:6379>strlen key  查看字符串的大小。

--热点key;
热点key需要通过开发程序去记录。DBA无工具几乎无法捕获。
热门新闻事件或商品通常会给系统代理巨大的流量,对存储这类信息的redis来说
是一个巨大的挑战。以redis cluster为例,它会造成整体流量的不均衡,个别节点
出现OPS过大的情况,极端情况下热点key设置会超过redis本身能够承受的OPS;

寻找热点key可以使用monitor,但是此命令仅可以短时间使用,长时间使用造成系统阻塞。
处理热点key的三种方案:
1)拆分复杂数据结构:如果当前key的类型是一个二级数据结构,例如哈希类型。
如果该哈希元素个数较多,可以考虑将当前hash进行拆分,这样热点key可以 
拆分为若干个新的key分布到不同redis节点上,从而减轻压力。
2)迁移热点key:以redis cluster为例,可以将热点key所在的slot单独迁移到
一个新的redis节点上,单词操作会增加运维成本。
3)本地缓存通知机制:可以将热点key放在业务端的本地缓存中,因为是在业务端
的本地内存中,处理能力要高出redis数十倍,但是当数据更新时,此种模式会
造成各个业务端和redis数据不一致,通常会使用发布订阅机制来解决类似的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值