[实验] Redis 数据库集群的搭建

纪念:站主于 2019 年 11 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

软件准备:

在 Redis 的官网上下载软件 Redis:

https://redis.io

在 rubygems 的官网上下载软件 rubygems

https://rubygems.org

正文:

步骤一:规划拓扑

1.1 服务器列表

redis1 IP 地址:192.168.1.51 端口号:1051
redis2 IP 地址:192.168.1.52 端口号:1052
redis3 IP 地址:192.168.1.53 端口号:1053
redis4 IP 地址:192.168.1.54 端口号:1054
redis5 IP 地址:192.168.1.55 端口号:1055
redis6 IP 地址:192.168.1.56 端口号:1056

1.2 服务器列表简介

1) 总共 6 个数据库,3 个为主库,3 个为从库
2) 如果 1 个主库宕掉则它的从库自动成为主库
3) 宕掉的主库修复好后会成为新主库的从库
4) 如果半数或者半数以上的主库宕掉,集群则无法使用

(注意: Redis 集群最少要有 3 个主库)

步骤二:系统环境要求

1) 所有服务器的系统都需要是 CentOS 7 版本
2) 所有服务器都要关闭防火墙
3) 所有服务器都要关闭 SELinux
4) 所有服务器系统都要配置好可用的软件源
5) 需要按照拓扑图给对应的服务器配置好 IP 地址和主机名
6) 所有服务器都要可以相互 ping 通自己和对方的 IP 地址和主机名
7) 至少要有一台服务器可以访问外网

步骤三:所有数据库服务器安装 Redis 数据库

3.1 安装 Redis 数据库的相关依赖包

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# yum -y install gcc gcc-c++ make

3.2 安装 Redis 数据库

3.2.1 解压安装包

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# tar -zxf redis-5.0.5.tar.gz

(补充:这里要安装的 Redis 版本是 5.0.5)

3.2.2 进入安装包目录

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# cd redis-5.0.5/

(补充:这里要安装的 Redis 版本是 5.0.5)

3.2.3 编译安装包

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# make
3.2.4 安装软件包
(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)
# make install
3.2.5 进入配置目录
(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)
# cd utils/
3.2.6 配置软件包

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# ./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] 
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] 
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
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/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

步骤四:搭建 Redis 数据库集群

4.1 修改所有服务器上的 Redis 数据库配置文件

(只在 redis1 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.51
......
port 1051
......
daemonize yes
......
pidfile /var/run/redis_1051.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1051.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.51 是本机的 IP 地址
3) 这里的 port 1051 代表数据库使用到的端口是 1051,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1051.pid 代表使用的 PID 文件是 /var/run/redis_1051.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1051.conf 代表使用的数据库配置文件是 nodes-1051.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

(只在 redis2 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.52
......
port 1052
......
daemonize yes
......
pidfile /var/run/redis_1052.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1052.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.52 是本机的 IP 地址
3) 这里的 port 1052 代表数据库使用到的端口是 1052,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1052.pid 代表使用的 PID 文件是 /var/run/redis_1052.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1052.conf 代表使用的数据库配置文件是 nodes-1052.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

(只在 redis3 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.53
......
port 1053
......
daemonize yes
......
pidfile /var/run/redis_1053.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1053.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.53 是本机的 IP 地址
3) 这里的 port 1053 代表数据库使用到的端口是 1053,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1053.pid 代表使用的 PID 文件是 /var/run/redis_1053.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1053.conf 代表使用的数据库配置文件是 nodes-1053.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

(只在 redis4 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.54
......
port 1054
......
daemonize yes
......
pidfile /var/run/redis_1054.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1054.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.54 是本机的 IP 地址
3) 这里的 port 1054 代表数据库使用到的端口是 1054,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1054.pid 代表使用的 PID 文件是 /var/run/redis_1054.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1054.conf 代表使用的数据库配置文件是 nodes-1054.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

(只在 redis5 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.55
......
port 1055
......
daemonize yes
......
pidfile /var/run/redis_1055.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1055.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.55 是本机的 IP 地址
3) 这里的 port 1055 代表数据库使用到的端口是 1055,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1055.pid 代表使用的 PID 文件是 /var/run/redis_1055.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1055.conf 代表使用的数据库配置文件是 nodes-1055.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

(只在 redis6 上执行以下步骤)

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.56
......
port 1056
......
daemonize yes
......
pidfile /var/run/redis_1056.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1056.conf
......
cluster-node-timeout 5000
......


补充:
1) 这里的 #bind 127.0.0.1 代表取消数据库可以被本地登录
2) 这里的 bind 192.168.1.56 是本机的 IP 地址
3) 这里的 port 1056 代表数据库使用到的端口是 1056,集群里的各个数据库端口号不能一样
4) 这里的 daemonize yes 代表以进程的形式启动
5) 这里的 pidfile /var/run/redis_1056.pid 代表使用的 PID 文件是 /var/run/redis_1056.pid,集群里的各个数据库 PID 文件不能一样
6) 这里的 cluster-enabled yes 代表启用集群,但是前面的 daemonize 必须也启用
7) 这里的 cluster-config-file nodes-1056.conf 代表使用的数据库配置文件是 nodes-1056.conf,集群里的各个数据库的配置文件不能一样
8) 这里的 cluster-node-timeout 5000 代表集群通信超时时间为 5000

4.2 重启所有服务器上的 Redis 数据库

4.2.1 关闭 Redis 数据库

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# redis-cli shutdown
4.2.2 开启 Redis 数据库

(分别在 redis1、redis2、redis3、redis4、redis5 和 redis6 上执行以下步骤)

# /etc/init.d/redis_6379 start

4.3 显示目前的集群信息

(此步骤可以在任意服务器上操作,这里以在 redis1 上操作为例)

4.3.1 进入数据库

(只在 redis1 上执行以下步骤)

# redis-cli -h 192.168.1.51 -p 1051
4.3.2 显示数据库是否可用

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> ping
PONG
4.3.3 显示集群信息

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> cluster info
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:0
cluster_current_epoch:0
cluster_my_epoch:0
cluster_stats_messages_sent:0
cluster_stats_messages_received:0

4.4 部署 Redis 集群环境

4.4.1 部署 Ruby 脚本运行环境

(此步骤可以在任意服务器上操作,但是这台服务器必须要可以访问外网,这里以在 redisA 上操作为例)

4.4.1.1 安装 Ruby

(只在 redis1 上执行以下步骤)

# yum -y install ruby rubygems ruby-devel
4.4.1.2 升级 Ruby
4.4.1.2.1 解压 Ruby 安装包

(只在 redis1 上执行以下步骤)

# tar -xvf rubygems-3.0.6.tgz 

(补充:这里要安装的 rubygems 版本是 3.0.6)

4.4.1.2.2 进入 Ruby 安装包目录

(只在 redis1 上执行以下步骤)

# cd rubygems-3.0.6

(补充:这里要安装的 rubygems 版本是 3.0.6)

4.4.1.2.3 升级 Ruby

(只在 redis1 上执行以下步骤)

# ruby setup.rb
4.4.1.3 安装 Redis 模块

(只在 redis1 上执行以下步骤)

# gem install redis -v 3.3.5
Fetching: redis-3.3.5.gem (100%)
Successfully installed redis-3.3.5
Parsing documentation for redis-3.3.5
Installing ri documentation for redis-3.3.5
1 gem installed
4.4.2 部署 Redis 集群文件
4.4.2.1 创建 Redis 集群文件的目录

(只在 redis1 上执行以下步骤)

# mkdir /root/bin
4.4.2.2 复制 Redis 集群文件

(只在 redis1 上执行以下步骤)

# cp redis-5.0.5/src/redis-trib.rb /root/bin
4.4.2.3 给 Redis 集群文件添加执行权限

(只在 redis1 上执行以下步骤)

# chmod +x /root/bin/redis-trib.rb

4.5 创建 Redis 集群

(只在 redis1 上执行以下步骤)

# redis-cli --cluster create 192.168.1.51:1051 192.168.1.52:1052 192.168.1.53:1053 192.168.1.54:1054 192.168.1.55:1055 192.168.1.56:1056 --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 192.168.1.55:1055 to 192.168.1.51:1051
Adding replica 192.168.1.56:1056 to 192.168.1.52:1052
Adding replica 192.168.1.54:1054 to 192.168.1.53:1053
M: 5d030ec05f9de86ebeedc1b035b2122addaa61d8 192.168.1.51:1051
   slots:[0-5460] (5461 slots) master
M: 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052
   slots:[5461-10922] (5462 slots) master
M: c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053
   slots:[10923-16383] (5461 slots) master
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
S: eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055
   replicates 5d030ec05f9de86ebeedc1b035b2122addaa61d8
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
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 192.168.1.51:1051)
M: 5d030ec05f9de86ebeedc1b035b2122addaa61d8 192.168.1.51:1051
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055
   slots: (0 slots) slave
   replicates 5d030ec05f9de86ebeedc1b035b2122addaa61d8
M: c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   slots: (0 slots) slave
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   slots: (0 slots) slave
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

4.6 显示集群中主机状态信息的方法

4.6.1 方法一
4.6.1.1 进入数据库

(只在 redis1 上执行以下步骤)

# redis-cli -h 192.168.1.51 -p 1051
4.6.1.2 显示集群整体信息

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:30858
cluster_stats_messages_pong_sent:29942
cluster_stats_messages_sent:60800
cluster_stats_messages_ping_received:29937
cluster_stats_messages_pong_received:30858
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:60800
4.6.1.3 显示集群主从关系

(只在 redis1 上执行以下步骤)

192.168.1.53:1053> cluster nodes
eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055@11055 slave 5d030ec05f9de86ebeedc1b035b2122addaa61d8 0 1574754846521 5 connected
a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054@11054 slave c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 0 1574754846000 4 connected
fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056@11056 slave 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 0 1574754845819 6 connected
5d030ec05f9de86ebeedc1b035b2122addaa61d8 192.168.1.51:1051@11051 master - 0 1574754846822 1 connected 0-5460
7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052@11052 master - 0 1574754846000 2 connected 5461-10922
c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053@11053 myself,master - 0 1574754844000 3 connected 10923-16383
4.6.1.4 退出数据库

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> quit
4.6.2 方法二
4.6.2.1 显示集群整体信息

(只在 redis1 上执行以下步骤)

# redis-cli --cluster info 192.168.1.51 1051
192.168.1.51:1051 (5d030ec0...) -> 1 keys | 5461 slots | 1 slaves.
192.168.1.53:1053 (c4f884e7...) -> 1 keys | 5461 slots | 1 slaves.
192.168.1.52:1052 (7477c04d...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 3 keys in 3 masters.
0.00 keys per slot on average.
4.6.2.2 显示集群主从关系

(只在 redis1 上执行以下步骤)

# redis-cli --cluster check 192.168.1.51 1051
192.168.1.51:1051 (5d030ec0...) -> 1 keys | 5461 slots | 1 slaves.
192.168.1.53:1053 (c4f884e7...) -> 1 keys | 5461 slots | 1 slaves.
192.168.1.52:1052 (7477c04d...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 3 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.1.51:1051)
M: 5d030ec05f9de86ebeedc1b035b2122addaa61d8 192.168.1.51:1051
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055
   slots: (0 slots) slave
   replicates 5d030ec05f9de86ebeedc1b035b2122addaa61d8
M: c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   slots: (0 slots) slave
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   slots: (0 slots) slave
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

步骤五:Redis 集群创建失败的解决办法

5.1 关闭所有 Redis服务器的 Redis 服务

(只在加入集群失败的服务器上执行以下步骤)

# redis-cli -h <IP address of this server> -p <port number used by redis of this server> shutdowm

5.2 删除所有原来的 Redis 数据

(只在加入集群失败的服务器上执行以下步骤)

# rm -rf /var/lib/redis/6379/*

5.3 重启 Redis 数据库

(只在加入集群失败的服务器上执行以下步骤)

# /etc/init.d/redis_6379 start

5.4 按照前面的步骤重新执行创建集群

(只在加入集群失败的服务器上执行以下步骤)

(步骤略)

步骤六:测试 Redis 集群

6.1 数据同步测试

6.1.1 进入数据库

(只在 redis1 上执行以下步骤)

# redis-cli -h 192.168.1.51 -p 1051

(只在 redis2 上执行以下步骤)

# redis-cli -h 192.168.1.52 -p 1052

(只在 redis3 上执行以下步骤)

# redis-cli -h 192.168.1.53 -p 1053

(只在 redis4 上执行以下步骤)

# redis-cli -h 192.168.1.54 -p 1054

(只在 redis5 上执行以下步骤)

# redis-cli -h 192.168.1.55 -p 1055

(只在 redis6 上执行以下步骤)

# redis-cli -h 192.168.1.56 -p 1056
6.1.2 确认现在的 Redis 数据库都是空的

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> keys *

(只在 redis2 上执行以下步骤)

192.168.1.51:1052> keys *

(只在 redis3 上执行以下步骤)

192.168.1.51:1053> keys *

(只在 redis4 上执行以下步骤)

192.168.1.51:1054> keys *

(只在 redis5 上执行以下步骤)

192.168.1.51:1055> keys *

(只在 redis6 上执行以下步骤)

192.168.1.51:1056> keys *
6.1.3 在主 Redis 数据库上插入数据

(补充:本次的主数据库是 redis1、redis2、redis3)

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> set aa 101
-> Redirected to slot [15495] located at 192.168.1.53:1053
OK

(只在 redis2 上执行以下步骤)

192.168.1.52:1052> set bb 102
-> Redirected to slot [3300] located at 192.168.1.51:1051
OK

(只在 redis3 上执行以下步骤)

192.168.1.53:1053> set ff 103
-> Redirected to slot [7365] located at 192.168.1.52:1052
OK
6.1.4 查看刚插入的数据

(只在 redis1 上执行以下步骤)

192.168.1.51:1051> keys *
1) "aa"

(只在 redis2 上执行以下步骤)

192.168.1.51:1052> keys *
1) "bb"

(只在 redis3 上执行以下步骤)

192.168.1.51:1053> keys *
1) "ff"

(只在 redis4 上执行以下步骤)

192.168.1.51:1054> keys *
1) "ff"

(只在 redis5 上执行以下步骤)

192.168.1.51:1055> keys *
1) "aa"

(只在 redis6 上执行以下步骤)

192.168.1.51:1056> keys *
1) "bb"


补充:
1) 对应的从库会自动同步主库的数据
2) 本次的主数据库是 redis1(从库是 redis5)、redis2(从库是 redis6)、redis3(从库是 redis4)
)

6.2 高可用测试

6.2.1 模拟此时主库宕机后,对应的从库会自动升级为主库但需要 5 分钟的时间

(只在模拟宕机的主库服务器上执行以下步骤)

# redis-cli -h <IP address of this server> -p <port number used by redis of this server> shutdown
6.2.2 等待 5 分钟后显示集群主从关系

(只在 redis1 上执行以下步骤)

# redis-cli --cluster check 192.168.1.51 1051
6.2.3 主库恢复后会成为新主库的从库

(只在模拟宕机的主库服务器上执行以下步骤)

# /etc/init.d/redis_6379 start
6.2.4 再次显示集群主从关系

(只在 redis1 上执行以下步骤)

# redis-cli --cluster check 192.168.1.51 1051

[实验] MariaDB & MySQL 主从同步的搭建 (互为主从)

纪念:站主于 2019 年 11 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

步骤一:规划拓扑

1.1 服务器列表

数据库服务器 21 IP 地址:192.168.1.21
数据库服务器 22 IP 地址:192.168.1.22

1.2 服务器列表简介

数据库服务器 21 和 数据库服务器 22 相互同步对方的数据

步骤二:系统环境要求

1) 所有服务器的系统都需要是 CentOS 7 版本
2) 所有服务器都要关闭防火墙
3) 所有服务器都要关闭 SELinux
4) 所有服务器系统都要配置好可用的软件源
5) 需要按照拓扑图给对应的服务器配置好 IP 地址和主机名
6) 所有服务器都要可以相互 ping 通自己和对方的 IP 地址和主机名

步骤三:所有数据库服务器安装 MariaDB 或 MySQL 数据库

3.1 所有数据库服务器安装 MariaDB 或 MySQL

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# yum -y install mariadb-server

(补充:这里以安装 MariaDB 数据库为例)

3.2 设置所有数据库服务器开机自启 MariaDB 或 MySQL

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# systemctl enable mariadb

(补充:这里以开机自启 MariaDB 数据库为例)

步骤四:配置 MairaDB & MySQL 互为主从结构

4.1 将数据库服务器 22 设置为数据库服务器 21 的从库

4.1.1 开启数据库服务器 21 的 server-id 和 binlog 日志

(只在数据库服务器 21 上执行以下步骤)

# vi /etc/my.cnf

将部分内容修改如下:

[mysqld]
server-id=1
log-bin=mariadb-bin
......


补充:这里以
1) 将 server-id 设置为 1
2) 启动 binlog 日志,并将 binlog 日志的前缀设置为 mariadb-bin
为例

(注意: 集群里的各个数据库的 server id 不能一样)

4.1.2 重启数据库服务器 21 的数据库

(只在数据库服务器 21 上执行以下步骤)

# systemctl restart mariadb

(补充:这里以重启 MariaDB 数据库为例)

4.1.3 在数据库服务器 21 的数据库中创建用于同步的用户
4.1.3.1 进入数据库

(只在数据库服务器 21 上执行以下步骤)

# mysql -p
4.1.3.2 创建数据库服务器 21 用于被数据库服务器 22 同步的 MariaDB 用户

(只在数据库服务器 21 上执行以下步骤)

> grant replication slave on *.* to 'backup'@'192.168.1.22' identified by 'backup';
4.1.3.3 刷新数据库服务器 21 里所有用户的权限

(只在数据库服务器 21 上执行以下步骤)

> flush privileges;
4.1.3.4 显示数据库服务器 21 的 MariaDB 的主库参数

(只在数据库服务器 21 上执行以下步骤)

> show master status;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

(补充:这里显示的 master_log_file 和 master_log_pos 的参数会在后面配置从库中使用)

4.1.4 让数据库服务器 22 同步数据库服务器 21
4.1.4.1 启动数据库服务器 22

(只在数据库服务器 22 上执行以下步骤)

# systemctl start mariadb

(补充:这里以启动 MariaDB 数据库为例)

4.1.4.2 进入数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# mysql -p
4.1.4.3 同步主库

(只在数据库服务器 22 上执行以下步骤)

> change master to master_host="192.168.1.21",master_user='backup',master_password='backup',master_log_file='mariadb-bin.000003',master_log_pos=475;
4.1.4.4 启动从库状态

(只在数据库服务器 22 上执行以下步骤)

> start slave;
4.1.4.5 显示从库状态

(只在数据库服务器 22 上执行以下步骤)

> show slave status\G;
          Master_Host: 192.168.1.21
              ......
          Slave_IO_Running: Yes  
          Last_IO_Error: ......
              ......
          Slave_SQL_Running: Yes
          Last_SQL_Error: ......
              ......

(补充:这里显示它的主服务器是 192.168.1.21)

(注意:这里要确保 Slave_IO_Running: 和 Slave_SQL_Running: 后面没有报错信息)

4.2 将数据库服务器 21 设置为数据库服务器 22 的从库

4.2.1 关闭数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# systemctl stop mariadb

(补充:这里以停止 MariaDB 数据库为例)

4.2.2 开启数据库服务器 21 的 server-id 和 binlog 日志

(只在数据库服务器 22 上执行以下步骤)

# vi /etc/my.cnf

(将部分内容修改如下)

[mysqld]
server-id=2
log-bin=mariadb-bin
......


补充:这里以
1) 将 server-id 设置为 2
2) 启动 binlog 日志,并将 binlog 日志的前缀设置为 mariadb-bin
为例

(注意: 集群里的各个数据库的 server id 不能一样)

4.2.3 启动数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# systemctl start mariadb

(补充:这里以重启 MariaDB 数据库为例)

4.2.4 在数据库服务器 22 的数据库中创建用于同步的用户
4.2.4.1 进入数据库

(只在数据库服务器 22 上执行以下步骤)

# mysql -p
4.2.4.2 创建数据库服务器 21 用于被数据库服务器 22 同步的 MariaDB 用户

(只在数据库服务器 22 上执行以下步骤)

> grant replication slave on *.* to 'backup'@'192.168.1.21' identified by 'backup';
4.2.4.3 刷新数据库服务器 22 数据库里所有用户的权限

(只在数据库服务器 22 上执行以下步骤)

> flush privileges;
4.2.4.4 显示数据库服务器 22 的 MariaDB 的主库参数

(只在数据库服务器 22 上执行以下步骤)

> show master status;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

(补充:这里显示的 master_log_file 和 master_log_pos 的参数会在后面配置从库中使用)

4.2.5 让数据库服务器 21 同步数据库服务器 22
4.2.5.1 进入数据库服务器 21 的数据库

(只在数据库服务器 21 上执行以下步骤)

# mysql -p
4.2.5.2 同步主库

(只在数据库服务器 21 上执行以下步骤)

> change master to master_host="192.168.1.22",master_user='backup',master_password='backup',master_log_file='mariadb-bin.000003',master_log_pos=475;
4.2.5.3 启动从库状态

(只在数据库服务器 21 上执行以下步骤)

> start slave;
4.2.5.4 显示从库状态

(只在数据库服务器 21 上执行以下步骤)

> show slave status\G;
          Master_Host: 192.168.1.22
              ......
          Slave_IO_Running: Yes  
          Last_IO_Error: ......
              ......
          Slave_SQL_Running: Yes
          Last_SQL_Error: ......
              ......

(补充:这里显示它的主服务器是 192.168.1.21)

(注意:这里要确保 Slave_IO_Running: 和 Slave_SQL_Running: 后面没有报错信息)

步骤五:测试 MariaDB & MySQL 互为主从集群

5.1 进入数据库

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# mysql -uroot -p

5.2 创建测试库

(只在数据库服务器 21 上执行以下步骤)

> create database test1;

5.3 进入测试库

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

> use test1;

5.4 创建测试表

(只在数据库服务器 21 上执行以下步骤)

> create table test1a(id int(10),name char(100),age int(10));

(补充:这里随意创建了一张表格)

5.5 在数据库服务器 21 上插入测试数据

(只在数据库服务器 21 上执行以下步骤)

> insert into test1a(id,name,age) values('1','zmy','10');

(补充:这里随意插入了一条数据)

5.6 在数据库服务器 22 上插入测试数据

(只在数据库服务器 22 上执行以下步骤)

> insert into test1a(id,name,age) values('2','ming','20');

(补充:这里随意插入了一条数据)

5.7 在两个数据库里都可以看到对方插入的测试数据

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

> select * from test1a;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | zmy  |   10 |
|    2 | ming |   20 |
+------+------+------+
2 rows in set (0.00 sec)

[内容] Nginx 代理的设置 (HTTP 和 SSH)

注意:

在设置 Nginx 代理之前要先安装 Nginx

正文:

内容一:设置 Nginx HTTP 代理

# vi /usr/local/nginx/conf/nginx.conf

将部分内容修改如下:

......
http {
.....
upstream webserver {
   server 192.168.1.100:80;
   server 192.168.1.200:80;
}
.....
server {
listen 80;
server_name www.eternalcenter.com;
location / {
proxy_pass http://webserver;
}
......
}
......
}

或者:

......
http {
.....
upstream webserver {
Server    192.168.2.100    weight=1    max_fails=1  fail_timeout=30;
Server    192.168.2.200    weight=2    max_fails=2  fail_timeout=30;
Server    192.168.2.101    down;
}
.....
server {
listen 80;
server_name www.eternalcenter.com;
location / {
proxy_pass http://webserver;
}
......
}
......
}

内容二:设置 Nginx SSH 代理

将部分内容修改如下:

stream {
upstream backend {
server 192.168.1.100:22;
server 192.168.1.200:22;
}
server{
listen 222;
proxy_connect_timeout 1s;
proxy_pass backend;
}
}

http{
......
}

[实验] FTP + Pacemaker 存储服务高可用的实现

纪念:站主于 2019 年 8 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

注意:

在实现 FTP + Pacemaker 存储服务高可用之前要先安装 Pacemaker 集群 ,并且需要 root 权限

正文:

步骤一:Pacemaker 高可用 FTP 服务的解析

1.1 集群本身需要的服务

需要额外一台服务器提供 Iscasi 远程目录服务

1.2 本 Pacemaker 高可用 FTP 服务的特点

1) 使用其他服务器提供的 Iscasi 服务器作为 FTP 的共享目录
2) 提供 FTP 服务
4) 提供虚拟 IP 服务
5) 以上三项服务器都实现高可用
6) 唯一的单点故障在于额外的那台服务器提供的 Iscasi 远程目录服务器

步骤二:前期准备所有集群主机上都安装 FTP 服务

2.1 在所有集群主机上安装 FTP

(在所有集群服务器上执行以下步骤)

# yum -y install vsftpd

2.2 确保 vsftpd 服务没有启动

(在所有集群服务器上执行以下步骤)

# systemctl stop vsftpd
# systemctl disable vsftpd

步骤三:部署 Pacemaker 的 FTP 高可用服务

3.1 在 ftp 资源组中创建名为 ftpip 的虚拟 ip 资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create ftpip IPaddr2 ip=192.168.0.21 cidr_netmask=24 --group ftp

3.2 在 ftp 资源组中创建名为 ftpfiles 挂载其他服务器的 Iscasi 服务的资源

(只在 1 台集群里的服务器上执行以下步骤)

# pcs resource create ftpfiles Filesystem device=192.168.8.21:/content/ftp directory=/var/ftp fstype=nfs options=ro --group ftp

(注意:这里的 Filesystem 指的是其他服务器搭建的 Iscasi 服务,这个服务需要提前搭建好)

3.3 在 ftp 资源组中创建名为 vsftpd 的 ftp 资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create vsftpd systemd:vsftpd --group ftp

[实验] Apache + Pacemaker 网站服务高可用的实现

纪念:站主于 2019 年 8 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

注意:

在实现 Apache + Pacemaker 网站服务高可用之前要先安装 Pacemaker 集群

正文:

步骤一:Pacemaker 高可用网站服务的解析

1.1 集群本身需要的服务

需要额外一台服务器提供 NFS 远程目录服务

1.2 本 Pacemaker 高可用网站服务的特点

1) 使用其他服务器提供的 NFS 服务器作为网站的网页目录
2) 提供网站 服务
3) 提供虚拟 IP 地址服务
4) 以上三项服务器都实现高可用
5) 唯一的单点故障在于额外的那台服务器提供的 NFS 远程目录服务器

步骤二:前期准备

2.1 在所有集群服务器上安装 httpd

(在所有集群服务器上执行以下步骤)

# yum -y install httpd

2.2 确保 httpd 不会被 SELinux 限制

(在所有集群服务器上执行以下步骤)

# setsebool -P httpd_use_nfs 1

(补充:这里是要求 SELinux 的布尔值让 httpd 也可以使用 NFS 服务)

2.3 确保 httpd 没有启动

(在所有集群服务器上执行以下步骤)

# systemctl stop httpd
# systemctl disable httpd

步骤三:部署 Pacemaker 的网站高可用服务

3.1 在 网站资源组中创建名为 webip 的虚拟 IP 地址资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create webip IPaddr2 ip=192.168.0.20 cidr_netmask=24 --group=web

3.2 在 网站资源组中创建名为 webnfs 挂载其他服务器的 NFS 服务的资源

(只在一台集群里的服务器上执行以下步骤)

# pcs resource create webnfs Filesystem device=192.168.8.21:/content directory=/var/www/html fstype=nfs options=ro --group web

(注意:这里的 Filesystem 指的是其他服务器搭建的 NFS 服务,这个服务需要提前搭建好,可以参考 https://eternalcenter.com/nfs/ 里的内容)

3.3 在网站资源组中创建名为 webserver 的网站资源

(只在 1 台集群里的服务器上执行以下步骤)

# pcs resource create webserver apache configfile="/etc/httpd/conf/httpd.conf" statusurl="http://127.0.0.1/server-status" --group web