《Redis深度历险》集群篇、拓展篇

集群1:李代桃僵--Sentinel

  • Redis主从方案如果主节点宕机,需要运维手工进行主从切换,效率低。
  • Redis Sentinel是一个高可用方案来抵抗节点故障,且可以主动进行从主切换。
  • Redis Sentinel集群负责监控主从节点的健康,一般由3-5个节点组成,保证高可用性。当主节点挂掉,会自动选择一个最优的从节点切换为主节点。客户端连接集群时,首先连接sentinel,通过sentinel查询主节点的地址再去连接主节点进行数据交互。
  • Redis主从采用异步复制,所以可能丢失部分未同步的消息。

集群2:分而治之--Codis

  • Codis使用Golang开发,是一个代理中间件,使用Redis协议。客户端向Codis发送指令时,Codis负责将指令转发到后面的Redis实例来执行,并将结果返回给客户端。
  • Codis是无状态的,可以启用多个Codis供客户端使用
  • 分片原理:将客户端的key进行crc32运算,然后将运算结果对1024取模,放入对应的槽位(1024个槽位slot)。每个槽位唯一映射多个Redis实例
  • 不同Codis为了同步槽位关系,使用分布式配置存储数据库来持久化槽位关系,可以是zk或者etcd

集群3:众志成城--Cluster

  • RedisCluster与Codis不同,是去中心化的。及群众每个节点负责整个集群的一部分数据,节点间通过一种特殊的二进制协议相互交互集群消息。
  • Redis Cluster将所有数据划分为16384的slots,每个节点负责一部分槽位。槽位的信息存储于每个节点。
  • Cluster默认会对key值使用crc32算法进行hash得到一个整数值,然后对16384进行取模来得到具体槽位
  • 如果请求了一个错误的节点,则节点会向客户端发送一个特殊的跳转指令携带目标操作的节点地址。
  • Redis Cluster可以为每个主节点设置若干个从节点,当主节点故障时,集群会自动将其中某个从节点提升为主节点。

拓展2:无所不知--Info指令

  • info指令可以显示Redis的运行状态。可分为九个部分:Server、Clients、Memory、Persistence、Stats、Replication、CPU、Cluster、KeySpace
  • info stats中的instantaneous_ops_per_sec可以查看每秒操作数
  • info clients可以查看正在连接的客户端信息
  • info clients中的rejected_connections可以查看因超出最大连接数限制而被拒绝的客户端连接次数。如果这个值很大,可能需要调整最大连接数设置
  • info memory可以看到redis内存分配总量和峰值以及脚本占用内存等
  • info replication中的repl_backlog_size就是复制积压缓冲区大小,严重影响主从复制的效率。设置过小容易引发复制死循环

拓展3:拾遗漏补--再谈分布式锁

  • 通过setnx完成的分布式锁在集群环境下不是绝对安全的。在主节点挂掉,从节点没有来得及同步该锁时,同一锁可能被获取两次。
  • redlock可以解决redis集群环境下的分布式锁问题,客户端向过半节点发送setnx指令,如果过半节点成功则加锁成功。释放时向所有节点发送del指令。

拓展4:朝生暮死--过期策略

  • redis过期删除策略采用定时策略和惰性策略。一方面将所有设置了过期时间的key放入一个独立的字典中,定时遍历字典来删除到期的key。一方面在客户端访问key的时候,redis会对这个key的过期时间进行检查,如果过期了就立即删除。
  • 定时扫描策略采用了贪心策略,1从过期字典中随机10个key,2删除这20个中已过期的,3如果过期的key超过1/4则重复1。为保证扫描不会出现循环过度,导致线程卡死,算法增加了扫描时间限制,默认不超过25ms
  • 从库对过期的处理是被动的。主库在key到期时会在aof日志中增加一条del指令,同步给所有的从库。

拓展5:优胜劣汰--LRU

  • Redis在实际内存超出maxmemory时,提供了几种可选策略:noeviction(不提供写服务,默认策略)、volatile-lru(淘汰设置了过期时间的最少使用的key)、volatile-ttl(淘汰ttl最小的key)、volatile-random(随机淘汰设置过期时间的key)、allkeys-lru(淘汰最近最少使用的key)、allkeys-random(随机淘汰key)
  • LRU算法可用双向链表+hash实现
  • Redis实现近似LRU算法,给每个key增加一个最后一次被访问的时间戳,当内存超出maxmemory时,随机采样5(可配置)样本,淘汰最旧的key,如果还是超出则继续采样淘汰。

拓展6:平波缓进--惰性删除

  • 当del一个大对象时,可能导致线程卡顿。所以Redis4.0版本引入了unlink指令,对del操作进行惰性处理,丢给后台线程来异步回收内存。
  • 同理flushdb和flushall后也可以加上async进行异步处理
  • 执行aof sync操作的线程也是一个独立的异步线程

拓展8:居安思危--保护redis

  • 在配置文件中通过rename-command将危险指令修改成特殊名称,避免人为误操作。
  • 指定监听的IP地址,增加密码访问限制
  • 如果redis在公网,可以使用SSL代理,redis官方推荐使用spiped
posted @ 2020-12-30 16:33  無花無酒鋤作田  阅读(103)  评论(0编辑  收藏  举报