概述
终于迎来了Redis系列的尾声,本文针对Redis常遇到的热Key,大Key,并发竞争解决方案进行介绍。
热Key
什么是热key?当一个key的访问量明显大于其他key的时候,他就可以被称为热key。
热Key带来的问题
- 热key占用大量的CPU资源,使其效率降低,影响其他业务
- 热key所在的节点访问量大,容易造成物理网卡瓶颈
- 超出redis承受能力后,容易造成击穿,这时大量访问打到数据库上造成数据库瓶颈
解决办法:
- 对热key根据一定的规则,增加后缀,让它变成好几个key,分散到不同的节点中,减少一个节点的压力,他也有一定的问题,比如数据的一致性问题。更新一个key变成更新多个,业务代码也要修改,增加工作量。
- 对为热key单独做集群,他们会有独立的热点key 做redis集群,和全量redis隔离。
- 本地缓存,客户端本地对热key进行收集做缓存,比如浏览器的localstorage,安卓ios自己的数据库,然后设置一个比较短的过期时间,比如1分钟,用来解决更新问题。
大key
什么是大Key?(Redis客户端提供了bigkeys命令来查找大key)
- string中的数据大于10k
- list set zset 中的数据个数大于5000个
删除大key时会造成阻塞,怎么删除大key?
- 根据实际业务时间,在低访问时间段删除
- list set zset hash可以分批次删除
- 使用unlink代替del命令,unlink是放入异步的线程中不会阻塞主线程的命令
并发竞争
多个客户端同时并发写一个key,本来应该先到的操作,因为某些原因后到了,导致数据出错。
解决方案:
1.利用分布式锁,确保同一时间只有一个系统再操作某一个Redis Key ,其他系统不能操作
2.利用时间戳,当时间戳最新时修改Redis key ,当时间戳比较旧时,忽略操作。
ZooKeeper
- ZooKeeper主要服务于分布式系统,可以用它来做,统一配置管理,统一命名服务,分布式锁,集群管理。
- ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper 节点
ZooKeeper 可以看成是树状结构,它的节点是znode
- 持久节点,默认节点类型,创建节点的客户端与ZooKeeper断开链接以后,节点仍然存在
- 持久节点顺序节点,再创建节点时,ZooKeeper会根据节点的创建时间,对节点进行编号
- 临时节点,创建节点的客户端与ZooKeeper断开链接以后,节点就会被删除
- 临时顺序节点,创建节点时,ZooKeeper会根据节点创建时间,对节点进行编号,创建节点的客户端与ZooKeeper断开链接以后,节点就会被删除。
惊群效应
惊群效应就是,给一堆睡觉的鸟群(羊群、牛群都行,随你高兴)中,扔一颗石子,结果就是会惊醒这一群的鸟,这就是所谓的惊群效应。
对应到并发编程中,当多个线程阻塞到相同资源上(比如锁)时,当这个资源ready后,资源就绪的信号唤醒了所有阻塞到这个资源上的所有线程。
在并发编程中,当有多个线程/进程争抢同一资源,因资源不足而被阻塞的时,当阻塞事件解除后,如果唤醒了所有阻塞在该事件上的所有线程/进程,那就触发了惊群效应。
ZooKeeper的解决
ZooKeeper利用临时顺序节点解决高并发中的惊群效应,步骤如下:
1.创建临时的顺序节点
2.判断是不是最小节点
3.是最小的,获得锁,否则监听上面的节点
4.释放锁后,后面的监听节点处理
这个朋友写的非常好,实现的过程我就不在这里叙述了[PHP zookeeper实现分布式锁,点击跳转]