Redis要点总结三

大纲

一.Redis的应用和解决方案

二.Redis在用户数据里的应用

三.Redis在列表数据里的应用

四.Redis在购物车里的应用

五.Redis在库存里的应用

六.Redis相关解决方案

一.Redis的应用和解决方案

1.Redis的性能总结

2.Redis缓存的相关问题

3.数据库和缓存的一致性问题

1.Redis的性能总结

首先需要判断出Redis是否真的慢。可以通过基准性能测试得出Redis的平均响应延迟和最大响应延迟。如果当前的响应延迟大于基准性能测试结果的两倍以上则可认为Redis慢了。如果真的发现Redis慢了,则可以通过以下角度进行分析判断。

(1)CPU角度之使用复杂度过高的命令

原因:复杂度高的命令,执行时耗费CPU,一次返回客户端数据过多,网络传输耗时,阻塞后面请求。解决:不使用复杂度高的命令、集合中的聚合查询放在客户端做、一次查询数据尽量少、全量数据分批查、不要为了追求低内存而过度放宽压缩列表(O(N)~O(N^2))的使用条件。

(2)CPU角度之绑定CPU

原因:子进程继承父进程CPU使用偏好,子进程数据持久化期间,与父进程发生CPU争抢。解决:主进程、后台子线程、后台RDB进程、AOF重写进程,分别绑定固定的CPU核心。

(3)内存角度之操作bigkey

现象:slowlog出现set/del等简单命令,实例中存储了bigkey。原因:写入bigkey分配内存耗时久,删除bigkey释放内存耗时久。解决:不存储bigkey、使用unlink代替del可以把释放内存的操作交给后台线程执行、开启lazy-free机制,这样执行bigkey的del操作时也会把释放内存的操作交给后台线程。

(4)内存角度之集中过期

现象:整点发生延迟、间隔固定时间发生延迟,info中expired_keys短期突增。原因:清理过期key在主线程执行、key集中过期增加了清理负担,过期bigkey延迟更明显。解决:排查业务时是否使用expired/pexpired命令,过期增加一个随机时间、降低集中过期的压力,开启lazy-free机制。运维监控info中expired_keys指标,短期内突增及时报警。

(5)内存角度之实例内存达到上限

现象:实例内存超过mxmemory之后写请求变慢,info中evicted_keys短期突增。原因:淘汰数据在主线程中执行、LRU淘汰数据也会消耗时间、写OPS越大延迟越明显、淘汰bigkey延迟越明显。解决:避免存储bigkey,视业务更换淘汰策略(随机比LRU快),拆分实例分摊淘汰数据的压力,开启lazy-free机制,运维监控info中evicted_keys指标,短期内突增及时报警。

(6)内存角度之fork操作耗时严重

现象:延迟只发生在这3个时候:后台定时RDB、后台AOF重写、主从全量同步。原因:使用fork调用会创建子进程,fork拷贝内存页表耗费时间,完成前会阻塞主进程,虚拟机执行耗时更久。解决:实例内存10GB以下,优化RDB备份策略如低峰期执行RDB,视情况关闭AOF和AOF重写,Redis不部署在虚拟机上,调大repl-backlog-size降低全量同步的概率。

(7)内存角度之开启内存大页

现象:子进程持久化数据期间,主进程写请求变慢(写时复制)。原因:内存大页会以2MB为单位向操作系统申请内存,耗时久。内存大页机制是为了降低申请内存次数,Redis对性能和延迟敏感,希望申请内存的时候耗时短。解决:关闭内存大页。

(8)内存角度之使用swap

现象:所有请求变慢,延迟达到上百毫秒甚至秒级。原因:内存数据更换到磁盘,访问磁盘延迟高。解决:增加内存,重启实例释放swap,让实例重新使用内存,并进行swap监控报警。

(9)内存角度之碎片整理

现象:延迟只发生在自动碎片整理期间。原因:碎片整理在主线程执行。解决:关闭碎片自动整理,合理配置碎片整理参数。

(10)内存角度之从库加载大的RDB文件

主库实例大小控制在2~4GB,以免主从复制时,从库因加载大的RDB文件而阻塞。

(11)磁盘角度

现象:磁盘IO负载高,AOF重写期间延迟更明显。原因:开启了AOF,AOF刷盘always策略加重主线程写负担。AOF刷盘everysec策略时,如果磁盘负载高,write和fsync系统调用会发生阻塞。解决:升级SSD磁盘,不和高磁盘负载的服务部署在一起(如存储服务、消息队列服务),重写AOF时不做fsync操作,高流量写入场景不开启AOF。

(12)网络角度

现象:稳定运行的实例,突然开始变慢,现象持续。原因:网络层存在数据传输延迟、丢包。解决:若是正常的业务大流量访问,需及时扩容或迁移实例,否则排查流量大的实例。

2.Redis缓存的相关问题

(1)缓存穿透问题

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求。解决方法如下:

方法一:缓存空对象。适用于数据频繁变化,实时性要求高的场景。缓存层要存更多空对象的键,这些键一般设置一个较短的过期时间。如果存储层添加了空对象的数据,为避免缓存层和存储层出现不一致,需要主动清除空对象。

方法二:布隆过滤器拦截。适用于数据相对固定,实时性要求低的场景。虽然代码维护比较复杂,但是缓存空间占用比较少。

三.请求入口检查合法性

(2)缓存击穿问题

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期)。这时由于并发用户特别多,同时读缓存没读到数据,所以需要同时去数据库去取数据。从而引起数据库压力瞬间增大,造成过大压力。

缓存击穿的解决方法:问题的关键是产生了并发,因此需要限制并发访问数据库,可考虑加锁。由于Redis是单进程单实例,可利用setnx()的特性来实现简单的分布式锁。

(3)缓存雪崩问题

缓存雪崩是指缓存中数据大批量到过期时间,而查询量巨大,引起数据库压力过大甚至宕机。和缓存击穿不同的是,缓存击穿是并发查同一条数据,缓存雪崩是不同数据都过期,很多数据都查不到而查数据库。缓存雪崩的解决方法如下:

方法一:过期时间加上随机数,避免同时过期

方法二:服务降级、服务熔断、请求限流

方法三:主从集群保护缓存高可用

方法四:提前演练

(4)缓存无底洞问题

缓存无底洞问题是指客户端一次批量操作涉及多次网络,节点越多耗时越大,由于网络连接数变多,对节点性能有影响。所以缓存无底洞问题其实就是如何在更多节点的分布式缓存中进行高效的批量操作。缓存无底洞的解决方法如下:

方法一:串行命令,简单、少量的key,性能可以满足,但大量的key请求会导致延迟严重

方法二:串行IO,简单、少量节点,性能可以满足,但大量的节点也会导致延迟严重

方法三:并行IO,复杂,多线程维护成本高

方法四:hash_tag,性能最高、维护成本高、数据易倾斜

(5)布隆过滤器介绍

如何判断给定的元素是否存在给定的集合中?如果该集合是已经排序的,那么可以用二分查找来实现。但是,如果集合的数据量庞大到一定程度ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值