Linux Redis安装(服务器架设篇)

前言

Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。它的特点就是一个字:快。作为一种内存性NoSql数据库,Redis的I/O速度非常快,而且支持多种数据格式的存储,相比大多数纯内存型NoSql数据库比如Memcache,Redis还可以持久化数据到硬盘保证服务器突然断电或者故障后的数据安全,在使用灵活性和性能上是强于Memcache的,具体的优缺点对比我就不多讲了。Redis主要用在大并发,高I/O读取的分布式场景下。例如配合关系型数据库做高速缓存;缓存高频次访问的数据,降低数据库I/O;分布式架构,做session共享;实现分布式锁等。

安装

环境 版本
RHEL/CentOS 7.x
Redis 5.0.x

安装redis单实例并设置端口,配置文件路径,数据库存放目录,执行文件路径并设置开机自启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 下载redis安装文件到linux主机上 解压
[thinktik@bogon ~]$ ls
redis-5.0.2.tar.gz
[thinktik@bogon ~]$ tar -zxvf redis-5.0.2.tar.gz
redis-5.0.2/
redis-5.0.2/.gitignore

...

redis-5.0.2/utils/speed-regression.tcl
redis-5.0.2/utils/whatisdoing.sh
# 完成解压
[thinktik@bogon ~]$ ls
redis-5.0.2 redis-5.0.2.tar.gz
# 进入解压后的目录
[thinktik@bogon ~]$ cd redis-5.0.2
[thinktik@bogon redis-5.0.2]$ ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
# 编译
[thinktik@bogon redis-5.0.2]$ make

# 编译完成后出现提示,建议我们make test 进行测试
LINK redis-server
INSTALL redis-sentinel
CC redis-cli.o
LINK redis-cli
CC redis-benchmark.o
LINK redis-benchmark
INSTALL redis-check-rdb
INSTALL redis-check-aof

Hint: It's a good idea to run 'make test' ;)

make[1]: Leaving directory `/home/thinktik/redis-5.0.2/src'

# 测试 提示需要tcl8.5以及8.5以上的环境,测试环境不满足无法测试
[thinktik@bogon redis-5.0.2]$ make test
cd src && make test
make[1]: Entering directory `/home/thinktik/redis-5.0.2/src'
CC Makefile.dep
make[1]: Leaving directory `/home/thinktik/redis-5.0.2/src'
make[1]: Entering directory `/home/thinktik/redis-5.0.2/src'
You need tcl 8.5 or newer in order to run the Redis test
make[1]: *** [test] Error 1
make[1]: Leaving directory `/home/thinktik/redis-5.0.2/src'
make: *** [test] Error 2

# 切换到root 安装tcl
[thinktik@bogon redis-5.0.2]$ su
Password:
[root@bogon redis-5.0.2]# yum install tcl
# root安装完tcl后退出root,使用普通用户测试
[thinktik@bogon redis-5.0.2]$ make test

...
301 seconds - unit/memefficiency
439 seconds - integration/replication
# 测试通过
\o/ All tests passed without errors!

Cleanup: may take some time... OK
make[1]: Leaving directory `/home/thinktik/redis-5.0.2/src'

# root安装
[thinktik@bogon redis-5.0.2]$ su
[root@bogon redis-5.0.2]# make install
cd src && make install
make[1]: Entering directory `/home/thinktik/redis-5.0.2/src'

Hint: It's a good idea to run 'make test' ;)

INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/home/thinktik/redis-5.0.2/src'

# root用户设置开机自启动已经监听等配置项
[root@bogon redis-5.0.2]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
[root@bogon redis-5.0.2]# cd utils/
[root@bogon utils]# ls
build-static-symbols.tcl graphs redis-copy.rb speed-regression.tcl
cluster_fail_time.tcl hashtable redis_init_script whatisdoing.sh
corrupt_rdb.c hyperloglog redis_init_script.tpl
create-cluster install_server.sh redis-sha1.rb
generate-command-help.rb lru releasetools
# 执行文件夹下的启动脚本
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
#这里可以自己指定监听端口 这里我不要默认的6379而指定为7379
Please select the redis port for this instance: [6379] 7379
#这里可以自己指定配置文件路径 我选默认
Please select the redis config file name [/etc/redis/7379.conf]
Selected default - /etc/redis/7379.conf
#这里可以自己指定日志文件路径 我选默认
Please select the redis log file name [/var/log/redis_7379.log]
Selected default - /var/log/redis_7379.log
#这里可以自己指定数据文件路径 我选默认
Please select the data directory for this instance [/var/lib/redis/7379]
Selected default - /var/lib/redis/7379
#这里可以自己指定redis执行文件路径 我选默认
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 7379
Config file : /etc/redis/7379.conf
Log file : /var/log/redis_7379.log
Data dir : /var/lib/redis/7379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/7379.conf => /etc/init.d/redis_7379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
# 配置完成

查看安装效果,验证是否可开机自启

配置完成后查看redis

1
2
3
4
# 看到redis自己在配置完成后启动并监听7379端口
[root@bogon utils]# ps -ef | grep redis
root 24359 1 0 14:03 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7379
root 24365 24214 0 14:08 pts/0 00:00:00 grep --color=auto redis

重启后检查redis是否自启动了,检查redis服务。redis服务名是redis_ + 端口,我这里就是redis_7379.service。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Last login: Sun Nov 25 12:58:41 2018 from thinklap
# 重启后再次检查,看到redis在系统重启后果然自启动并监听7379端口
[thinktik@bogon ~]$ ps -ef|grep redis
root 1125 1 0 14:10 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7379
thinktik 1478 1456 0 14:12 pts/0 00:00:00 grep --color=auto redis
# 切换root
[thinktik@bogon ~]$ su
Password:
#查看自启动服务有哪些
[root@thinkcent thinktik]# systemctl list-units
# 里面一定会有redis开头的服务 结尾是你的redis监听端口号
redis_6379.service loaded active running LSB: start and stop redis_7379
# 其实查的烦,我直接过滤出redis的服务名
[root@bogon thinktik]# systemctl list-units | grep redis
redis_7379.service loaded active running LSB: start and stop redis_7379
# 重启redis
[root@bogon thinktik]# systemctl restart redis_7379
# 查看redis状态
[root@bogon thinktik]# systemctl status redis_7379
● redis_7379.service - LSB: start and stop redis_7379
Loaded: loaded (/etc/rc.d/init.d/redis_7379; bad; vendor preset: disabled)
Active: active (running) since Sun 2018-11-25 14:14:08 CST; 6s ago
Docs: man:systemd-sysv-generator(8)
Process: 1504 ExecStop=/etc/rc.d/init.d/redis_7379 stop (code=exited, status=0/SUCCESS)
Process: 1508 ExecStart=/etc/rc.d/init.d/redis_7379 start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/redis_7379.service
└─1510 /usr/local/bin/redis-server 127.0.0.1:7379

Nov 25 14:14:08 bogon systemd[1]: Starting LSB: start and stop redis_7379...
Nov 25 14:14:08 bogon redis_7379[1508]: Starting Redis server...
Nov 25 14:14:08 bogon systemd[1]: Started LSB: start and stop redis_7379.

设置redis远程访问并设置密码(可选)

Redis开启远程访问一般实际使用的少,主要是开发调试等方面用的多,不是开发调试场景,不建议开启,会有安全问题,redis本身速度非常快,暴露在公网上很容易被暴力穷举出登录密码进行入侵。

如果是开发角度上进行远程访问开操作,那么请继续看下去

修改配置文件

1
2
3
4
5
6
7
# 修改/etc/redis/7379.conf
[root@bogon thinktik]# vim /etc/redis/7379.conf

# 修改监听端口
bind 0.0.0.0
# 添加密码
requirepass myPassword

配置完成后重启redis服务

1
2
3
4
5
6
7
8
9
10
11
# 重启服务
[root@bogon thinktik]# systemctl restart redis_7379
# 查看状态
[root@bogon thinktik]# ps -ef | grep redis
root 1539 1 0 14:25 ? 00:00:00 /usr/local/bin/redis-server 0.0.0.0:7379
root 1544 1487 0 14:25 pts/0 00:00:00 grep --color=auto redis
# 防火墙放行redis监听端口
[root@bogon thinktik]# firewall-cmd --zone=public --add-port=7379/tcp --permanent
success
[root@bogon thinktik]# firewall-cmd --reload
success

上面的步骤完成后大家可以在window上安装redis客户端访问linux主机上的redis,我就不做解释了。到这里单实例就完成了安装。

注意第一次你设置密码后重启时,命令是可以的,因为上一次是没有密码的。如果你设置密码后重启,以后再次重启就不行了因为你没有指定密码,不能直接关闭redis。

对于CentOS6/7使用service redis_xxx restart命令反馈如下:

1
2
3
4
5
6
7
8
9
# 设置密码后无法重启
[root@localhost utils]# service redis_7379 restart
Stopping ...
(error) NOAUTH Authentication required.
Waiting for Redis to shutdown ...
Waiting for Redis to shutdown ...
Waiting for Redis to shutdown ...
Waiting for Redis to shutdown ...
^C

对于CentOS7使用systemctl restart redis_xxx命令反馈如下:

1
2
3
4
5
# 设置密码后无法重启
[root@bogon redis-5.0.2]# systemctl restart redis_7379


# 直接无反馈,redis不会关闭也不会重启而是保持现状,一直等待关闭执行。

其实可以这样解决

1
2
3
4
5
6
7
8
9
10
11
12
# 指定密码和端口后关闭即可
[root@localhost utils]# redis-cli -a myPassword -p 7379 shutdown
Warning: Using a password with '-a' option on the command line interface may not be safe.

# 然后就正常了,但是重启,关闭redis服务每次都要向上面那样指定密码
[root@localhost utils]# service redis_7379 restart
/var/run/redis_7379.pid does not exist, process is not running
Starting Redis server...
[root@localhost utils]# service redis_7379 restart
Stopping ...
Redis stopped
Starting Redis server...

Redis设置密码后重启失败

redis几种高可用方案

在服务器上搭建单点的redis在日常开发是够用了的,但是如果用在公司的正式产品上就会有一定风险,同时单点redis也难以抗住逐渐增加的访问压力。为了保证数据大并发下的高可靠性、高性能,redis服务一般会搭建数个节点组成的集群。

目前有三种方案:

  • 主从
  • 哨兵
  • 集群

主从只保证了高可靠性,不能提高redis的写性能,但是搭建最简单,硬件条件要求最低,适合中小型业务。而哨兵在主从的基础上进行了升级,主要加了主从切换的功能、动态加入节点的功能,一般中小型项目推荐使用这种。集群模式是在哨兵模式上的进一步增强,一般大中型高性能高可靠条件下建议使用。

高可用方案主从配置搭建

实现主从复制(Master-Slave Replication)的工作原理:Slave从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,来完成一次完全同步。而Slave从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master主节点继续将所有已经收集到数据的修改命令和新的数据增删改查命令按时间顺序传送给Slaves,Slave将执行这些数据修改命令,从而达到最终的数据同步。

我接着上面单机安装的步骤,在一台机器上开4个redis实例完成主从的演示。其实你多台机分别安装一个redis完成多个实主从和我的没任何区别,只要几台机器间的互相可以访问并且打开各自的redis端口防火墙提供redis远程访问就行了,这个不要讲太多你懂的。我的是伪集群,实际还是要在不同的主机上搭建redis真集群的。

我在单机上开了4个redis实例,如下:

1
2
3
4
5
6
[root@bogon utils]# ps -ef |grep redis
root 1539 1 0 14:25 ? 00:00:01 /usr/local/bin/redis-server 0.0.0.0:7379
root 1625 1 0 14:47 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7380
root 1694 1 0 14:47 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7381
root 1830 1 0 14:48 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7382
root 1835 1487 0 14:48 pts/0 00:00:00 grep --color=auto redis

一个机器开机多个实例的方法很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 以开启7380端口实例为例,其余的实例一样
# 老套路,我们启动redis 02 端口7380
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7380

...

Starting Redis server...
Installation successful!

# 7380 7381 7382都是这样启动的

看好了这几个伪集群节点将要设置关系

节点 ip 端口 身份
01 192.168.50.56 7379
02 192.168.50.56 7380
03 192.168.50.56 7381
04 192.168.50.56 7382

开放远程访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 修改配置文件,将绑定地址由127.0.0.1改为0.0.0.0监听所有的ip访问
[root@localhost utils]# vi /etc/redis/7379.conf
# 重启服务
[root@localhost utils]# service redis_7379 restart
Stopping ...
Redis stopped
Starting Redis server...
#防火墙放行
# 防火墙放行redis监听端口
[root@bogon thinktik]# firewall-cmd --zone=public --add-port=7379/tcp --permanent
success
[root@bogon thinktik]# firewall-cmd --reload
success
#验证 请在和192.168.50.56同一局域网上的其他主机上尝试192.168.50.56的7379 下面就是成功了
[root@localhost utils]# telnet 192.168.56.110 7379
Trying 192.168.56.110...
Connected to 192.168.56.110.
Escape character is '^]'.
# 这样就证明192.168.50.56的7379端口可以被远程访问,真集群就要验证这个保证几个主机redis通信正常,我的伪集群其实不强制需要毕竟没有单机内防火墙阻挡。

设置主从

我们将7379设置为主,其余的全部为从。主从复制的配置很简单,主要操作从节点的配置文件,主节点不需要任何改动

修改所有从机的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@localhost utils]# vi /etc/redis/7380.conf
# 端口设为监听所有
bind 0.0.0.0
# 从机设置密码
requirepass myPassword

# 下面是主从设置 redis5开始不再使用master-slave这个说法了。男女权的问题
################################# REPLICATION #################################

# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
# 从机这里加入主节点的ip和端口
replicaof 192.168.50.56 7379

# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.
# 从机这里加入主节点的密码验证
masterauth myPassword

[root@localhost utils]# vi /etc/redis/7380.conf
# 修改完了保存配置,再重启就可以了
[root@localhost utils]# service redis_7380 restart
Stopping ...
Redis stopped
Starting Redis server...

其余的从机也一样,修改完重启服务。主机和从机都重启服务使设置生效

验证

主机7379

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

[thinktik@bogon ~]$ redis-cli -p 7379
127.0.0.1:7379> info Replication
NOAUTH Authentication required.
127.0.0.1:7379> AUTH myPassword
OK
127.0.0.1:7379> info Replication
# Replication
role:master # 身份master
connected_slaves:3
slave0:ip=192.168.50.56,port=7381,state=online,offset=168,lag=1 # 从机02加入
slave1:ip=192.168.50.56,port=7380,state=online,offset=168,lag=1 # 从机03加入
slave2:ip=192.168.50.56,port=7382,state=online,offset=182,lag=1 # 从机04加入
master_replid:5ec30eeb585bd79a0555142f2642d54f3d412348
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:182
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:182



# 从机02号7380
[thinktik@bogon ~]$ redis-cli -p 7380
127.0.0.1:7380> AUTH myPassword
OK
127.0.0.1:7380> info Replication
# Replication
role:slave # 身份slave
master_host:192.168.50.56 # 主机信息
master_port:7379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:336
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:5ec30eeb585bd79a0555142f2642d54f3d412348
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:336
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:336
127.0.0.1:7380>

# 这样向上面就证明从机们加入成功了

# 我们再验证下数据同步
[thinktik@bogon ~]$ redis-cli -p 7379
127.0.0.1:7379> set test 1
(error) NOAUTH Authentication required.
127.0.0.1:7379> AUTH myPassword
OK
#主机插入数据
127.0.0.1:7379> set test 1
OK
127.0.0.1:7379>
127.0.0.1:7379>
127.0.0.1:7379>
[thinktik@bogon ~]$ redis-cli -p 7380
127.0.0.1:7380> auth myPassword
OK
#从机获取数据
127.0.0.1:7380> get test
"1"

# 这样同步功能就证明可以了

安全设置

redis是一个非常快的NoSQL,这个不要我解释了都懂。为了设置主从,我把redis监听ip改为了0.0.0.0这意味这有可能被恶意的主机从外部访问,所以必须设置密码。同时密码也要复杂一些,redis相比mysql速度快了很多,很短的时间内就可以被人暴力枚举很多次,建议密码还是长一点复杂一点,同时防火墙,redis监听端口和IP大家也尽量设置的详细一些。我是为了演示才设置0.0.0.0.实际可以指定部分ip即可,没必要全部监听和放行。

到这里主从设置就算是结束了,我再次提示下主机密码和从机密码是分开的,不要混了,这和mysql,mongodb的访问密码有点不同。

关于为什么redis5和redis4的主从配置关键字改了的原因,有说明的:太无奈!Redis 作者被迫修改 master-slave 架构的描述

不过名称改了其实配置没什么变化,不要担心。这是新的配置文件,里面也给了说明。如果你要看没改前的redis主从配置请看 Linux Redis4.x安装(服务器架设篇)

参考:

高可用方案哨兵搭建

目前无论是mysql,mongo还是redis,主从模式都有一个固有的根本性问题,那就是主从断连后,如果是从库出问题还好办,大不了从库排除故障后重新连接主库进行增量更新同步。但是如果主库崩溃了就难办了,从库只是保存了主库的数据副本,没法自己提升为主库。为了解决这个问题,mysql提出了集群方案,mongo提出了副本集和分片集方案并不再建议使用了主从方案。那么redis怎么解决的?答案是:哨兵和集群,两种方案各有优劣。

我们接着介绍哨兵模式

Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态,在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用,其已经被集成在redis2.6+的版本中,Redis的哨兵模式到了2.8版本之后就稳定了下来。一般在生产环境也建议使用Redis的2.8版本的以后版本。哨兵(Sentinel)是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel)进程,这些进程使用流言协议(gossipprotocols)来接收关于Master主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。每个哨兵(Sentinel)进程会向其它哨兵(Sentinel)、Master、Slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定配置时间(可配置的)内未得到回应,则暂时认为对方已掉线,也就是所谓的”主观认为宕机” ,英文名称:Subjective Down,简称SDOWN。有主观宕机,肯定就有客观宕机。当“哨兵群”中的多数Sentinel进程在对Master主服务器做出SDOWN的判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down,简称ODOWN。通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)。

哨兵(sentinel) 虽然有一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 –sentinel 选项来启动哨兵(sentinel),哨兵(sentinel) 的一些设计思路和zookeeper非常类似。

Sentinel集群之间会互相通信,沟通交流redis节点的状态,做出相应的判断并进行处理,这里的主观下线状态和客观下线状态是比较重要的状态,它们决定了是否进行故障转移,可以通过订阅指定的频道信息,当服务器出现故障得时候通知管理员,客户端可以将 Sentinel看作是一个只提供了订阅功能的Redis服务器,你不可以使用PUBLISH命令向这个服务器发送信息,但你可以用 SUBSCRIBE 命令或者PSUBSCRIBE命令,通过订阅给定的频道来获取相应的事件提醒。一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。

我们依然使用刚才的4台虚拟机,外加一个哨兵做裁决

1
2
3
4
5
6
7
[root@bogon utils]# ps -ef|grep redis
root 1082 1 0 15:19 ? 00:00:01 /usr/local/bin/redis-server 0.0.0.0:7380
root 1083 1 0 15:19 ? 00:00:01 /usr/local/bin/redis-server 0.0.0.0:7381
root 1084 1 0 15:19 ? 00:00:01 /usr/local/bin/redis-server 0.0.0.0:7382
root 1085 1 0 15:19 ? 00:00:01 /usr/local/bin/redis-server 0.0.0.0:7379
root 1669 1 0 15:45 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7383
root 1674 1525 0 15:45 pts/0 00:00:00 grep --color=auto redis

看好了

节点 ip 端口 身份
01 192.168.50.56 7379
02 192.168.50.56 7380
03 192.168.50.56 7381
04 192.168.50.56 7382
05 192.168.50.56 26379 哨兵

建立主从

保持刚才的主从不变,建议先验证下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 主节点 192.168.56.109
[root@bogon thinktik]# redis-cli -p 7379
127.0.0.1:7379> AUTH myPassword
OK
127.0.0.1:7379> info Replication
# Replication
role:master
connected_slaves:3
slave0:ip=192.168.50.56,port=7380,state=online,offset=364,lag=1
slave1:ip=192.168.50.56,port=7381,state=online,offset=364,lag=1
slave2:ip=192.168.50.56,port=7382,state=online,offset=364,lag=0
master_replid:6833b4d58f8eed0eb4e9403454491457cbd5fa9d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:364
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:364


#从节点192.168.56.110
[root@bogon thinktik]# redis-cli -p 7380
127.0.0.1:7380> AUTH myPassword
OK
127.0.0.1:7380> info Replication
# Replication
role:slave
master_host:192.168.50.56
master_port:7379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:406
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:6833b4d58f8eed0eb4e9403454491457cbd5fa9d
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:406
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:406

修改配置

注意:建议我们设置的时候把这三台配置保持不变,哨兵模式仅仅是在主从上面加了哨兵

主机7379

1
2
3
4
5
6
7
# 修改或者参照配置文件,这些配置以下面的为准,在主从配置下修改如下:
[root@localhost redis-4.0.11]# vi /etc/redis/7379.conf

timeout 30 //Client 端空闲断开连接的时间
daemonize yes //把值修改为yes,以后台模式运行
appendonly yes //默认值是No,意思是不使用AOF增量持久化的方式,使用RDB全量持久化的方式。把No值改成Yes,使用AOF增量持久化的方式
appendfsync always

从机: 7380,7381,7382

1
2
3
4
5
6
7
# 修改或者参照配置文件,这些配置以下面的为准 在主从配置下修改如下:
[root@localhost redis-4.0.11]# vi /etc/redis/7379.conf
timeout 30 //Client 端空闲断开连接的时间
daemonize yes //把值修改为yes,以后台模式运行
slave-serve-stale-data no //可以不改,默认为yes。 如果slave无法与master同步,设置成slave不可读,方便监控脚本发现问题。
appendonly yes //默认值是No,意思是不使用AOF增量持久化的方式,使用RDB全量持久化的方式。把No值改成Yes,使用AOF增量持久化的方式
appendfsync always

哨兵: 26379

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 哨兵配置文件模板在安装源代码文件下
[root@bogon redis-5.0.2]# pwd
/home/thinktik/redis-5.0.2
[root@bogon redis-5.0.2]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
# 修改哨兵配置文件
[root@bogon redis-5.0.2]# vim sentinel.conf

# sentinel监听端口,默认是26379
port 26379 # 哨兵端口号保持不变,可以修改,但是我没有修改
# 告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效。我们是一个sentinel就写1
sentinel monitor mymaster 192.168.50.56 7379 1
# 指定主机的密码,如果你没有设置主机的密码可以不写,设置了就要加上。建议主机和从机的密码都搞成一样的,方便配置管理
sentinel auth-pass mymaster myPassword
#这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒
sentinel down-after-milliseconds mymaster 5000
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长
sentinel parallel-syncs mymaster 1
# 当进行failover时,配置所有slaves指向新的master所需的最大时间:
sentinel failover-timeout mymaster 20000

加入哨兵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 先将原来的一主三从全部重启下,重启后验证它们是否还是自动加入了一组三从,是的话继续下一步
# 3个节点都要
[root@bogon redis-5.0.2]# systemctl restart redis_7379

#对哨兵所在的服务器进行操作

# 注意sentinel.conf其实是在redis安装包下,并不是在在/etc/redis/下面与/etc/redis/7379.conf同目录。
[root@bogon redis-5.0.2]# pwd
/home/thinktik/redis-5.0.2

# 修改上面哨兵指令的配置文件并保存
[root@bogon redis-5.0.2]# vi sentinel.conf
# 开启哨兵 指定以哨兵配置文件启动
[root@bogon redis-5.0.2]# redis-server sentinel.conf --sentinel
2095:X 25 Nov 2018 17:10:15.984 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2095:X 25 Nov 2018 17:10:15.984 # Redis version=5.0.2, bits=64, commit=00000000, modified=0, pid=2095, just started
2095:X 25 Nov 2018 17:10:15.984 # Configuration loaded
2095:X 25 Nov 2018 17:10:15.984 * Increased maximum number of open files to 10032 (it was originally set to 1024).
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.2 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 26379
| `-._ `._ / _.-' | PID: 2095
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

2095:X 25 Nov 2018 17:10:15.985 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2095:X 25 Nov 2018 17:10:15.985 # Sentinel ID is 56e4a141b733671d4cceb3e357e59fd0c5f6ede7
2095:X 25 Nov 2018 17:10:15.985 # +monitor master mymaster 192.168.50.56 7379 quorum 1
2095:X 25 Nov 2018 17:10:15.988 * +slave slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:10:16.332 * +slave slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:10:16.337 * +slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7379
#上面这样就可以了,上面哨兵报告已经发现了主节点和三个从节点


# 我们也可以再次查看哨兵配置文件来验证哨兵是否正常,redis哨兵在后面自己加上了三个从节点的信息
[root@localhost redis-4.0.11]# vi sentinel.conf

# SENTINEL rename-command mymaster CONFIG CONFIG
# Generated by CONFIG REWRITE

sentinel known-replica mymaster 192.168.50.56 7381
sentinel known-replica mymaster 192.168.50.56 7382
sentinel known-replica mymaster 192.168.50.56 7380

# 到这里哨兵就设置完成了

模拟哨兵功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 关闭主节点,等待哨兵反应
[root@bogon redis-5.0.2]# redis-cli -a myPassword -p 7379 shutdown
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

#哨兵出现这些日志,表示主节点失效
2095:X 25 Nov 2018 17:15:11.032 # +sdown master mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.032 # +odown master mymaster 192.168.50.56 7379 #quorum 1/1
2095:X 25 Nov 2018 17:15:11.032 # +new-epoch 8
2095:X 25 Nov 2018 17:15:11.032 # +try-failover master mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.037 # +vote-for-leader 56e4a141b733671d4cceb3e357e59fd0c5f6ede7 8
2095:X 25 Nov 2018 17:15:11.037 # +elected-leader master mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.037 # +failover-state-select-slave master mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.100 # +selected-slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.100 * +failover-state-send-slaveof-noone slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.158 * +failover-state-wait-promotion slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.227 # +promoted-slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.227 # +failover-state-reconf-slaves master mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:11.280 * +slave-reconf-sent slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:12.269 * +slave-reconf-inprog slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:12.269 * +slave-reconf-done slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:12.331 * +slave-reconf-sent slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:13.311 * +slave-reconf-inprog slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:13.311 * +slave-reconf-done slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7379
2095:X 25 Nov 2018 17:15:13.393 # +failover-end master mymaster 192.168.50.56 7379
#哨兵出现这些日志,表示主节点失效,切换了主从关系 由7379 到了7380
2095:X 25 Nov 2018 17:15:13.393 # +switch-master mymaster 192.168.50.56 7379 192.168.50.56 7380
2095:X 25 Nov 2018 17:15:13.393 * +slave slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:15:13.393 * +slave slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:15:13.393 * +slave slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:15:43.399 # +sdown slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7380



# 我们继续关闭新的主节点
[root@bogon redis-5.0.2]# redis-cli -a myPassword -p 7380 shutdown
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.


# 最后一个redis节点成了主节点
# 我们在启动刚才关了的2个节点

# 哨兵出现这些日志,表示主节点7380失效
2095:X 25 Nov 2018 17:17:34.457 # +sdown master mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.457 # +odown master mymaster 192.168.50.56 7380 #quorum 1/1
2095:X 25 Nov 2018 17:17:34.457 # +new-epoch 9
2095:X 25 Nov 2018 17:17:34.457 # +try-failover master mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.465 # +vote-for-leader 56e4a141b733671d4cceb3e357e59fd0c5f6ede7 9
2095:X 25 Nov 2018 17:17:34.465 # +elected-leader master mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.465 # +failover-state-select-slave master mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.518 # +selected-slave slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.518 * +failover-state-send-slaveof-noone slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:34.577 * +failover-state-wait-promotion slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:35.490 # +promoted-slave slave 192.168.50.56:7382 192.168.50.56 7382 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:35.491 # +failover-state-reconf-slaves master mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:35.555 * +slave-reconf-sent slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:36.518 * +slave-reconf-inprog slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:36.518 * +slave-reconf-done slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7380
2095:X 25 Nov 2018 17:17:36.569 # +failover-end master mymaster 192.168.50.56 7380
#哨兵出现这些日志,表示主节点失效,切换了主从关系 由7380 到了7382
2095:X 25 Nov 2018 17:17:36.569 # +switch-master mymaster 192.168.50.56 7380 192.168.50.56 7382
2095:X 25 Nov 2018 17:17:36.569 * +slave slave 192.168.50.56:7381 192.168.50.56 7381 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:17:36.569 * +slave slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:17:36.569 * +slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:18:06.575 # +sdown slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:18:06.575 # +sdown slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382

# 再次启动这两个被关的节点,看他们是不是可以再加入进来主从
[root@bogon redis-5.0.2]# systemctl restart redis_7380
[root@bogon redis-5.0.2]# systemctl restart redis_7379


# 刚才被关了的2个节点被加入了进来,并由主节点变成了从节点,当前主节点不变
2095:X 25 Nov 2018 17:17:36.569 * +slave slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:17:36.569 * +slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:18:06.575 # +sdown slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:18:06.575 # +sdown slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382

2095:X 25 Nov 2018 17:22:47.562 # -sdown slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:22:57.545 * +convert-to-slave slave 192.168.50.56:7379 192.168.50.56 7379 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:23:34.184 # -sdown slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382
2095:X 25 Nov 2018 17:23:44.157 * +convert-to-slave slave 192.168.50.56:7380 192.168.50.56 7380 @ mymaster 192.168.50.56 7382

到这里哨兵模式就完成了

高可用方案集群搭建

redis5 是一次很大的功能更新,它添加了很多实用的功能。对我看来两项功能最有用,第一是redis的新的流数据类型(Stream data type),第二就是redis-cli中的集群管理器从 Ruby (redis-trib.rb) 移植到了 C 语言代码。第二个新的改进是我写这篇文章的主要原因,因为上一篇文章是redis4的linux安装教程,里面介绍了单机,主从,哨兵模式的搭建,而redis集群当时我没有写的原因是我对ruby不了解而且redis4的集群感觉不是很好搭建。redis5的出现,集群模式变得高效而且简单起来,我于是参考redis官方的是说明进行了这个尝试。

具体哪些新功能可以看 Redis 5.0 正式发布!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# 单机安装和redis4完全没区别
# 下载redis安装文件到linux主机上 解压
# 进入解压后的目录
# 编译
[thinktik@thinkcent redis-5.0.0]$ make

# 编译完成后出现提示,建议我们make test 进行测试
LINK redis-benchmark
INSTALL redis-check-rdb
INSTALL redis-check-aof

Hint: It's a good idea to run 'make test' ;)

make[1]: Leaving directory `/home/thinktik/install/redis-4.0.10/src'

# 测试
[thinktik@thinkcent redis-5.0.0]$ make test

....

289 seconds - unit/memefficiency
416 seconds - integration/replication

# 安装测试通过
\o/ All tests passed without errors!

Cleanup: may take some time... OK
make[1]: Leaving directory `/home/thinktik/redis-5.0.0/src'

# 安装
[root@bogon redis-5.0.0]# make install
cd src && make install
make[1]: Entering directory `/home/thinktik/redis-5.0.0/src'

Hint: It's a good idea to run 'make test' ;)

INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/home/thinktik/redis-5.0.0/src'
# 安装成功了看下文件有哪些
[root@bogon redis-5.0.0]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
[root@bogon redis-5.0.0]# cd utils/
[root@bogon utils]# ls
build-static-symbols.tcl graphs redis-copy.rb speed-regression.tcl
cluster_fail_time.tcl hashtable redis_init_script whatisdoing.sh
corrupt_rdb.c hyperloglog redis_init_script.tpl
create-cluster install_server.sh redis-sha1.rb
generate-command-help.rb lru releasetools
# 老套路,我们启动redis 01 端口7379
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7379

...

Installation successful!
# 老套路,我们启动redis 02 端口7380
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7380

...

Installation successful!
# 老套路,我们启动redis 03 端口7381
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7381

...

Starting Redis server...
Installation successful!
# 老套路,我们启动redis 04 端口7382
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7382

...

Starting Redis server...
Installation successful!
# 老套路,我们启动redis 05 端口7383
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7383

...

Starting Redis server...
Installation successful!

# 老套路,我们启动redis 06 端口7384
[root@bogon utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 7384

...

Starting Redis server...
Installation successful!

这里redis5就有了6个节点了,和上一篇文章区别在于上一篇是3个独立虚拟机分别安装3个reids,这一次是一台主机上安装6个监听端口不同的redis尝试组成伪集群。这两种也没什么区别,看你自己的喜好,真集群和伪集群步骤完全一致。

redis5节点编号 端口
01 7379
02 7380
03 7381
04 7382
05 7383
06 7384

这里一起是6个,看好了。

1
2
3
4
5
6
7
8
[root@bogon utils]# ps -ef | grep redis
root 29662 1 0 23:24 ? 00:00:02 /usr/local/bin/redis-server 127.0.0.1:7379
root 29731 1 0 23:25 ? 00:00:02 /usr/local/bin/redis-server 127.0.0.1:7380
root 29800 1 0 23:25 ? 00:00:02 /usr/local/bin/redis-server 127.0.0.1:7381
root 29869 1 0 23:25 ? 00:00:02 /usr/local/bin/redis-server 127.0.0.1:7382
root 29950 1 0 23:52 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7383
root 29953 1 0 23:52 ? 00:00:00 /usr/local/bin/redis-server 127.0.0.1:7384
root 29955 9349 0 23:52 pts/0 00:00:00 grep --color=auto redis

进入正题

redis 高可用集群方案

尽管可以使用哨兵主从集群实现可用性保证,但是这种实现方式每个节点的数据都是全量复制,数据存放量存在着局限性,受限于内存最小的节点,因此考虑采用数据分片的方式,来实现存储,这个就是redis-cluster。

这里我们修改下6个节点的配配置

1
2
3
4
5
6
7
8
[root@bogon utils]# vim /etc/redis/7379.conf

# 修改这3个
cluster-enabled yes # 打开集群模式
cluster-config-file nodes-7379.conf # 设置唯一的配置文件 建议编号和端口一致就可以了,6个不能重复
cluster-node-timeout 15000 # 集群节点连接超时
# 改完重启
[root@bogon utils]# systemctl restart redis_7379

注意,6个都要改,配置文件是/etc/redis/xxxx.conf 其中xxxx是你的端口,改完每个节点服务都重启不然不行的。6个节点都改完并且重启后往下面看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 将6个节点带入命令中,指定1:1的复制。--replicas N 选项表明集群中的每个节点带几个从节点 我这里是1,也就是1主1从共3对组成合计3主3从的集群
[root@bogon utils]# redis-cli --cluster create 127.0.0.1:7379 127.0.0.1:7380 127.0.0.1:7381 127.0.0.1:7382 127.0.0.1:7383 127.0.0.1:7384 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:7382 to 127.0.0.1:7379
Adding replica 127.0.0.1:7383 to 127.0.0.1:7380
Adding replica 127.0.0.1:7384 to 127.0.0.1:7381

# 这里是警告 提示主从都在一台主机上,不管它,我这里是一台主机上的伪集群,它警告有道理的,实际的集群不会出现这个。
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 2aaf18275ca23ef6f71bcd7a75ae8e347056f245 127.0.0.1:7379
slots:[0-5460] (5461 slots) master
M: 3771f62dba7b15b092efbb3b2598e385059d39a8 127.0.0.1:7380
slots:[5461-10922] (5462 slots) master
M: 3435d586118de9800667a4900f6f5682c2135a99 127.0.0.1:7381
slots:[10923-16383] (5461 slots) master
S: 3b2b6ef26bb71a38b9c21d17e7c2a66c925ceb9d 127.0.0.1:7382
replicates 3771f62dba7b15b092efbb3b2598e385059d39a8
S: 8c684a500412eba7d3d38b611dcf0444704fc572 127.0.0.1:7383
replicates 3435d586118de9800667a4900f6f5682c2135a99
S: e0348812da63e1c7dcabe02541b38276b1eca7e1 127.0.0.1:7384
replicates 2aaf18275ca23ef6f71bcd7a75ae8e347056f245

# 要我对上面的警告和配置信息进行确认 我输入yes.
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 127.0.0.1:7379)
M: 2aaf18275ca23ef6f71bcd7a75ae8e347056f245 127.0.0.1:7379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 3771f62dba7b15b092efbb3b2598e385059d39a8 127.0.0.1:7380
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 3b2b6ef26bb71a38b9c21d17e7c2a66c925ceb9d 127.0.0.1:7382
slots: (0 slots) slave
replicates 3771f62dba7b15b092efbb3b2598e385059d39a8
S: 8c684a500412eba7d3d38b611dcf0444704fc572 127.0.0.1:7383
slots: (0 slots) slave
replicates 3435d586118de9800667a4900f6f5682c2135a99
S: e0348812da63e1c7dcabe02541b38276b1eca7e1 127.0.0.1:7384
slots: (0 slots) slave
replicates 2aaf18275ca23ef6f71bcd7a75ae8e347056f245
M: 3435d586118de9800667a4900f6f5682c2135a99 127.0.0.1:7381
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

# 到这里就好了,ok!!!

# 看下效果 6个节点都入了集群
[root@bogon utils]# ps aux|grep redis
root 30053 0.1 0.4 156432 8504 ? Ssl 00:22 0:01 /usr/local/bin/redis-server 127.0.0.1:7383 [cluster]
root 30086 0.1 0.5 159504 10056 ? Ssl 00:23 0:01 /usr/local/bin/redis-server 127.0.0.1:7382 [cluster]
root 30107 0.1 0.6 162576 12180 ? Ssl 00:25 0:01 /usr/local/bin/redis-server 127.0.0.1:7380 [cluster]
root 30125 0.1 0.4 156432 8188 ? Ssl 00:25 0:01 /usr/local/bin/redis-server 127.0.0.1:7381 [cluster]
root 30245 0.1 0.7 165648 13792 ? Ssl 00:27 0:00 /usr/local/bin/redis-server 127.0.0.1:7379 [cluster]
root 30297 0.1 0.4 156432 8508 ? Ssl 00:29 0:00 /usr/local/bin/redis-server 127.0.0.1:7384 [cluster]
root 30315 0.0 0.0 112704 972 pts/0 R+ 00:37 0:00 grep --color=auto redis

验证下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 进入其中一个节点
[root@bogon utils]# redis-cli -p 7379
# 查看集群状况 3主3从没毛病
127.0.0.1:7379> cluster nodes
3771f62dba7b15b092efbb3b2598e385059d39a8 127.0.0.1:7380@17380 master - 0 1542904731993 2 connected 5461-10922
3b2b6ef26bb71a38b9c21d17e7c2a66c925ceb9d 127.0.0.1:7382@17382 slave 3771f62dba7b15b092efbb3b2598e385059d39a8 0 1542904731000 4 connected
8c684a500412eba7d3d38b611dcf0444704fc572 127.0.0.1:7383@17383 slave 3435d586118de9800667a4900f6f5682c2135a99 0 1542904730000 5 connected
e0348812da63e1c7dcabe02541b38276b1eca7e1 127.0.0.1:7384@17384 slave 2aaf18275ca23ef6f71bcd7a75ae8e347056f245 0 1542904730989 6 connected
2aaf18275ca23ef6f71bcd7a75ae8e347056f245 127.0.0.1:7379@17379 myself,master - 0 1542904728000 1 connected 0-5460
3435d586118de9800667a4900f6f5682c2135a99 127.0.0.1:7381@17381 master - 0 1542904730000 3 connected 10923-16383
127.0.0.1:7379> set thinktik no.1
(error) MOVED 12578 127.0.0.1:7381
127.0.0.1:7379> set thinktik no.1
(error) MOVED 12578 127.0.0.1:7381
127.0.0.1:7379> get thinktik
(error) MOVED 12578 127.0.0.1:7381
127.0.0.1:7379> set foo no.2
(error) MOVED 12182 127.0.0.1:7381
127.0.0.1:7379> set foo1 no.2
(error) MOVED 13431 127.0.0.1:7381
127.0.0.1:7379> set foo2 no.2
OK
127.0.0.1:7379> get foo2
"no.2"
127.0.0.1:7379>
[root@bogon utils]# redis-cli -p 7380
127.0.0.1:7380> get foo2
(error) MOVED 1044 127.0.0.1:7379
127.0.0.1:7380>

这里使用时出现error不是集群的问题,这里涉及到redis集群的知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 加上 -c 以集群模式启动客户端,再次尝试 ok
[root@bogon utils]# redis-cli -c -p 7380
127.0.0.1:7380> cluster nodes
e0348812da63e1c7dcabe02541b38276b1eca7e1 127.0.0.1:7384@17384 slave 2aaf18275ca23ef6f71bcd7a75ae8e347056f245 0 1542906011000 1 connected
3771f62dba7b15b092efbb3b2598e385059d39a8 127.0.0.1:7380@17380 myself,master - 0 1542906009000 2 connected 5461-10922
3435d586118de9800667a4900f6f5682c2135a99 127.0.0.1:7381@17381 master - 0 1542906010851 3 connected 10923-16383
8c684a500412eba7d3d38b611dcf0444704fc572 127.0.0.1:7383@17383 slave 3435d586118de9800667a4900f6f5682c2135a99 0 1542906011858 5 connected
2aaf18275ca23ef6f71bcd7a75ae8e347056f245 127.0.0.1:7379@17379 master - 0 1542906010000 1 connected 0-5460
3b2b6ef26bb71a38b9c21d17e7c2a66c925ceb9d 127.0.0.1:7382@17382 slave 3771f62dba7b15b092efbb3b2598e385059d39a8 0 1542906010000 4 connected
127.0.0.1:7380> get foo2
-> Redirected to slot [1044] located at 127.0.0.1:7379
"no.2"
127.0.0.1:7379> set foo1 no.2
-> Redirected to slot [13431] located at 127.0.0.1:7381
OK
127.0.0.1:7381> set foo1 no.2
OK
127.0.0.1:7381> get foo1 no.2
(error) ERR wrong number of arguments for 'get' command
127.0.0.1:7381> get foo1
"no.2"
节点 监听口 集群通信口 分片 槽位 被连接数 是否是master 所属主节点ID
01 7379 17379 1 0-5460 1 Y -
02 7380 17380 2 5461-10922 2 Y -
03 7381 17381 3 10923-16383 3 Y -
04 7382 17382 3 10923-16383 4 N 7379的ID: ..39a8
05 7383 17383 3 10923-16383 5 N 7381的ID: ..5a99
06 7384 17384 3 10923-16383 1 N 7380的ID: ..f245

Redis的集群模型和MySQL的是有本质区别的,不能一概而论。Redis的哨兵模式,集群模式在极端网络情况下可能出现脑裂,这个我分析后明确的表示:脑裂是绝对存在的,但是相对不可能。Redis官方也给了说明不保证绝对的一致性。

Redis Cluster is not able to guarantee strong consistency. In practical terms this means that under certain conditions it is possible that Redis Cluster will lose writes that were acknowledged by the system to the client.

CAP定理,脑裂,官方说明参考如下: