复制集群
- 在slave服务器上通过slave of + ip的形式去监听master节点。
- slave是通过SYNC和PSYNC命令去实现的数据同步
- SYNC是旧版 PSYNC是新版,区别在于PSYNC可以实现部分同步。
- master在收到命令后会通过BGSAVE生成RDB文件,并用一个缓冲区缓存现在开始接受到的命令。
- 完成BGSAVE之后发送RDB文件到slave,然后将缓冲区文件发送到到slave。
- PSYNC的通过记录双方服务器的offset来实现部分重新同步。
- 从服务器通过REPLCONFIG ACK replication_offset进行每秒的发送进行心跳检测。
哨兵集群(sentinel)
- sentinel 是一个特殊的redis服务器
- 根据配置信息,对指定的redis服务器创建命令连接和订阅链接——sentinel:hello
- 一般情况下每10s发送INFO到redis服务器,当redis服务器故障或者在进行转移的时候每秒1次
- 监听redis的sentinel每2s向订阅的频道——sentinel:hello发送自己包含的信息
- 收到其他的sentinel发送的信息的时候,会为他创建命令连接和数据结构
- sentinel 每s向所有服务器发送ping 未收到pong信息会判断主观下线
- 当sentinel判断主观下线之后,会向其他sentinel收集信息,收集到足够的票就进行故障转移
- sentinel 进行故障转移之前会选出一个master sentinel,master sentinel来发送故障转移的命令
- 故障转移 就是从服务器中选一个主服务器,其他同步新主服务器,将旧的主服务器变成从服务器。
集群模式
- redis集群是分布式数据库方案,通过分片的方式进行数据共享,并提供复制和故障转移的功能。
- cluster meet 和指定node进行握手创建集群。
- 对16384个slot进行指定节点分配之后,集群才会进入到上线状态。
- 如果发送到错误的node,会返回MOVED指令重定向到正确的node。
- cluster keyslot可以确定键属于哪个slot。
- slot和node的关系通过跳表来保存。
- 新增node节点,集群会进行重新分配,由redis-trib模块进行自动分配
- 集群中,分为master 和 slave节点,slave复制master节点,master下线的时候会代替master成为新的主节点。
- cluster replicate 设置从节点。 slave of 开始复制。
- 故障监测机制:node之间通过互相ping来确认是否存活,通过互相发送消息确认某个节点的状态。
- 半数以上疑似下线就进行故障转移。
- 和sentinel一样 cluster模式也是通过raft算法进行领头选举。
- redis 在进行选举的时候会出现不可用的情况。
一些实战的TIPS
生产进行redis访问的方式:
- 轮训(主从,sentinel)
- hash访问,针对key进行访问(主从,sentinel)
- 一致性hash(集群模式)
- 针对不同的集群模式,会有不同的访问方式。但是在不同的场景下面会有更合适的方式。
- 主从和sentinel的数据存储形式是不同的节点上面都有全量的数据。
- 集群模式的redis有点在于可以根据crc16算法存储更多的数据。但是会出现数据偏移、访问量偏移的情况。
- 对于在秒杀类似的场景下,可能会存在两种模式互为备份的情况,sentinel比集群更能扛住类似的场景,因为在秒杀情况下,商品的key会出现明显的访问偏移现象。
如何处理集群模式下面访问偏移和数据偏移的情况(大key 热key)
- 大key会导致内存升高,如果进行主从同步,会占用带宽,并且增加主从之间的延迟,对大key的读写也会导致机器卡顿。
- 热key直接会导致,单台机器的cpu飙高,热key失效会导致mysql压力暴增,大量的访问可能导致incr等命令无法保证原子性。
- 临时处理方式:加内存,调整带宽,但是对cpu飙高没有什么好的临时解决方案。
-
解决方案:大key: 拆分、删除
-
热key:key -》 key1 key2 key3 这样去分散 ; 使用读写分离架构