rhel6.5-redis的集群、主从复制,高可用

一.redis

    redis是一个开源的,遵守BSD协议,是一个高性能的key-value数据库,内存存储的数据结构服务器,可用作数据路,高速缓存和消息队列的代理。支持字符串,哈希表,列表,集合,有序集合,位图,hyperloglogs等数据类型。内置复制,lua脚本,LRU收回,事务以及不同级别磁盘持续化功能,同时通过redis sentinel提供了高可用,通过redis cluster提供了自动分区。Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,Redis支持数据的备份,即master-slave模式的数据备份。中文官网(http://www.redis.net.cn)

redis的持久化:

       AFO:以日志的形式俩记录每个写操作,将 redis 执行过的所有写指令记录下来(读操作不记录)。只许追加文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,redis重启的话就根据日志文件的内容将写指令从前到后执行一次一完成数据恢复工作。使用 AOF 持久化会让 Redis 变得非常耐久:你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据

        Rdb:在指定的时间间隔内将内存中的数据集快照写入磁盘,它恢复时就是将快照文件直接读到内存里。
Redis 会单独的创建(fork) 一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,再用这个临时文件替换上次持久化的文件。整个过程主进程是不进行任何 IO 操作,这就确保了极高的性能,如果需要进行大规模的数据恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方法要比 AOF 方式更加的高效。RDB 的缺点是最后一次持久化后的数据可能丢失。(因为是隔一段时间才把数据集写入磁盘,当突然redis被crash,本次的数据丢失)

二.redis的主从复制

主从复制的原理:

全量复制:

Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。

1)从服务器连接主服务器,发送SYNC命令; 
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写名令; 
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令; 
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照; 
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令; 
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
增量复制:
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。 
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
 redis主从复制策略:
主从刚刚连接的时候,进行全量同步;全量同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

redis的复制机制:对于slave端来说,主从复制主要经历四个阶段:(1)与master建立连接;(2)向master发起同步请求(SYNC);(3)接受master发来的RDB数据;(3)载入RDB文件

1.redis的安装(安装包:redis-4.0.8.tar.gz)

(1)解压tar包,cd  src/进行编译


(2)cd utils/进行安装,会生成配置文件,端口信息等

安装有报错(在README.md这个文件中有提示安装的方法以及遇到的报错解决方案)


(3)redis的基本信息

默认端口=6379

配置文件:/etc/redis/redis_6379.conf

2.主从复制的部署(一主一从)

server1_backup:172.25.78.1   server3_master:172.25.78.3

(1)修改配置文件

vim  /etc/redis/redis_6379.conf(主从的配置文件都把bind这行注释掉,监听所有IP)

(2)在从机指定主机的IP和端口

slaveof   IP   port     ##做一主多从就在每台从机的配置文件中加上这行参数即可

(3)测试

主机设定key-value

从机能获取到value值

从机默认不可以写,以免破坏数据的一致性

三.redis的高可用(redis-sentinel实现高可用)

server3_master:172.25.78.3  server1_backup:172.25.78.1  server2_backup:172.25.78.2

redis-sentinel原理:

(1)sentinel集群通过给定的配置文件发现master,启动时会监控master。通过向master发送info信息获得该服务器下面的所有从服务器。
(2)sentinel集群通过命令连接向被监视的主从服务器发送hello信息(每秒一次),该信息包括sentinel本身的ip、端口、id等内容,以此来向其他sentinel宣告自己的存在。
(3)sentinel集群通过订阅连接接收其他sentinel发送的hello信息,以此来发现监视同一个主服务器的其他sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收hello信息的中介,sentinel之间不会创建订阅连接。
(4)sentinel集群使用ping命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。
(5)当failover主备切换被触发后,failover并不会马上进行,还需要sentinel中的大多数sentinel授权后才可以进行failover,即进行failover的sentinel会去获得指定的sentinel授权,成功后进入ODOWN状态。(先进行主观下线,sentinel判决超过半数以上认为master已经down掉,进行客观下线,进行主从切换)
(6)sentinel向选为master的slave发送SLAVEOF NO ONE命令(把此slave推选为新的master),选择slave的条件是sentinel首先会根据slaves的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从master接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程ID较小的。
(7)sentinel被授权后,它将会获得宕掉的master的一份最新配置版本号(config-epoch),当failover执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它sentinel,其它的sentinel则更新对应master的配置。

1.redis一主两从的部署
在从机的配置文件中加上:
slaveof  172.25.78.3  6379
2.redis自带sentinel(哨兵)脚本实现高可用

(1)在master配置redis-sentinel的配置文件,并且把redis-sentinel的配置文件发送到backup


(2)vim /etc/redis/sentinel.conf
sentinel端口是26379
protected-mode no     ##关闭保护模式,可以进行远程连接

daemonize yes            ##打开守护进程


sentinel monitor mymaster 172.25.78.3 6379 2     ##监控的名称是mymaster, 2表示判决,三台主机只有半数以上同意方可切换


sentinel dsentinel down-after-milliseconds mymaster 10000   ##10秒收不到master的数据包,就认为master已经down


sentinel parallel-syncs mymaster 1             ##仅有一台从机备用切换


sentinel  failover-timeout mymaster  180000   ##主从切换不超过3分钟


3.开启sentinel(redis-sentinel     /etc/redis/sentinel.conf,需要指定配置文件)

4.测试

(1)查看redis集群的复制情况

redis-cli   ##进入master(有两台从机分别为172.25.78.1、172.25.78.2,都已经上线)

(2)手动down掉master

可见172.25.78.1切换为master,172.25.78.2从机开始向新的master同步

172.25.78.2的sentinel的配置文件的master也重新指定到172.25.78.1

成功进行了主从切换

(3)手动让旧的master重新上线做从机(在切换的时候会有一点延迟,当重新让旧的master上线做从机的时候,并没有瞬间上线)

在新的master上查看集群信息172.25.78.3重新添加进来做从机

同时在每个主机的sentinel的配置文件的末尾也会追加进行主从切换时的集群信息以及sentinel所在主机的信息,failover时就是依据配置文件的sentinel信息来进行判决选择新的master


四.redis的集群(redis cluster)

    Redis Cluster是由多个同时服务于一个数据集合的Redis实例组成的整体,对于用户来说,用户只关注这个数据集合,而整个数据集合的某个数据子集存储在哪个节点对于用户来说是透明的。Redis Cluster具有分布式系统的特点。Redis Cluster中有一个16384长度的槽的概念,他们的编号为0、1、2、3……16382、16383。这个槽是一个虚拟的槽,并不是真正存在的。正常工作的时候,Redis Cluster中的每个Master节点都会负责一部分的槽,当有某个key被映射到某个Master负责的槽,那么这个Master负责为这个key提供服务,至于哪个Master节点负责哪个槽,这是可以由用户指定的,也可以在初始化的时候自动生成(redis-trib.rb脚本)。这里值得一提的是,在Redis Cluster中,只有Master才拥有槽的所有权,如果是某个Master的slave,这个slave只负责槽的使用,但是没有所有权。

1.redis集群的搭建(实验之前关闭本机上的redis服务)

(1)安装ruby(2.2以上)、rubygems、以及依赖包libyaml

ruby是一种面向对象的语言;rubygems是ruby包的管理工具

(2)安装redis-gems(redis集群需要的ruby插件,使用gem安装)

(3)在/usr/local/目录下创建一个cluster目录用来创建6个redis节点

(4)vim /usr/local/cluster/redis.conf    ##每一个节点的配置文件(除了端口外,别的配置信息一样)

port           ##端口

cluster-enabled  yes    ##开启集群 把注释去掉

cluster-config-file nodes.conf     ##集群的节点配置文件
cluster-node-timeout  5000        ##请求超时

appendonly  yes                         ##aof日志开启,每一次写操作都会记录一条日志

daemonsize yes                          ##允许redis在后台运行

(5)开启redis集群(逐个节点打开)

如果有报错: # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

vim /etc/sysctl.conf
:

vm.overcommit_memory = 1

sysctl -p     ##激活配置

overcommit_memory 是内存分配策略,可选值:0、1、2。
0--表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1--表示内核允许分配所有的物理内存,而不管当前的内存状态如何
2--表示内核允许分配超过所有物理内存和交换空间总和的内存

2.用redis自带的redis-trib.rb脚本把每个节点加入redis集群

(1)redis-trib.rb create --replicas 1 127.0.0.1:7000 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     ##由于节点在本地,连接回环接口即可,--replicas 1  ##一主一从



(2)可以从任意一个节点进入集群,对用户全透明

redis-trib.rb check 127.0.0.0:7000   ##检查集群信息

redis-trib.rb info 127.0.0.1:7000  ##查看master

3.故障测试(只要任意节点和它的从库不同时挂掉,集群正常运行;任意一个主库挂掉,会有新的从库来顶替挂掉的主库)

如果节点只有三台,集群还是会正常运行,每台都是主库;但是16384个槽点必须保持完整,如果槽点被破坏,集群就down掉