[实验] Redis 数据库集群 Redis 数据库的添加和删除

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

注意:

在给 Redis 数据库集群添加和删除 Redis 数据库之前要先搭建 Redis 数据库集群

软件准备:

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

https://redis.io/

在 rubygems 的官网上下载软件 rubygems

https://rubygems.org

正文:

步骤一:规划拓扑

1.1 服务器列表

现有的 Redis 集群
redis7 IP 地址:192.168.1.57 端口号:1057
redis8 IP 地址:192.168.1.58 端口号:1058

(补充:在本次实验中现有的 redis 集群管理服务器是 redis1,IP 地址是 192.168.1.57,端口号是 1057)

1.2 服务器列表简介

redis7 作为主库 redis8 作为从库加入到一个现有的 Redis 集群中

步骤二:系统环境要求

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

(注意:现有的 Redis 集群因为已经是创建好了的,所以不用执行以上操作)

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

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

(分别在 redis7 和 redis8 上执行以下步骤)

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

3.2 安装 Redis 数据库

3.2.1 解压安装包

(分别在 redis7 和 redis8 上执行以下步骤)

# tar -zxf redis-5.0.5.tar.gz

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

3.2.2 进入安装包目录

(分别在 redis7 和 redis8 上执行以下步骤)

# cd redis-5.0.5/

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

3.2.3 编译安装包

(分别在 redis7 和 redis8 上执行以下步骤)

# make
3.2.4 安装软件包

(分别在 redis7 和 redis8 上执行以下步骤)

# make install
3.2.5 进入配置目录

(分别在 redis7 和 redis8 上执行以下步骤)

# cd utils/
3.2.6 安装软件包

(分别在 redis7 和 redis8 上执行以下步骤)

# ./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 数据库配置文件

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

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.57
......
port 1057
......
daemonize yes
......
pidfile /var/run/redis_1057.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1057.conf
......
cluster-node-timeout 5000
......


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

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

# vim /etc/redis/6379.conf

将部分内容修改如下:

......
#bind 127.0.0.1
bind 192.168.1.58
......
port 1058
......
daemonize yes
......
pidfile /var/run/redis_1058.pid
......
cluster-enabled yes
......
cluster-config-file nodes-1058.conf
......
cluster-node-timeout 5000
......


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

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

4.2.1 关闭 Redis 数据库

(分别在 redis7 和 redis8 上执行以下步骤)

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

(分别在 redis7 和 redis8 上执行以下步骤)

# /etc/init.d/redis_6379 start

4.3 将 redis7 和 redis8 添加到现有的 Redis 集群中

4.3.1 显示现有集群的状况

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

# redis-cli --cluster check 192.168.1.51:1051
4.3.2 添加 redis7 并将其视为主数据库

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

# redis-cli --cluster add-node 192.168.1.57:1057 192.168.1.51:1051
4.3.3 添加 redis8 并将其视为从数据库

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

# redis-cli --cluster add-node 192.168.1.58:1058 192.168.1.51:1051 --cluster-slave
4.3.4 确认 redis7 和 redis8 已经加入到了集群中

(只在 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...) -> 2 keys | 5461 slots | 1 slaves.
192.168.1.52:1052 (7477c04d...) -> 1 keys | 5462 slots | 1 slaves.
192.168.1.57:1057 (10bb6a57...) -> 0 keys | 0 slots | 1 slaves.
[OK] 4 keys in 4 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
S: 93d8988475c754a3b58d5172522163664c391da2 192.168.1.58:1058
   slots: (0 slots) slave
   replicates 10bb6a5732f629ee62801417cb44ddb670e99e86
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   slots: (0 slots) slave
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
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)
M: 10bb6a5732f629ee62801417cb44ddb670e99e86 192.168.1.57:1057
   slots: (0 slots) master
   1 additional replica(s)
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   slots: (0 slots) slave
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

4.4 让新加入的 redis 数据库也能存储数据

4.4.1 重新分配集群的存储块

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

# redis-cli --cluster reshard 192.168.1.51:1051
......
How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID? 10bb6a5732f629ee62801417cb44ddb670e99e86
......
Source node #1: all
......
Do you want to proceed with the proposed reshard plan (yes/no)? yes
......
4.4.2 确认集群的存储块已经覆盖所有主数据库

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

# redis-cli --cluster check 192.168.1.51:1051
192.168.1.51:1051 (5d030ec0...) -> 0 keys | 4096 slots | 1 slaves.
192.168.1.53:1053 (c4f884e7...) -> 1 keys | 4096 slots | 1 slaves.
192.168.1.52:1052 (7477c04d...) -> 1 keys | 4096 slots | 1 slaves.
192.168.1.57:1057 (10bb6a57...) -> 2 keys | 4096 slots | 1 slaves.
[OK] 4 keys in 4 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:[1365-5460] (4096 slots) master
   1 additional replica(s)
S: eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055
   slots: (0 slots) slave
   replicates 5d030ec05f9de86ebeedc1b035b2122addaa61d8
S: 93d8988475c754a3b58d5172522163664c391da2 192.168.1.58:1058
   slots: (0 slots) slave
   replicates 10bb6a5732f629ee62801417cb44ddb670e99e86
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   slots: (0 slots) slave
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
M: c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
M: 10bb6a5732f629ee62801417cb44ddb670e99e86 192.168.1.57:1057
   slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
   1 additional replica(s)
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   slots: (0 slots) slave
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

步骤五:将部分 Redis 数据库从集群中删除

(这里以删除 redis7 和 redis8 为例)

5.1 将存储块从要被删除的 redis 主数据库里拿走

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

# redis-cli --cluster reshard 192.168.1.51:1051
......
How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID? 5d030ec05f9de86ebeedc1b035b2122addaa61d8
......
Source node #1: 10bb6a5732f629ee62801417cb44ddb670e99e86
Source node #2: done
......
Do you want to proceed with the proposed reshard plan (yes/no)? yes
......

5.2 将部分 Redis 数据库从集群中删除

5.2.1 将作为主库的 Redis 数据库从集群中删除

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

# redis-cli --cluster del-node 192.168.1.57:1057 10bb6a5732f629ee62801417cb44ddb670e99e86
>>> Removing node 10bb6a5732f629ee62801417cb44ddb670e99e86 from cluster 192.168.1.57:1057
>>> Sending CLUSTER FORGET messages to the cluster...
5.2.2 将作为从库的 Redis 数据库从集群中删除

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

# redis-cli --cluster del-node 192.168.1.58:1058 023abbc600cd4fb1ca8bb7ce8c45099e186041f8
>>> Removing node 023abbc600cd4fb1ca8bb7ce8c45099e186041f8 from cluster 192.168.1.58:1058
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

5.3 确认部分 Redis 数据库已经从集群中删除

# redis-cli --cluster check 192.168.1.51:1051
192.168.1.51:1051 (5d030ec0...) -> 0 keys | 4096 slots | 1 slaves.
192.168.1.53:1053 (c4f884e7...) -> 1 keys | 4096 slots | 1 slaves.
192.168.1.52:1052 (7477c04d...) -> 1 keys | 4096 slots | 1 slaves.
[OK] 4 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-6826],[10923-12287] (4096 slots) master
   1 additional replica(s)
S: eac6a0586ad00375bea9aa352951c784be57e9ad 192.168.1.55:1055
   slots: (0 slots) slave
   replicates 5d030ec05f9de86ebeedc1b035b2122addaa61d8
   replicates 10bb6a5732f629ee62801417cb44ddb670e99e86
S: a5cddda6c1bc7c6d3397e17e1ba29571bb7a1657 192.168.1.54:1054
   slots: (0 slots) slave
   replicates c4f884e7e4ce6adb4f5bc4f6eb398680beb26089
M: c4f884e7e4ce6adb4f5bc4f6eb398680beb26089 192.168.1.53:1053
   slots:[12288-16383] (4096 slots) master
   1 additional replica(s)
M: 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30 192.168.1.52:1052
   slots:[6827-10922] (4096 slots) master
   1 additional replica(s)
S: fd973bbcc376bfccf5888ba06dba97feb9ef1273 192.168.1.56:1056
   slots: (0 slots) slave
   replicates 7477c04d8ebf9d498ed5586d5f4e6d513fdb3c30
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

[实验] 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 安全调优思路

内容一:数据库运行环境安全

1.1 保证运行数据库的系统是安全的

(步骤略)

1.2 以最小权限用户运行数据库

1.2.1 停止数据库
# systemctl stop mariadb

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

1.2.2 修改数据库目录的
# chown -R mysql /var/lib/mysql

(补充:MariaDB&MySQL 数据库数据默认存放位置是 /var/lib/mysql)

1.2.3 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

user=mysql
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

1.2.4 启动数据库
# systemctl start mariadb

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

1.3 将数据库版本升级到更新的版本

(步骤略)

内容二:数据库库安全

2.1 删除所有不用的库

2.1.1 查看所有库的列表
> show databases;
2.1.2 删除测试库
> drop database <database>

2.2 删除所有测试库

2.2.1 方法一:手动删除所有测试库
2.2.1.1 查看所有库的列表
> show databases;
2.2.1.2 删除测试库
> drop database <database>
2.2.2 方法二:使用工具删除所有测试库
# sudo mysql_secure_installation

2.3 禁用客户端本地数据被读取

2.3.1 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

local-infile=0
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

(注意:此参数对 MariaDB 数据库无效)

2.3.2 重启数据库
# systemctl restart mariadb

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

2.4 保护数据的本地存储

思路如下:
1) 使用加密的文件系统存储存放数据库的数据文件
2) 使用数据库之外的存储加密产品
3) 使用其他加密产品实现适当的数据保护

内容三:数据库登录安全

3.1 限制数据的导入导出

3.1.1 案例一:禁止数据的导入导出
3.1.1.1 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

secure_file_priv=null
...... 

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

(注意:此参数对 MariaDB 数据库无效)

3.1.1.2 重启数据库
# systemctl restart mariadb

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

3.1.2 案例二:只允许将数据从 /root 目录导入或导出到 /root 目录
3.1.2.1 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

secure_file_priv=/root/
...... 

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

(注意:此参数对 MariaDB 数据库无效)

3.1.2.2 重启数据库
# systemctl restart mariadb

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

3.1.3 案例三:不对数据作出导入和导出的限制
3.1.3.1 修改配置文件
# vim /etc/my.cnf

删除以下内容:

......
secure_file_priv=*
...... 

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

(注意:此参数对 MariaDB 数据库无效)

3.1.3.2 重启数据库
# systemctl restart mariadb

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

3.2 删除无用和不需要的用户

3.2.1 查看所有用户
> select user,host from mysql.user;
3.2.2 删除不需要的用户
3.2.2.1 方法一:使用 drop 命令删除用户
> drop <user>;
3.2.2.2 方法二:使用 delete 命令删除用户
> delete from mysql.user where user='<user>' and host='<host>';

3.3 强制用户使用强密码

3.3.1 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

plugin-load=validate_password.so
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

3.3.2 重启数据库
# systemctl restart mariadb

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

3.3.3 确保 validate_password_policy 被设置的参数是 MEDIUM
3.3.3.1 进入数据库
# mysql -p
3.3.3.2 查看 validate_password_policy 参数
> show variables like 'validate_password_policy';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| validate_password.policy | MEDIUM |
| validate_password_policy | MEDIUM |
+--------------------------+--------+
2 rows in set (0.01 sec)

(补充:MEDIUM 的含义是密码最小的长度是 8 ,并且必须要有一个特殊字符和一个数字)

3.4 设置用户密码有效期

3.4.1 对于 MariaDB 和 MySQL 5.7 及以下的版本无法设置有效期,只能定期修改密码
> alter user 'root'@'localhost' identified by '<password>';
3.4.2 设置用户默认有效期的方法
3.4.2.1 修改用户密码默认的自动过期时间
> set global default_password_lifetime=<number>;

(补充:这里的数字代表天数)

3.4.2.2 让用户密码立刻过期
> aleter user '<user>'@'<host>' password expire;
3.4.2.3 让用户密码永不过期
> aleter user '<user>'@'<host>' password expire never;

(补充:建议普通用户每 90 天修改一次密码,敏感用户每 30 天修改一次密码,服务用户每 365 天修改一次密码)

3.5 删除无密码用户

3.5.1 方法一:手动删除无密码用户
3.5.1.1 查看无密码用户
3.5.1.1.1 MariaDB 和 MySQL 5.7 及以下版本查看无密码用户的方法
> select user, host, password from mysql.user;
3.5.1.1.2 MySQL 8.0 及以上版本查看无密码用户的方法
> select user, host, authentication_string from mysql.user;
3.5.1.2 手动删除不需要的用户的方法
3.5.1.2.1 手动删除用户的第一种方法:使用 drop 命令删除用户
> drop user <user>;
3.5.1.2.2 手动删除用户的第二种方法:使用 delete 命令删除用户
> delete from mysql.user where user='<user>' and host='<host>';
3.5.2 方法二:使用工具删除无密码用户
# sudo mysql_secure_installation

3.6 禁止非 root 用户 拥有 mysql.user 表访问权限

> show grants for root@localhost \G;
> select * from mysql.user where user='test' \G;

3.7 让用户只拥有最小但够用的权限

3.7.1 查看所有用户
> select user,host from mysql.user;
3.7.2 数据库权限层级

1) 全局层级权限:是指整个数据库级别的权限,存储在 mysql.user 表中
格式:

> grant all on *.* ......
> show grants for <user>;
> select * from mysql.user where user='<user>'\G;

2) 库级层级权限:是指数据库中某个库的权限,存储在 mysql.db 和 mysql.host 表中
格式:

> grant all on <database>.* ......
> show grants for <user>;
> select * from mysql.db where user='<user>'\G;

3) 表级层级权限:是指数据库中某个库的某个表的权限,存储在 mysql.tables_priv 表中
格式:

> grant all on <database>.<table> ......
> show grants for <user>;
> select * from mysql.tables_priv where user='<user>'\G;

4) 列级层级权限:是指数据库中某个库的某个表的某一单列的权限,存储在 mysql.columns_priv 表中
格式:

> grant select(<field>,<field>) on <database>.<table> ......
> show grants for <user>;
> select * from mysql.columns_priv where user='<user>'\G;

5) 子程序层级权限:适用于已存储的子程序
create routing, alter routing, execute 和 grant 权限适用于已存储的子程序
create routing, alter routing, execute 和 grant 权限可以被授予为全局层级和数据库层级
alter routing, execute 和 grant 权限可以被授予为子程序层级,并存储在 mysql.procs_priv 表中
格式:

> grant execute on <subroutine> <database>.<table> ......
> show grants for <user>;
> select * from mysql.procs_priv where user='<user>'\G;
3.7.3 查看每一个用户的权限
> show grants for '<user>'@'<host>';
3.7.4 删除用户多余的权限

如果有全局权限(如: FILE,PROCESS,SUPER, or SHUTDOWN 等权限),就删除这些权限
格式:

> revoke <privilege> on *.* from <user>@<host>;
> flush privileages;

内容四:数据库网络安全

4.1 禁止或者限制远程登录

(步骤略)

(
补充:
查看可以远程登录的用户的案例

> select user, host from mysql.user where host not in ('::1','127.0.0.1','localhost');

4.1.1 禁止远程登录

4.1.1.1 通过 MariaDB & MySQL 的配置文件禁止远程登录
4.1.1.1.1 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

skip-networking
bind-address=127.0.0.1
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

(注意:加入 skip-networking 这一行会让 MariaDB&MySQL 不再使用和监听任何端口)

4.1.1.1.2 重启数据库
# systemctl restart mariadb

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

4.1.1.2 通过防火墙禁止远程登录
4.1.2 如果非要进行远程登录则要限制远程登录
4.1.2.1 限制访问数据库 TCP 端口的具体 IP 地址

(步骤略)

(补充:MariaDB&MySQL 数据库的默认端口号是 3306)

4.1.2.2 禁止有较大权限的用户被远程登录

1) 有 grant option 权限的用户
2) 被给予了全局权限像是 grant all on . 权限的用户
3) 一个可以访问 mysql.user 表的用户

4.2 对网络数据进行加密传输

4.2.1 生成 SSL
4.2.1.1 创建 CA 证书
# openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
..+++
...................................+++
e is 65537 (0x10001)

# openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ca
Email Address []:

(注意:创建 CA 证书、服务端证书、客户端证书时 Common Name 必须要有值,且必须相互不一样)

4.2.1.2 创建服务端证书,并去除加密,并使用刚刚的 CA 证书进行签名
# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
Generating a 2048 bit RSA private key
.............+++
...+++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# openssl rsa -in server-key.pem -out server-key.pem
writing RSA key

# openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key

(注意:创建 CA 证书、服务端证书、客户端证书时 Common Name 必须要有值,且必须相互不一样)

4.2.1.3 创建客户端证书,并去除加密,并使用刚刚的 CA 证书进行签名
# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem
Generating a 2048 bit RSA private key
..................+++
..............................................+++
writing new private key to 'client-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# openssl rsa -in client-key.pem -out client-key.pem
writing RSA key

# openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key
4.2.1.4 对生成的证书进行验证
# openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
4.2.2 将 SSL 添加到 MariaDB & MySQL
4.2.2.1 将 SSL 放在指定的位置
# mv ca.pem /home/mysql/sslconfig/ca.pem
# mv server-cert.pem /home/mysql/sslconfig/server-cert.pem
# mv server-key.pem /home/mysql/sslconfig/server-key.pem
4.2.2.2 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

ssl-ca=/home/mysql/sslconfig/ca.pem
ssl-cert=/home/mysql/sslconfig/server-cert.pem
ssl-key=/home/mysql/sslconfig/server-key.pem
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

4.2.3 重启数据库
# systemctl restart mariadb

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

4.2.4 验证 SSL
4.2.4.1 查看 have_ssl 和 ssl 变量
> show variables like 'have_%ssl';
> show variables like '%ssl%';

(补充:如果它们的参数为 yes ,表示服务端已经开启 SSL)

4.2.4.2 查看 SSL 的状态
> show status like 'ssl_cipher'

(补充:如果出现 “SSL:Cipher in use is DHE-RSA-AES256-SHA“ 则表示客户端已经使用 SSL 连接了)

4.2.5 确保所有数据库用户使用 SSL
> grant usage on <database>.<table> to '<user>'@'<host>' reouter ssl;
4.2.6 用户通过 SSL 连接数据库的方法
> mysql -u <user> -p -h <host> --ssl-ca=/home/mysql/sslconfig/ca.pem

内容五:开启审计

5.1 开启审计

5.1.1 MariaDB 和 MySQL 5.7 及以下版本开启审计的方法
> set global log_warning=2;
5.1.2 MySQL 8.0 及以上版本开启审计的方法
> set global general_log = on;
> set global log_timestamps = SYSTEM;
5.2 查看 MariaDB & MySQL 日志
# find /I "Access denied for user" <logfile_name>.log
# grep -i 'Access denied for user' <logfile_name>.log

(补充:中止连接、失败连接、尝试连接都将被写进日志)

[步骤] MariaDB & MySQL root 密码的重置

注意:

在重置 MariaDB & MySQL 的 root 密码之前要先安装 MariaDB & MySQL

正文:

步骤一:免密进入数据库

1.1 在 MariaDB&MySQL 文件中添加免密登录参数

# vim /etc/my.cnf

将部分内容修改如下:

......
[mysqld]
skip-grant-tables
......

1.2 使修改的配置生效

1.2.1 MariaDB 使修改的配置生效
# systemctl restart mariadb

(注意:只有当重置 MariaDB 的时候才执行这一步)

1.2.2 MySQL 使修改的配置生效
# systemctl restart mysqld

(注意:只有当重置 MariaDB 的时候才执行这一步)

步骤二:将 root 密码设置为空

2.1 不使用密码进入数据库

# mysql -u root -p

(补充:当提示输入密码时直接敲回车)

2.2 清空 root 用户密码

2.2.1 MariaDB 和 MySQL 5.7 及以下的版本将 root 密码设置为空
> update mysql.user set password='' where user='root';

(注意:只有当是重置 MariaDB 和 MySQL 5.7 及以下版本密码的时候才需要执行这一步)

2.2.2 MySQL 8.0 及以上的版本将 root 密码设置为空
> update mysql.user set authentication_string='' where user='root';

(注意:只有当是重置 MySQL 8.0 及以上版本密码的时候才需要执行这一步)

2.3 退出数据库

> quit;

步骤三:给 root 设置新密码

3.1 在 MariaDB&MySQL 文件中将免密登录参数注释掉

# vim /etc/my.cnf

将部分内容修改如下:

......
[mysqld]
# skip-grant-tables
......

3.2 使修改的配置生效

3.2.1 MariaDB 使修改的配置生效
# systemctl restart mariadb

(注意:只有当重置 MariaDB 的时候才执行这一步)

3.2.2 MySQL 使修改的配置生效
# systemctl restart mysqld

(注意:只有当重置 MySQL 的时候才执行这一步)

3.3 进入数据库

> mysql -u root -p

(补充:当提示输入密码时直接敲回车)

3.4 给 root 设置新密码

> alter user 'root'@'localhost' identified by '<password>';

3.5 退出数据库

> quit;

[实验] MySQL 的安装 (通过 RPM 软件包实现)

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

软件准备:

在 MySQL 的官网上下载安装数据库所需要的软件包 MySQL:

https://dev.mysql.com/downloads/mysql/

正文:

步骤一:系统环境要求

1) 服务器的系统需要是 CentOS Linux 7 版本
2) 服务器系统需要有软件源

步骤二:部署安装 MySQL 的环境

2.1 删除系统上的 MariaDB

# systemctl stop mariadb
# rm -rf /var/lib/mysql/*
# rpm -e --nodeps mariadb-server mariadb 

2.2 确保当前目录下拥有如下安装包

# ls
mysql-community-client-8.0.18-1.el7.x86_64.rpm
mysql-community-common-8.0.18-1.el7.x86_64.rpm
mysql-community-devel-8.0.18-1.el7.x86_64.rpm
mysql-community-libs-8.0.18-1.el7.x86_64.rpm
mysql-community-server-8.0.18-1.el7.x86_64.rpm

(补充:这里要安装的是 MySQL 是 8.0.18 社区版)

步骤三:安装 MySQL 数据库

# yum -y localinstall mysql-community-*

步骤四:启动 MySQL 数据库

# systemctl start mysqld

步骤五:修改 MySQL 数据库的 root 密码

5.1 显示初始的 root 密码

# grep 'temporary password' /var/log/mysqld.log 
2019-11-09T09:37:31.347523Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: wAA!w,?e#M2J

(补充:这里查出来的密码是 wAA!w,?e#M2J)

5.2 进入数据库

# mysql -u root -p'wAA!w,?e#M2J'

(补充:这里使用的密码是 wAA!w,?e#M2J)

5.3 修改 root 密码

> alter user user() identified by '<password>';

5.4 退出数据库

> quit;