Redis 实战搭建高可用架构
Posted chenhaoyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 实战搭建高可用架构相关的知识,希望对你有一定的参考价值。
前言:最近在看关于redis缓存方面的知识,今天就来个 Redis sentinel 高可用架构,实战开始之前,先看看sentinel的概念
什么是redis-sentinel
Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,
Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
为什么使用sentinel服务
redis的普通主从模式中,当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化。
为此,Redis 2.8开始提供了哨兵工具来实现自动化的系统监控和故障恢复功能。 哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。
一、首先实现主从复制(一主多从)
说明:如果这台服务器出现硬盘故障等问题,也会导致数据丢失。为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。
为此, Redis 提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。
这里,我们把redis.conf作为master,slave_1.conf和slave_2.conf为从
1、找到redis.conf,复制出2份(我只有一个服务器,所以通过改变端口来实现)
2、修改以下几项配置
1、端口号: slave_1.conf:6380 slave_2.conf:6381 2、绑定 slave_1.conf:slaveof 127.0.0.1 6379 slave_2.conf:slaveof 127.0.0.1 6379 3、密码(最好跟master一致) slave_1.conf:requirepass 123456
slave_2.conf:requirepass 123456
4、验证密码(从机对主机验证时,所需的密码)
slave_1.conf:masterauth 123456
slave_2.conf:masterauth 123456
3、启动主机和从机
4、验证结果
master:
slave_1:
slave_2:
5、流程图
可以看到主机执行写命令,从机能同步主机的值,主从复制就实现了。
注意:默认情况下从库是只读的,不能进行修改,需要修改需要设置配置文件中的slave-read-only为no。在命令行里执行slaveof no one可以让一个从库变成主库。
问题:当主服务器挂了怎么办
二、引入sentinel(哨兵)模式
特点:
1、不时地监控redis是否按照预期良好地运行;
2、如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
3、能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,
其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。
单点sentinel示意图
集群sentinel示意图(防止单点故障)
1、找到sentinel.conf文件
1、找到sentinel.conf文件,默认在redis源码包里
2、复制sentinel.conf文件到redis.conf同级目录
2、配置sentinel.conf
说明:我这里是单个sentinel,集群sentinel下面方法也通用
1、port : 当前Sentinel服务运行的端口(注意:多个sentinel,记得修改端口号)
2、dir : Sentinel服务运行时使用的临时文件夹
3、sentinel monitor master001 192.168.110.101 6379 2:Sentinel去监视一个名为master001的主redis实例,这个主实例的IP地址为本机地址192.168.110.101,端口号为6379,
而将这个主实例判断为失效至少需要2个 Sentinel进程的同意(注意:如果是单个sentinel,这里就是1),只要同意Sentinel的数量不达标,
自动failover就不会执行
4、sentinel auth-pass mymaster 123456:设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
4、sentinel down-after-milliseconds master001 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。
只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,
实例才会被标记为客观下线,这时自动故障迁移才会执行
5、sentinel parallel-syncs master001 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
6、sentinel failover-timeout master001 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败
7、sentinel notification-script <master-name> <script-path>:指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用
3、启动sentinel
命令:redis-sentinel sentinel.conf
说明:redis-sentinel path (sentinel的配置文件路径) + filename (文件名)
多个sentinel也一样,只需修改filename就行
启动后会在控制台看到如下信息
4、测试sentinel自动切换功能
1、停止主节点(端口为6379)
2、查看slave节点(端口为6380,6381)
可以看到,已经成功切换了
3、恢复主节点(master)
之前的主节点变成了slave
5、启动中碰到的问题
1、redis启动警告问题:WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 原因:对一个高负载的环境来说tcp设置128这个值,太小了。 解决: 1、临时:执行 echo 511 > /proc/sys/net/core/somaxconn 2、永久:打开ietc/sysctl.conf,在这里面添net.core.somaxconn= 1024 然后执行sysctl -p 就可以永久消除这个warning 2、在控制台info中没看到* +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379这类的信息,
而是这个sdown master mymaster 127.0.0.1 6379,Next failover delay: I will not start a failover之类的 原因:没有设置master连接密码 解决:在sentinel.conf上设置 sentinel auth-pass mymaster password(master密码)
3、启动sentinel出现:*** FATAL CONFIG FILE ERROR *** Reading the configuration file, at line 104 ‘sentinel auth-pass mymaster redis‘ No such master with specified name.
原因:这是因为设置sentinel auth-pass的时候没有在sentinel monitor mymaster ... 的下面
解决:设置在sentinel monitor mymaster ... 的下面就行了
说明:我上面的例子中,只用了单个sentinel,这会存在单点故障问题。这点需要注意
三、官方提供的集群高可用架构(redis-cluster)
前言:关于redis-cluster,这里就不实际操作了,有兴趣的小伙伴可以自己去试试。
1、这里简单说说redis-cluster的作用
即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。
为了最大化利用内存,可以采用cluster群集,就是分布式存储。即每台redis存储不同的内容。
采用redis-cluster架构正是满足这种分布式存储要求的集群的一种体现。redis-cluster架构中,被设计成共有16384个hash slot。
每个master分得一部分slot,其算法为:hash_slot = crc16(key) mod 16384 ,这就找到对应slot。采用hash slot的算法,
实际上是解决了redis-cluster架构下,有多个master节点的时候,数据如何分布到这些节点上去。
key是可用key,如果有{}则取{}内的作为可用key,否则整个可以是可用key。群集至少需要3主3从,且每个实例使用不同的配置文件。
示意图
2、redis-cluster架构说明
在cluster架构下,默认的,一般redis-master用于接收读写,而redis-slave则用于备份,当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。
但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可通过readonly命令,将slave设置成可读,然后通过slave获取相关的key,达到读写分离。
3、注意事项
(1)redis-cluster最小配置为三主三从,当1个主故障,大家会给对应的从投票,把从立为主,若没有从数据库可以恢复则redis群集就down了。
(2)在这个redis cluster中,如果你要在slave读取数据,那么需要带上readonly指令。redis cluster的核心的理念,主要是用slave做高可用的,
每个master挂一两个slave,主要是做数据的热备,当master故障时的作为主备切换,实现高可用的。redis cluster默认是不支持slave节点读或者写的,
跟我们手动基于replication搭建的主从架构不一样的。slave node要设置readonly,然后再get,这个时候才能在slave node进行读取。对于redis -cluster主从架构,
若要进行读写分离,官方其实是不建议的,但也能做,只是会复杂一些。
(3)redis-cluster的架构下,实际上本身master就是可以任意扩展的,你如果要支撑更大的读吞吐量,或者写吞吐量,或者数据量,都可以直接对master进行横向扩展就可以了。
也扩容master,跟之前扩容slave进行读写分离,效果是一样的或者说更好。
(4)可以使用自带客户端连接:使用redis-cli -c -p cluster中任意一个端口,进行数据获取测试。
以上就是全部内容了,sentinel模式为本人实测
以上是关于Redis 实战搭建高可用架构的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes云原生实战03 搭建高可用负载均衡器(Keepalived 和 HAproxy)
Kubernetes云原生实战03 搭建高可用负载均衡器(Keepalived 和 HAproxy)