主从复制
master-slave(replication)
从节点上只能读数据,不能写入数据,只能在主节点写入数据。主节点的数据会自动同步到从节点。
复制原理:
- 从节点第一次加入后和主节点建立连接
- 建立连接后主节点通过bgsave生成RDB文件,再将文件发送到从节点(假如超时则会重发)
- 新来的指令主节点保存在缓冲区中,然后再发送给从节点
- 从节点基于rdb做一次数据载入
- 后续通过命令传播到从节点保持数据一致
- 假如从节点断开一段时间重新加入,会丢失断开时间的数据,会基于偏移量增量复制。
解决的问题:
- 数据备份
- 读写分离(不是很有必要,redis本身的性能已经够高了)
存在的问题:
主从会有延迟。
主挂了,主从不会自动切换,需要手动重启主节点。
高可用(Sentinel机制)
sentinel是特殊的redis-server节点,一般会建造多个sentinel节点互相监控,sentinel之间地位平等,没有主从之分。
sentinel会监控真正redis-server节点:
- 当主节点超时未与sentinel节点连接时,会先将主节点标记下线(主观下线)
- 该sentinel节点会询问其他的节点,假如超过半数(奇数个sentinel)认为主节点下线,此时为真正下线(客观下线)
- 此时需要failover(故障转移):奇数个哨兵会通过Raft算法选举leader,leader的sentinel节点会发送两条指令让某一个从节点成为主节点
- 旧的主节点重启后会变成新的主节点的从节点
解决的问题:
- 高可用
存在的问题:
- 切换过程中可能会出现短暂数据丢失
- 没有解决水平扩容问题
redis客户端会从sentinel拿到主节点的地址,再去根据地址进行真正地连接及操作。
Raft算法(分布式一致性算法的一种)
1、先到先得
2、少数服从多数
选举的超时时间是一个随机数,最先超时的会变成一个candidate,然后发起投票,并且给自己投一票,假如超过半数投票自己(平票则需要再投一次),自己成为了leader以后,会定期给从节点发送心跳包,重置从节点的选举超时时间。
可拓展
为了解决水平扩容的问题,我们可以在客户端做分片,也可以用代理分片服务,另外Redis本身提供Cluter模式,进行水平扩容
客户端:jedis
实现了分片到不同redis服务的功能,代码的拓展性有限,不能实现平滑扩容
代理proxy
Twenproxy,Codis:需要考虑proxy单点问题;不能实现平滑扩容
服务端实现:Redis-Cluster(重点)
架构:多主多从
数据分布:CRC16算法对16384取模,按哈希槽分配(一共有16384个槽),将一些槽分配到对应的节点上。
HashTag:在key中加{xxx},会用xxx取模分配槽,假如xxx一样则会分配在同一个节点上。
主节点挂了:
- slave发现master宕机,广播通知
- 其他master发送ACK
- slave变成新的master,广播通知
客户端连接到任意一个节点都可以实现一样的效果,去中心化。