redis复制配置
由于主服务器设置了密码,需要在从服务器中指定主服务器的密码 vim
/etc/redis/6379.conf
masterauth 123456
由于我的redis版本是5.0,所以同步的命令较以前的命令不太一样,但也兼容以前的同步命令
第一种方法:
配置文件修改 vim /etc/redis/6379.conf
replicaof masterip port #5.0版本支持的命令 或者 slaveof masterip port
第二种方法:
在redis客户端执行命令,在客户端执行的同步命令将在重启后失效
replicaof masterip port #5.0版本支持的命令 或者 slaveof masterip port
配置好之后,主从的masterID信息是一样的,这是主服务器的信息
这是从服务器的信息
主从同步后,从服务器将不能写入数据
当我们断开当前数据库的连接,与另一台主服务器建立主从同步后,masterid也发生变化,将重新进行完全同步
Redis哨兵
在redis主从模式下,一旦主服务器宕机,需要人工进行干预将某个从服务器转换为主服务器,还需要去监视redis的状态,费事费力,还会造成一段时间内服务不可用,对于某些应用场景,这种处理方法并不可取,redis在2.8版本开始提供了RedisSentinel工具,通过心跳检测的方式监视多个主服务器以及它们属下的所有从服务器,并在某个主服务器下线时自动对其实施故障转移,Sentinel将选择一个从服务器并将其提升为主服务器,其他剩余的从服务器实例将自动重新配置为使用新的主服务器。
哨兵功能
- 监控。Sentinel会不断检查主从节点是否按预期工作。
- 通知。Sentinel通过API通知客户端出现问题的节点
- 自动故障转移。当主服务器不能正常工作时,Sentinel可以进行故障转移操作,在该操作中将从服务器升级为主服务器,将其他从服务器改为复制新主服务器。
- 配置提供程序。客户端在初始化时,通过连接到Sentinels,获取当前主服务器的节点地址。
哨兵搭建
环境准备
192.168.179.131:6379 master 192.168.179.132:6379 slave 192.168.179.134:6379 slave 192.168.179.131:26379 sentinel 192.168.179.132:26379 sentinel 192.168.179.134:26379 sentinel
主从节点配置
#192.168.179.131 port 6379 daemonize yes logfile /var/log/redis_6379.log dbfilename dump.rdb #192.168.179.132 port 6379 daemonize yes logfile /var/log/redis_6379.log dbfilename dump.rdb replicaof 192.168.179.131 6379 #192.168.179.134 port 6379 daemonize yes logfile /var/log/redis_6379.log dbfilename dump.rdb replicaof 192.168.179.131 6379
测试主从复制是否配置成功
哨兵节点配置
三个哨兵节点相同配置,最后一句配置的意思是监控192.168.179.131这个主节点,节点名称是mymaster,并且至少需要两个哨兵节点同意才能判定主节点故障并进行自动迁移
port 26379 daemonize yes sentinel monitor mymaster 192.168.179.131 6379 2
启动哨兵节点
以下两条命令启动都可以,可以看到哨兵已经启动成功
./src/redis-sentinel sentinel.conf ./src/redis-server sentinel.conf --sentinel
故障转移测试
这里我将192.168.179.131的redis给关掉,查看从节点的复制信息,可以看到redis的主节点已经切换为192.168.179.132
将192.168.179.131上面的redis再次启动,查看节点状态已经变为从节点了
哨兵管理命令
- info sentinel:获取监控的所有主节点的基本信息
- sentinel masters:获取所有被监视主节点的信息
- sentinel master:获取指定主节点的详细信息
- sentinel slaves:获取指定主节点的从节点的详细信息
- sentinel sentinels:获取指定主节点的哨兵节点的详细信息
- sentinel get-master-addr-by-name mymaster:获取主节点的IP地址和端口
- sentinel is-master-down-by-addr:哨兵节点之间可以通过该命令询问主节点是否下线,从而对是否客观下线做出判断
- sentinel failover: 强制对主节点进行故障转移
- sentinel ckquorum: 检查可用的哨兵数量
- sentinel flushconfig: 强制写入配置文件
- sentinel remove:取消对指定主节点的监视
Redis集群模式
上面也说到,Redis主从模式中如果主服务器宕掉将无法进行写操作,即使哨兵模式提供了Redis的高可用,但面对数据量比较大的场景,Redis单点就不太能满足这个要求了 Redis 集群是一个分布式、容错的 Redis 实现, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集。Redis 集群是Redis的分布式实现,集群中不存在中心节点或者代理节点, 集群的其中一个主要设计目标是达到线性可扩展性。集群的容错功能是通过使用主节点和从节点两种角色的节点来实现的:主节点和从节点使用完全相同的服务器实现, 它们的功能也完全一样, 但从节点通常仅用于替换失效的主节点。如果不需要保证“先写入,后读取”操作的一致性, 那么可以使用从节点来执行只读查询。Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令。
Redis集群中节点的工作内容
- 保存键值对数据。
- 记录集群的状态,包括键到正确节点的映射。
- 自动发现其他节点,识别工作不正常的节点,并从节点中选举出新的主节点。
键分布模型
Redis 集群的键空间被分割为 16384 个槽(slot), 集群的最大节点数量也是 16384 个。当一个集群处于“稳定”状态时, 集群每个哈希槽都不会进行移动,当需要添加一个节点的时候,只需要将其他节点的某些哈希槽转移到新节点上,当需要删除一个节点的时候,就把此节点的哈希槽转移到其他节点上就可以了。一个主节点可以有任意多个从节点, 这些从节点用于在主节点发生网络断线或者节点失效时, 对主节点进行替换。
集群节点属性
每个节点在集群中都有一个独一无二的 ID , 该 ID 是一个十六进制表示的 160 位随机数, 在节点第一次启动时由 /dev/urandom 生成。节点会将它的 ID 保存到配置文件, 只要这个配置文件不被删除, 节点就会一直沿用这个 ID 。节点 ID 用于标识集群中的每个节点。一个节点可以改变它的 IP 和端口号, 而不改变节点 ID 。集群可以自动识别出 IP/端口号的变化, 并将这一信息通过 Gossip 协议广播给其他节点知道。以下是每个节点都有的关联信息, 并且节点会将这些信息发送给其他节点:
- 节点所使用的 IP 地址和 TCP 端口号。
- 节点的标志(flags)。
- 节点负责处理的哈希槽。
- 节点最近一次使用集群连接发送 PING 数据包(packet)的时间。
- 节点最近一次在回复中接收到 PONG 数据包的时间。
- 集群将该节点标记为下线的时间。
- 该节点的从节点数量。
- 如果该节点是从节点的话,那么它会记录主节点的节点 ID 。如果这是一个主节点的话,那么主节点 ID 这一栏的值为 0000000 。
以上信息的其中一部分可以通过向集群中的任意节点(主节点或者从节点都可以)发送 CLUSTER NODES 命令来获得。
集群数据一致性
Redis集群是无法保证数据的强一致性的
- 原因之一是因为Redis集群是异步复制的,当客户端向服务端的某个主节点写数据时,主服务器会先响应客户端,之后再把写操作请求发送给从节点,在这过程之中,如果主节点发生了宕机,而从节点还没有收到写操作的请求,那么这条数据将会永久丢失,当然可以通过强制数据库在回复客户端以前刷新数据到磁盘,但这样会导致性能降低。
- 还有一种情况是网络分区(network partition)带来的,当Redis集群出现网络分区时,客户端仍对处于小分区的主节点进行写操作,当达到集群的node timeout的时间限制后,处于大分区的那个从节点将会取代处于小分区的主节点称为新的主节点,而在node timeout这段时间里客户端向主节点写入的数据将会丢失
节点失效检测
- 当一个节点向另一个节点发送 PING 命令时, 目标节点未能在node timeout内返回 PING 命令的回复时, 那么发送命令的节点会将目标节点标记为 PFAIL (可能已失效)。
- 每次当节点对其他节点发送 PING 命令的时候, 它都会随机地广播三个它所知道的节点的信息, 这些信息里面的其中一项就是说明节点是否已经被标记为 PFAIL 或者 FAIL 。
- 如果节点已经将某个节点标记为 PFAIL , 并且集群中的大部分其他主节点也认为那个节点进入了失效状态, 那么节点会将那个失效节点的状态标记为 FAIL 。
- 一旦某个节点被标记为 FAIL , 关于这个节点已失效的信息就会被广播到整个集群, 所有接收到这条信息的节点都会将失效节点标记为 FAIL 。
集群搭建
编辑配置文件启动集群节点
每个集群实例都要开启,之后重启redis实例
cluster-enabled yes cluster-config-file nodes-6379.conf cluster-node-timeout 15000
连接集群节点并分配槽
./redis-cli --cluster create 192.168.179.131:6379 192.168.179.131:6380 192.168.179.134:6379 192.168.179.134:6380 192.168.179.132:6379 192.168.179.132:6380 --cluster-replicas 1
可以查看集群的节点信息,输入集群内任意节点地址即可
./redis-cli --cluster check 192.168.179.132:6379
集群验证
当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,当get数据的时候,也是通过这种方法去对应的节点上获取数据
./redis-cli -c -h 192.168.179.132 -p 6380 192.168.179.132:6380> set key 1 -> Redirected to slot [12539] located at 192.168.179.132:6379 OK ./redis-cli -c -h 192.168.179.134 -p 6379 192.168.179.134:6379> get key -> Redirected to slot [12539] located at 192.168.179.132:6379 "1"