从redis2.8版本之后支持"断点续传"机制:在主从复制过程中 ,网络断开,那么可以接着上次复制的地方继续复制,而不是从头开始重新复制一份。主库会在内存中常建一个backlog,主库和从库都会保存一个replica offset,offset就是保存在backlog中的,backlog是一个等待队列,当有大量请求需要redis处理时,redis有可能处理不过来,所以用backlog来缓存等待的请求,backlog的数量决定了可以缓存的队列数。当主库和从库发生网络故障的时候,从库会让主库从上次offset的点继续复制,但是如果没有找到offset的话,那么会执行全量复制。
实验部署
本实验以三个实例为环镜
mkdir /data/redisCluster/638{0,1}/{conf,log,pid} -p
cat >/data/redisCluster/638{0,1}/conf<<EOF
daemonize yes
port 6379
logfile /data/redisCluster/6379/log/redis.log
dir /data/redisCluster/6379
dbfilename dump.rdb
bind 192.168.8.19 127.0.0.1
pidfile /data/redisCluster/6379/pid/redis.pid
loglevel notice
masterauth 123
requirepass 123
EOF
#从库执行
redis-cli -a 123 -p 6380 slaveof 主库IP 主库PORT
#查看状态
redis-cli -a 123 -p 6379 info replication
注意:
:启用了主从复制master必须开启持久化,否则master宕机、重启是没有本地数据可以恢复的,然后就会直接认为数据是空的同步到slave上导致slave的数据全部清空。
redis的哨兵系统由于管理多个redis服务器(实例),该系统执行以下三个任务:
监控(Monitoring)
:sentinel会不断地检查主服务器和从服务器是否运作正常。通知(Notification)
:当被监控的某个服务器出现问题时,sentinel可以通过API向管理员或者其它应用程序发送通知。自动故障转移(Automatic failover)
:当一个主服务器不能正常工作时,sentinel会开始一次自动故障迁移操作,它会将失效主节点的其中一个节点升级为主服务器,并让失效节点的其它从节点改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新服务器的地址,使得集群可以使用新主服务器代替失效的服务器。sentinel是一个分布式系统,可以在一个架构中运行多个sentinel进程,这些进程使用流言协议(gossip protocols) 来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols) 来决定是否执行自动故障转移以及选择哪个从服务器代替失效服务器。
配置sentinel:(每台物理服务器配置sentinel)
vim /data/26380/sentinel.conf
port 26380
dir "/data/26380"
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123
# 对于sentinel程序启动
redis-sentinel /path/to/sentinel.conf
#对于server程序启动
redis-server /path/to/sentinel.conf --sentinel
集群是一个可以在多个redis节点之间进行数据共享的设施,它不仅支持那些需要同时处理多个键的redis命令,因为执行这些命令需要在多个redis节点之间移动数据,并且在高负载的情况下,这些命令会降低redis集群的性能。redis集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。
redis集群提供了以下两个好处:
redis集群使用数据分片(shardinng)而非一致性哈希(consistency hashing)来实现:一个redis集群包含16384个哈希槽(hash slot),数据库中的每个键都属于这个16384个哈希槽的其中一个,集群使用公式CRC16(key)%16384来计算key属于哪个槽,其中CRC16(key)语句用于计算key的CRC16校验和。
集群中的每个节点负责处理一部分哈希槽。举个例子,一个集群中有三个哈希槽,其中:
这种将哈希槽分不到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。比如说:
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞,所以无论是添加节点还是移除节已存在的节点,又或者改变某个节点包含的哈希槽数量,都不会造成集群下线。
yum install -y ruby rubygems
gem source -a https://mirrors.aliyun.com/rubygems/
gem source --remove https://rubygems.org/
gem sources -l
gem install redis -v x.x.x
vim /data/700{1..8}/conf/redis.conf
#
daemonize yes
port 7001
pidfile /data/7001/redis.pid
loglevel notice
logfile "/data/7001/redis.log"
dbfilename dump.rdb
dir /data/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
#
启动:
redis-server /data/700{1..6}/conf/redis.conf
创建集群:(123为master节点,456为slave节点,一一对应)
redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
添加一个master节点
:redis-trib.rb add-node 127.0.0.1:7007 127.0.0.1:7001 //把7007加入到7001的集群当中
上图可以看到添加完成后是不起作用的,因为没分配哈希槽。接下来对master节点重新分片:
redis-trib.rb reshard 127.0.0.1:7001
添加一个slave节点
:redis-trib.rb add-node --slave --master-id 24abb63c8840dd4b26b0bdb06645e9c97da814f0 127.0.0.1:7008 127.0.0.1:7001
删除节点
:redis-trib.rb reshard 127.0.0.1:7001
redis-trib.rb del-node 127.0.0.1:7007 7467e9b12ec7c4dcc08c916a0bc8666e4470ecaf