0x00 Redis简介
Redis是一款开源的、高性能的键-值存储(key-value store)。它常被称作是一款数据结构服务器(data structure server)。
Redis的键值可以包括字符串(strings)类型,同时它还包括哈希(hashes)、列表(lists)、集合(sets)和 有序集合(sorted sets)等数据类型。 对于这些数据类型,你可以执行原子操作。例如:对字符串进行附加操作(append);递增哈希中的值;向列表中增加元素;计算集合的交集、并集与差集等。
为了获得优异的性能,Redis采用了内存中(in-memory)数据集(dataset)的方式。同时,Redis支持数据的持久化,你可以每隔一段时间将数据集转存到磁盘上(snapshot),或者在日志尾部追加每一条操作命令(append only file,aof)。
Redis同样支持主从复制(master-slave replication),并且具有非常快速的非阻塞首次同步( non-blocking first synchronization)、网络断开自动重连等功能。同时Redis还具有其它一些特性,其中包括简单的事物支持、发布订阅 ( pub/sub)、管道(pipeline)和虚拟内存(vm)等 。
Redis具有丰富的客户端,支持现阶段流行的大多数编程语言。
Redis 下载地址:http://www.redis.cn/download.html
Redis 在线测试工具:http://try.redis.io/
0x01 Redis单机安装
1. 在线获取安装包或者直接把redis下载好的安装包拖入要安装的主机。
wget http://download.redis.io/releases/redis-3.2.6.tar.gz
2. 解压
tar xzvf redis-3.2.6.tar.gz
3. 进入解压文件夹,开始编译安装
cd redis-3.2.6
make & make install
4. 编译完成后,在Src目录下,有四个可执行文件redis-server、redis-benchmark、redis-cli和redis.conf。然后拷贝到一个目录下
mkdir /usr/redis
cp redis-server /usr/redis
cp redis-benchmark /usr/redis
cp redis-cli /usr/redis
cp redis.conf /usr/redis
cd /usr/redis
5. 启动Redis服务
./redis-server &
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5yM5QzNycDZ3YTNzY2Y0MGOyYzX3QTMxETM0IzLcVDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
然后用客户端测试一下是否启动成功
redis-cli
6. 停止和卸载Redis
pkill redis //停止redis
// 卸载redis:
rm -rf /usr/local/redis //删除安装目录
rm -rf /usr/bin/redis-* //删除所有redis相关命令脚本
rm -rf /root/download/redis-4.0.4 //删除redis解压文件夹
0x02 Redis伪集群安装
1. 安装ruby环境
yum install ruby
yum install rubygems
2.将redis集群管理工具redis-trib.rb上传至服务器,或者在线安装ruby的包
gem install redis-3.0.0.gem
在local下创建redis-cluster文件夹,在该文件夹中创建6个redis实例,端口号从7001~7006
复制redis安装目录bin文件夹
在redis-cluster文件夹下将redis01复制5份
修改redis01至redis06中的redis.conf 文件,将端口依次改为70001~7006,并打开cluster-enabled yes行前的注释
3. 把创建集群的ruby脚本redis-trib.rb复制到redis-cluster文件夹下
4. 启动6个redis实例
5. 创建集群(192.168.242.134是你自己ip,创建过程中输入yes确认)
./redis-trib.rb create --replicas 1
192.168.242.134:7001
192.168.242.134:7002
192.168.242.134:7003
192.168.242.134:7004
192.168.242.134:7005
192.168.242.134:7006
6. 测试集群(-c 不能缺)
进入集群任一文件夹下输入
redis01/redis-cli -h 192.168.25.153 -p 7002 -c
0x03 Redis之Sentinel高可用主从复制安装部署
1. Sentinel介绍
1.1 主从复制的问题
Redis
主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
- 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
- 扩展主节点的读能力,分担主节点读压力。
但是问题来了:
- 一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
- 主节点的写能力受到单机的限制。
- 主节点的存储能力受到单机的限制。
第一个问题,我们接下来讲的
Sentinel
就可以解决。而后两个问题,
Redis
也给出了方案
Redis Cluster
。
1.2 Redis Sentinel的高可用
Redis Sentinel
是一个分布式架构,包含若干个
Sentinel
节点和
Redis
数据节点,每个
Sentinel
节点会对数据节点和其余
Sentinel
节点进行监控,当发现节点不可达时,会对节点做下线标识。
如果被标识的是主节点,他还会选择和其他
Sentinel
节点进行“协商”,当大多数的
Sentinel
节点都认为主节点不可达时,他们会选举出一个
Sentinel
节点来完成自动故障转移工作,同时将这个变化通知给
Redis
应用方。
整个过程完全自动,不需要人工介入,所以可以很好解决
Redis
的高可用问题。
接下来我们就通过部署一个
Redis Sentinel
实例来了解整体框架。
2. Redis Sentinel部署
我们部署的拓扑结构如图所示:
分别有3个
Sentinel
节点,1个主节点,2个从节点组成一个
Redis Sentinel
。
2.1 启动主节点
配置:
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
启动主节点:
sudo redis-server redis-6379.conf
使用
PING
命令检测是否启动:
redis-cli -h 127.0.0.1 -p 6379 ping
PONG
2.2 启动两个从节点
配置(两个从节点配置相同,除了文件名有区分):
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379 // 从属主节点
启动两个从节点:
sudo redis-server redis-6380.conf
sudo redis-server redis-6381.conf
使用
PING
命令检测是否启动:
redis-cli -h 127.0.0.1 -p 6380 ping
redis-cli -h 127.0.0.1 -p 6381 ping
2.3 确认主从关系
主节点视角
redis-cli -h 127.0.0.1 -p 6379 INFO replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=85,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=85,lag=0
......
从节点视角(6380端口)
redis-cli -h 127.0.0.1 -p 6380 INFO replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
......
确立中从关系,如下图所示:
2.4 部署Sentinel节点
3个Sentinel节点的部署方法是相同的(端口不同)。以
26379
为例。
配置
// Sentinel节点的端口
port 26379
dir /var/redis/data/
logfile "26379.log"
// 当前Sentinel节点监控 127.0.0.1:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// mymaster是主节点的别名
sentinel monitor mymaster 127.0.0.1 6379 2
//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达
sentinel down-after-milliseconds mymaster 30000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000
启动(两种方法)
redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel
sudo redis-sentinel sentinel-26379.conf --sentinel
确认
redis-cli -h 127.0.0.1 -p 26379 INFO Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=1 //sentinels=1表示启动了1个Sentinel
部署三个
Sentinel
节点之后,真个拓扑结构如图所示:
- 当部署号
之后,会有如下变化Redis Sentinel
- Sentinel节点自动发现了从节点、其余Sentinel节点。
- 去掉了默认配置,例如:
、parallel-syncs
。failover-timeout
- 新添加了纪元(epoch)参数。
我们拿端口
26379
的举例,启动所有的Sentinel和数据节点后,配置文件如下:
port 26379
dir "/var/redis/data"
sentinel myid 70a3e215c1a34b4d9925d170d9606e615a8874f2
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
daemonize yes
logfile "26379.log"
// 发现了两个从节点
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-slave mymaster 127.0.0.1 6380
// 发送了连个Sentinel节点
sentinel known-sentinel mymaster 127.0.0.1 26381 e1148ad6caf60302dd6d0dbd693cb3448e209ac2
sentinel known-sentinel mymaster 127.0.0.1 26380 39db5b040b21a52da5334dd2d798244c034b4fc3
sentinel current-epoch 0
2.5 故障转移实验
先查看一下节点的进程
pid
ps -aux | grep redis
root 18225 0.1 0.0 40208 11212 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6379
root 18234 0.0 0.0 38160 8364 ? Ssl 22:10 0:04 redis-server 127.0.0.1:6380
root 18244 0.0 0.0 38160 8308 ? Ssl 22:10 0:04 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 23:05 0:02 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 23:07 0:02 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 23:07 0:02 redis-sentinel *:26381 [sentinel]
我们干掉端口
6379
的主节点。
➜ sudo kill -9 18225
➜ ps -aux | grep redis
root 18234 0.0 0.0 38160 8364 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6380
root 18244 0.0 0.0 38160 8308 ? Ssl 22:10 0:05 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 23:05 0:03 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 23:07 0:03 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 23:07 0:03 redis-sentinel *:26381 [sentinel]
此时,
Redis Sentinel
对主节点进行客观下线(Objectively Down, 简称 ODOWN)的判断,确认主节点不可达,则通知从节点中止复制主节点的操作。
当主节点下线时长超过配置的下线时长
30000
秒,
Redis Sentinel
执行故障转移操作。
此时,我们查看一下Sentinel节点监控的主节点信息:
127.0.0.1:26379> sentinel masters
1) 1) "name"
2) "mymaster"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6380" //可以看到主节点已经成为6380端口的节点
7) "runid"
8) "084850ab4ff6c2f2502b185c8eab5bdd25a26ce2"
9) "flags"
10) "master"
..............
看一下Sentinel节点监控的从节点信息:
127.0.0.1:26379> sentinel slaves mymaster
1) 1) "name"
2) "127.0.0.1:6379" //ip:port
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) ""
9) "flags"
10) "s_down,slave,disconnected" //端口6379的原主节点已经断开了连接
..............
2) 1) "name"
2) "127.0.0.1:6381"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6381"
7) "runid"
8) "24495fe180e4fd64ac47467e0b2652894406e9e4"
9) "flags"
10) "slave" //本来的从节点,还是从节点的role
..............
由以上信息可得,端口为
6380
的Redis数据节点成为新的主节点,端口为
6379
的旧主节点断开连接。如图所示:
我们在试着重启端口
6379
的数据节点。
➜ sudo redis-server redis-6379.conf
➜ ps -aux | grep redis
root 18234 0.1 0.0 40208 11392 ? Ssl 5月22 0:06 redis-server 127.0.0.1:6380
root 18244 0.1 0.0 40208 10356 ? Ssl 5月22 0:07 redis-server 127.0.0.1:6381
root 20568 0.1 0.0 38160 8460 ? Ssl 5月22 0:05 redis-sentinel *:26379 [sentinel]
root 20655 0.1 0.0 38160 8296 ? Ssl 5月22 0:05 redis-sentinel *:26380 [sentinel]
root 20664 0.1 0.0 38160 8312 ? Ssl 5月22 0:05 redis-sentinel *:26381 [sentinel]
menwen 22475 0.0 0.0 14216 5920 pts/2 S+ 5月22 0:00 redis-cli -p 26379
// 6379的数据节点已重启
root 22617 0.0 0.0 38160 8304 ? Ssl 00:00 0:00 redis-server 127.0.0.1:6379
看看发生什么:
127.0.0.1:26379> sentinel slaves mymaster
1) 1) "name"
2) "127.0.0.1:6379" //6379端口的节点重启后,变成了"活"的从节点
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "de1b5c28483cf150d9550f8e338886706e952346"
9) "flags"
10) "slave"
..............
2) 1) "name" //6381端口的节点没有变化,仍是从节点
2) "127.0.0.1:6381"
..............
他被降级成为端口
6380
的从节点。
从上面的逻辑架构和故障转移试验中,可以看出
Redis Sentinel
的以下几个功能。
- 监控:
节点会定期检测Sentinel
数据节点和其余Redis
节点是否可达。Sentinel
- 通知:
节点会将故障转移通知给应用方。Sentinel
- 主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系。
- 配置提供者:在
结构中,客户端在初始化的时候连接的是Redis Sentinel
节点集合,从中获取主节点信息。Sentinel
3. Sentinel配置说明
- sentinel monitor mymaster 127.0.0.1 6379 2
- 当前Sentinel节点监控 127.0.0.1:6379 这个主节点
- 2代表判断主节点失败至少需要2个Sentinel节点节点同意
- mymaster是主节点的别名
- sentinel down-after-milliseconds mymaster 30000
- 每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达
- sentinel parallel-syncs mymaster 1
- 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1。
- sentinel failover-timeout mymaster 180000
- 故障转移超时时间为180000
- sentinel auth-pass \ \
- 如果
监控的主节点配置了密码,可以通过Sentinel
配置通过添加主节点的密码,防止sentinel auth-pass
节点无法对主节点进行监控。Sentinel
- 例如:
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
- sentinel notification-script \ \
- 在故障转移期间,当一些警告级别的
事件发生(指重要事件,如主观下线,客观下线等)时,会触发对应路径的脚本,想脚本发送相应的事件参数。Sentinel
- 例如:
sentinel notification-script mymaster /var/redis/notify.sh
- sentinel client-reconfig-script \ \
- 在故障转移结束后,触发应对路径的脚本,并向脚本发送故障转移结果的参数。
- 例如:
。sentinel client-reconfig-script mymaster /var/redis/reconfig.sh