《Redis开发与运维》读书笔记三

目录

集群运维

集群倾斜

集群读写分离

手动故障转移

数据迁移

缓存更新策略

穿透优化

无底洞优化

雪崩优化

热点key优化

Linux配置优化

flushall/flushdb误操作

安全的redis

处理bigkey

寻找热点key


之前这本书看了大概二分之一,后面就没有再坚持下去,这次在我球管理redis-manager的机会,重新捡起这本书,深度的阅读,以防止自己记忆碎片,整理文档。Redis开发与运维这本书的内容太多,网上没有找到检索,记录下来自己认为重要的信息片段,供检所使用。

书籍地址:https://github.com/singgel/Study-Floder

集群运维

集群完整性:

默认当16384中任何一个槽没有指派时集群不可用

持有槽的主节点下线时,从故障发现到自动切换转移,整个集群状态为不可用,大多数场景无法接受将cluster-require-full-coverage设置为no

带宽消耗:

消息发送频率:cluster-node-timeout/2

消息数据量:slots槽数组(2kb)+1/10集群的状态数据

节点部署规模:部署的节点要划分均匀

Pub/Sub广播问题:

集群模式下的public广播问题,频繁的应用Pub/Sub避免在大量节点的集群使用,建议使用sentinel结构专门用于Pub/Sub

集群倾斜

数据倾斜:

节点和槽不均匀 使用redis-trib.rb rebalance

不同槽对应键数据量差异过大 大量使用hash_tag导致,

使用cluster countkeysinslot {slot}获取槽对应键的数量发现最多建的槽,

再通过cluster getkeysinslot {slot} {count}迭代出所有键找出过度使用的hash_tag

集合对象包含大量元素 使用redis-cli --bigkey识别,找出后根据业务场景拆分(过大会造成migrate失败)

内存相关配置不一致 例如hash-max-ziplist-value、set-max-intset-entitres等压缩数据结构配置

请求倾斜:

热点key的场景,简单的getset不会造成负载不均匀,一般是hgetall、smembers等搞复杂度算法命令

1.大集合键拆分,hmget代替hgetall

2.不使用热key做hash_tag

3.一致性要求不高的,客户端使用本地缓存减少热键调用

集群读写分离

只读连接:

集群模式下从节点不接受任何读写请求,被转发到对应的master上

分担读压力,使用readonly打开只读状态

只读流程:如果槽属于正在复制的主节点,直接执行命令,负责重定向

readonly命令时连接级别,每次新建命令都要

读写分离:

复制延迟,读取过期数据,从节点故障

集群提供cluster slave {nodeId}获取从节点

不提倡使用

手动故障转移

从节点执行cluster failover执行切换流程

应用于:

主节点迁移(新旧机器迁移)

强制故障转移(主从节点同时故障)

从节点与主节点复制断线时间超过cluster-slave-validity-factor*cluster-node-timeout+repl-ping-slave-period

网络不稳定,无法在cluster-node-timeout*2时间内完成发现转移

集群超过一半以上主节点同时故障

cluster failover提供

force:不再请求master的偏移量,直接替换并广播

takeover:用于超一半主节点故障,会导致配置纪元冲突,会采用配置纪元大的(纪元冲突采用nodeId大的)

数据迁移

和雪球当前方案一样redis-migrate-tool

缓存更新策略

1.LRU/LFU/FIFO

maxmemory-policy缓存使用量超过预设最大值

一致性最差,由算法决定

2.超时剔除

给缓存数据添加过期时间

一致性由expire决定

3.主动更新

利用消息系统或者其他方式通知更新缓存

一致性最高,搭配expire更好

4.最佳实践

低一致性配置最大内存和淘汰策略

高一致性超时剔除+主动更新

缓存粒度:

穿透优化

业务代码或者数据问题,恶意攻击、爬虫导致

1.缓存空值

优点:保护后端数据源 数据压力

缺点:意味着更多的空间(如果是攻击,问题就严重了)、缓存和存储有一个时间窗口不一致

2.布隆过滤器拦截

在访问缓存和存储前,将存在的key用布隆过滤器提前保存起来做第一层拦截

https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter

无底洞优化

增加节点,性能不增加反而降低

命令优化,例如优化SQL语句

减少网络通信次数

降低接入成本(长连接、连接池、NIO)

雪崩优化

1.保证缓存层服务的高可用性

2.依赖隔离组件为后端限流并降级https://github.com/netflix/hystrix

3.故障演练,上线前就关闭缓存压测一下

热点key优化

问题:

热点key(例如热门的新闻事件)并发量贼大

重建缓存不能短时间内完成(复杂计算,sql、io、多依赖等)

在缓存失效期间大量线程重建缓存造成后端压力骤增

解决:

减少重建次数、数据尽可能一致、较少的潜在危险

互斥锁:等上一个把缓存整出来、先看看有没有

永不过期:缓存方面、功能方面(逻辑过期时间)

Linux配置优化

1.vm.overcommit_memory

设置为1(cat /proc/sys/vm/overcommit_memory),不然log会有提示

最佳实践

Redis合理设置maxmemory保证机器有20%~30%的空闲

集中化管理AOF和RDB的bgsave

设置vm.overcommit_memory=1,防止极端情况下fork失败

2.swappiness

百分比会决定操作系统使用swap的倾向程度,越大倾向越高(默认60,cat /proc/sys/vm/swappiness)

free -m、vmstat 1、cat /proc/{pid}/smaps |grep Swap

Linux>3.5 vm.swapniess=1 : vm.swapniess=0

3.THP

Linux2.6.38之后默认开启,内存页从4KB变为2MB,建议禁用(echo never > /sys/kernel/mm/transparent_hugepage/enabled)

4.OOM killer

会在可用内存不足时杀掉用户进程,根据每个进程的权值(越高越被杀,cat /proc/{pid}/oom_score)

这个值受(cat /proc/{pid}/oom_adj)控制,当oom_adj为最小值时该进程不会被杀掉

5.NTP

网络时间协议,保证不同机器时钟一致性

6.ulimit

查看和设置当前用户进程的资源数,open files是单个用户打开的最大文件个数

maxclient+32是redis的进程数(ulimit -Sn {max-open-files})

7.TCP backlog

在linux系统内核中维护了两个队列:syns queue和accept queue,https://www.jianshu.com/p/e6f2036621f4

redis默认值511(cat /proc/sys/net/core/somaxconn)

这个值不能小于redis的默认值,这个是Linux半连接请求(syns queue

flushall/flushdb误操作

被误flush后,根据缓存还是存储策略不同

缓存:就是个简单的缓存穿透

存储:影响巨大

AOF:

auto-aof-rewrite-percentage、auto-aof-rewrite-min-size看看aof是不是重写了(调大这个参数),拒绝手动bgrewriteaof

删除掉flush这个命令,用redis-check-aof修复AOF文件

RDB:

save {time} {times}配置文件,防止手动bgsave

flush涉及的key较多,RDB会被清除,取决于RDB是什么时候备份的

最佳实践:

使用shell脚本

安全的redis

伪装危险命令:keys、flushall/flushdb、save、debug、config、shutdown

AOF和RDB不要,不然redis无法重启

主从节点要配置一致

使用防火墙限制ip port只开放80

bind绑定的是网卡,可以设置多个

定期备份数据

不使用默认端口

不使用root作为管理员

处理bigkey

字符串一般超过10kb都是大key了,和ops相关

集合类型一般是元素个数过多

危害:

内存空间不均匀

超时阻塞

网络拥塞

处理:

redis-cli --bigkeys统计(debug object key可以查看key的字节数)

被动收集:抛异常时打印所有的key

主动检测:scan+debug object(推荐,键过多可以使用pipeline,从节点上执行,避免阻塞)

删除:

string直接del

集合类型先scan,再pipeline逐个del filed

寻找热点key

1.客户端,每次调用redis命令时使用字典记录

缺点:

无法预知keygeshu,存在内存泄漏

对代码侵入,多个语言维护困难

只能了解客户端热点key,无法规模化运维

2.代理端(Twemproxy、Codis)

3.redis服务端

使用monitor命令

Facebook的redis-faina(尽可能在本机执行,存在单点,影响线上性能问题)

4.机器

对TCP抓包,采用ELK体系下的packetbeat插件(也可以对MySQL检测)

处理热点key:

拆分复杂数据结构

迁移热点key,将热点slot单独迁到一个节点上

本地缓存加通知机制(发布订阅解决不一致问题)

猜你喜欢

转载自blog.csdn.net/singgel/article/details/94408390