在工程项目中,系统应用的高可用性越来越重要,业主越来越重视。其实高可用可以分为应用层高可用和数据层高可用,数据层高可用中常见的有关系型数据库mysql的高可用、非关系型NoSQl数据库redis的高可用等,下面聊聊典型的NoSQL数据库redis的高可用方案。
高可用(High Availability,即HA),指的是通过尽量缩短日常维护操作和突发的系统崩溃所导致的停机时间,以提高系统和应用的可用性。一个业务系统如果全年无一时刻不在提供服务,它的可用性可达100%。那么什么样的系统可以称之为高可用呢,业界一般用几个九来衡量系统的可用性,当系统运行时间达到4个九即99.99%时的系统为高可用的,全年宕机时间为52分钟左右。
1、redis集群简介
redis集群是一种通过将多个redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。根据搭建的方式和集群的特性,redis集群主要有三种模式:主从复制Master-Slave模式、哨兵Sentinel模式和集群Cluster模式。
redis集群的作用和优势如下:
- 容灾恢复:在哨兵模式下,redis集群可以在主节点出现故障时,快速切换到从节点,实现业务的无缝切换;
- 高可用性:在cluster模式下,redis集群可以在某个节点发生故障时,自动进行故障转移,保证服务的持续可用;
- 负载均衡:在cluster模式下,redis集群可以将客户端请求分发到不同的节点上,有效地分摊节点的压力,提高系统的整体性能;
- 数据分片:在cluster模式下,redis集群可以将数据分散在不同的节点上,从而突破单节点内存限制,实现更大规模的数据存储;
- 易于扩展:在cluster模式下,redis集群可以根据业务需求和系统负载,动态地添加或移除节点,实现水平扩展。
2、主从复制Master-Slave模式
2.1、主从复制原理
主从复制是redis的一种基本集群模式,它通过将一个redis节点(主节点)的数据复制到一个或多个其他redis节点(从节点)来实现数据的冗余和备份。
主节点负责处理客户端的写操作,同时从节点会实时同步主节点的数据。客户端可以从从节点读取数据,实现读写分离,提高系统性能。
2.2、主从复制配置
配置主节点:在主节点的redis.conf配置文件中,无需进行特殊配置,主节点默认监听所有客户端请求。
# 主节点默认端口号6379
port 6379
配置从节点:在从节点的redis.conf配置文件中,天津如下配置,制动主节点的地址和端口。
# 从节点设置端口号6380
port 6380
# replicaof 主节点IP 主节点端口
replicaof 127.0.0.1 6379
在主节点上执行写操作,然后在从节点上进行读操作,检查数据是否一致。
2.3、主从复制的优缺点
- 优点:配置简单,易于实现;实现数据冗余,提供数据可靠性;读写分离,提供系统性能。
- 缺点:主节点故障时,需要手动切换到从节点,不能自动实现故障转移,故障恢复时间较长;主节点承担所有写操作,可能成为性能瓶颈;无法实现数据分片,受单节点内存限制。
2.4、主从复制应用场景
主从复制模式适用于以下场景:
- 数据备份和容灾恢复:通过从节点备份主节点的数据,实现数据冗余;
- 读写分离:将读操作分发到从节点,减轻主节点压力,提高系统性能;
- 在线升级和扩展:在不影响主节点的情况下,通过增加从节点来扩展系统的读取能力。
3、哨兵Sentinel模式
3.1、哨兵模式原理
哨兵模式是在主从复制模式的基础上加入了哨兵节点,实现了自动故障转移。哨兵节点是一种特殊的Redis节点,它会监控主节点和从节点的运行状态。当主节点发生故障时,哨兵节点会自动从从节点中选举出一个新的主节点,并通知其他从节点和客户端,实现故障转移。
3.2、哨兵模式配置
配置主从复制:首先按照主从复制模式的配置方法,搭建一个主从复制集群,参考上面。
配置哨兵节点:在哨兵节点上创建一个新的哨兵配置文件(如:sentinel.conf),并添加如下配置:
# sentinel节点端口号
port 26379
# sentinel monitor 被监控主节点名称 主节点IP 主节点端口 quorum
sentinel monitor mymaster 127.0.0.1 6379 2
# sentinel down-after-milliseconds 被监控主节点名称 毫秒数
sentinel down-after-milliseconds mymaster 60000
# sentinel failover-timeout 被监控主节点名称 毫秒数
sentinel failover-timeout mymaster 180000
其中,quorum是指触发故障转移所需的最小哨兵节点数。down-after-milliseconds表示主节点被判断为失效的时间。failover-timeout是故障转移超时时间。
启动哨兵节点:使用如下命令启动哨兵节点
redis> redis-sentinel /path/to/sentinel.conf
手动停止主节点,观察哨兵节点是否自动选举出新的主节点,并通知其他从节点和客户端。
3.3、哨兵模式的优缺点
- 优点:自动故障转移,提供系统的高可用性;具有主从复制的优点,如数据冗余和读写分离。
- 缺点:配置和管理相对复杂,依然无法实现数据分片,受单节点内存限制。
3.4、哨兵模式应用场景
哨兵模式适用于以下场景:
- 高可用性要求较高的场景:通过自动故障转移,确保服务的持续可用;
- 数据备份和容灾恢复:在主从复制的基础上,提供自动故障转移功能;
4、集群Cluster模式
4.1、Cluster模式原理
Cluster模式是Redis的一种高级集群模式,它通过数据分片和分布式存储实现了负载均衡和高可用性。在Cluster模式下,Redis将所有的键值对数据分散在多个节点上。每个节点负责一部分数据,称为槽位。通过对数据的分片,Cluster模式可以突破单节点的内存限制,实现更大规模的数据存储。
集群部署的方式能自动将数据进行分片,每个master上放一部分数据,提供了内置的高可用服务,即使某个master宕机了,服务还可以正常地提供,类似如下:
(摘自网上,未再次绘制)
集群模式中数据通过数据分片的方式被自动分割到不同的master节点上,每个Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽。数据在集群模式中是分开存储的,那么节点之间想要知道其他节点的状态信息,包括当前集群状态、集群中各节点负责的哈希槽、集群中各节点的master-slave状态、集群中各节点的存活状态等是通过建立TCP连接,使用gossip协议来进行集群信息传播。
4.2、Cluster模式配置
配置redis节点:为每个节点创建一个redis.conf配置文件,并添加如下配置
# cluster节点端口号
port 7001
# 开启集群模式
cluster-enabled yes
# 节点超时时间
cluster-node-timeout 15000
像这样的配置,一共需要创建6个,做一个三主三从的集群。
启动redis节点:使用如下命令启动6个节点
redis-server redis_7001.conf
创建redis集群:使用Redis命令行工具执行如下命令创建Cluster
redis-cli --cluster create 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 --cluster-replicas 1
cluster-replicas 表示从节点的数量,1代表每个主节点都有一个从节点,要求集群至少6个;若从节点数量为2,则要求集群至少9个。
向Cluster发送请求,观察请求是否正确路由到相应的节点。
4.4、Cluster模式的优缺点
- 优点:数据分片、实现大规模数据存储;负载均衡,提供系统性能;自动故障转移,提高高可用性。
- 缺点:配置和管理较复杂。
4.5、Clustet模式应用场景
Cluster模式适用于以下场景:
- 大规模数据存储:通过数据分片,突破单节点内存限制;
- 高性能要求场景:通过负载均衡,提高系统性能;
- 高可用性要求场景:通过自动故障转移,确保服务的持续可用;
5、搭建集群Cluster模式
redis版本:redis-5.0.12
系统:ubuntun16.04
创建6个Redis的配置文件,如下所示:
/usr/local/redis-5.0.12/redis-cluster-conf/7001/redis.conf
/usr/local/redis-5.0.12/redis-cluster-conf/7002/redis.conf
/usr/local/redis-5.0.12/redis-cluster-conf/7003/redis.conf
/usr/local/redis-5.0.12/redis-cluster-conf/7004/redis.conf
/usr/local/redis-5.0.12/redis-cluster-conf/7005/redis.conf
/usr/local/redis-5.0.12/redis-cluster-conf/7006/redis.conf
配置文件内容如下:
# 端口,每个配置文件不同7001-7006
port 7001
# 启用集群模式
cluster-enabled yes
#节点配置文件
cluster-config-file nodes.conf
# 超时时间
cluster-node-timeout 5000
# 打开aof持久化
appendonly yes
# 后台运行
daemonize yes
# 非保护模式
protected-mode no
启动6个redis节点,如下:
./bin/redis-server redis-cluster-conf/7001/redis.conf
./bin/redis-server redis-cluster-conf/7002/redis.conf
./bin/redis-server redis-cluster-conf/7003/redis.conf
./bin/redis-server redis-cluster-conf/7004/redis.conf
./bin/redis-server redis-cluster-conf/7005/redis.conf
./bin/redis-server redis-cluster-conf/7006/redis.conf
此时启动的6个Redis服务是相互独立运行的,通过以下命令配置集群,如下:
./bin/redis-cli --cluster create --cluster-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
配置完看到如下图所示信息表示集群搭建成功:
从图中可以看到启动了3个master节点,3个slave节点,16384个槽点平均分配到了3个master节点上。图中很长的一串字母数字的组合(07000b3a90…)为节点的ID。后面对节点的操作中会用到。
自动故障转移
当运行中的master节点挂掉了,集群会在该master节点的slave节点中选出一个作为新的master节点。
添加一个主节点
按之前的方式再复制一份配置文件,并修改配置,后启动该Redis服务,执行以下命令将该节点添加到集群中去,如下:
./bin/redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001
程序中使用,springboot中连接Redis集群配置
spring:
redis:
cluster:
nodes: 192.168.1.164:7001,192.168.1.164:7002,192.168.1.164:7003,192.168.1.164:7004,192.168.1.164:7005,192.168.1.164:7006
database: 0
password: <password>
6、小结
redis集群的每种模式都有其特点和应用场景,分析如下:
- 主从复制模式:适用于数据备份和读写分离场景,配置简单,但在主节点故障时需要手动切换。
- 哨兵模式:在主从复制的基础上实现自动故障转移,提高高可用性,适用于高可用性要求较高的场景。
- Cluster模式:通过数据分片和负载均衡实现大规模数据存储和高性能,适用于大规模数据存储和高性能要求场景。