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

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

注意:

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

软件准备:

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

https://redis.io/

在 rubygems 的官网上下载软件 rubygems

https://rubygems.org

正文:

步骤目录:

步骤一:规划拓扑
1.1 服务器列表
1.2 服务器列表简介

步骤二:系统环境要求

步骤三:所有数据库服务器安装 Redis 数据库
3.1 安装 Redis 数据库的相关依赖包
3.2 安装 Redis 数据库
3.2.1 解压安装包
3.2.2 进入安装包目录
3.2.3 编译安装包
3.2.4 安装软件包
3.2.5 进入配置目录
3.2.6 安装软件包

步骤四:将 Redis 数据库添加到别的集群
4.1 修改所有服务器上的 Redis 数据库配置文件
4.2 重启所有服务器上的 Redis 数据库
4.2.1 关闭 Redis 数据库
4.2.2 开启 Redis 数据库
4.3 将 redis7 和 redis8 添加到现有的 Redis 集群中
4.3.1 显示现有集群的状况
4.3.2 添加 redis7 并将其视为主数据库
4.3.3 添加 redis8 并将其视为从数据库
4.3.4 确认 redis7 和 redis8 已经加入到了集群中
4.4 让新加入的 redis 数据库也能存储数据
4.4.1 重新分配集群的存储块
4.4.2 确认集群的存储块已经覆盖所有主数据库

步骤五:将部分 Redis 数据库从集群中删除
5.1 将存储块从要被删除的 redis 主数据库里拿走
5.2 将部分 Redis 数据库从集群中删除
5.2.1 将作为主库的 Redis 数据库从集群中删除
5.2.2 将作为从库的 Redis 数据库从集群中删除
5.3 确认部分 Redis 数据库已经从集群中删除

具体的操作步骤:

步骤一:规划拓扑
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 服务器列表
1.2 服务器列表简介

步骤二:系统环境要求

步骤三:所有数据库服务器安装 Redis 数据库
3.1 安装 Redis 数据库的相关依赖包
3.2 安装 Redis 数据库
3.2.1 解压安装包
3.2.2 进入安装包目录
3.2.3 编译安装包
3.2.4 安装软件包
3.2.5 进入配置目录
3.2.6 配置软件包

步骤四:搭建 Redis 数据库集群
4.1 修改所有服务器上的 Redis 数据库配置文件
4.2 重启所有服务器上的 Redis 数据库
4.2.1 关闭 Redis 数据库
4.2.2 开启 Redis 数据库
4.3 显示目前的集群信息
4.3.1 进入数据库
4.3.2 显示数据库是否可用
4.3.3 显示集群信息
4.4 部署 Redis 集群环境
4.4.1 部署 ruby 脚本运行环境
4.4.1.1 安装 ruby
4.4.1.2 升级 ruby
4.4.1.2.1 解压 ruby 安装包
4.4.1.2.2 进入 ruby 安装包目录
4.4.1.2.3 升级 ruby
4.4.1.3 安装 Redis 模块
4.4.2 部署 Redis 集群文件
4.4.2.1 创建 Redis 集群文件的目录
4.4.2.2 复制 Redis 集群文件
4.4.2.3 给 Redis 集群文件添加执行权限
4.5 创建 Redis 集群
4.6 显示集群中主机状态信息的方法
4.6.1 方法一
4.6.1.1 进入数据库
4.6.1.2 显示集群整体信息
4.6.1.3 显示集群主从关系
4.6.1.4 退出数据库
4.6.2 方法二
4.6.2.1 显示集群整体信息
4.6.2.2 显示集群主从关系

步骤五:Redis 集群创建失败的解决办法
5.1 关闭所有 Redis服务器的 Redis 服务
5.2 删除所有原来的 Redis 数据
5.3 重启 Redis 数据库
5.4 按照前面的步骤重新执行创建集群

步骤六:测试 Redis 集群
6.1 数据同步测试
6.1.1 进入数据库
6.1.2 确认现在的 Redis 数据库都是空的
6.1.3 在主 Redis 数据库上插入数据
6.1.4 查看刚插入的数据
6.2 高可用测试
6.2.1 模拟此时主库宕机后,对应的从库会自动升级为主库但需要 5 分钟的时间
6.2.2 等待 5 分钟后显示集群主从关系
6.2.3 主库恢复后会成为新主库的从库
6.2.4 再次显示集群主从关系

具体的操作步骤:

步骤一:规划拓扑
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 停止数据库
1.2.2 修改数据库目录的
1.2.3 修改配置文件
1.2.4 启动数据库
1.3 将数据库版本升级到更新的版本

内容二:数据库库安全
2.1 删除所有不用的库
2.1.1 查看所有库的列表
2.1.2 删除测试库
2.2 删除所有测试库
2.2.1 方法一:手动删除所有测试库
2.2.1.1 查看所有库的列表
2.2.1.2 删除测试库
2.2.2 方法二:使用工具删除所有测试库
2.3 禁用客户端本地数据被读取
2.3.1 修改配置文件
2.3.2 重启数据库
2.4 保护数据的本地存储

内容三:数据库登陆安全
3.1 限制数据的导入导出
3.1.1 案例一:禁止数据的导入导出
3.1.1.1 修改配置文件
3.1.1.2 重启数据库
3.1.2 案例二:只允许将数据从 /root 目录导入或导出到 /root 目录
3.1.2.1 修改配置文件
3.1.2.2 重启数据库
3.1.3 案例三:不对数据作出导入和导出的限制
3.1.3.1 修改配置文件
3.1.3.2 重启数据库
3.2 删除无用和不需要的用户
3.2.1 查看所有用户
3.2.2 删除不需要的用户
3.2.2.1 删除用户的第一种方法:使用 drop 命令删除用户
3.2.2.2 删除用户的第二中方法:使用 delete 命令删除用户
3.3 强制用户使用强密码
3.3.1 修改配置文件
3.3.2 重启数据库
3.3.3 确保 validate_password_policy 被设置的参数是 MEDIUM
3.3.3.1 进入数据库
3.3.3.2 查看 validate_password_policy 参数
3.4 设置用户密码有效期
3.4.1 对于 MariaDB 和 MySQL5.7 及以下的版本无法设置有效期,只能定期修改密码
3.4.2 设置用户默认有效期的方法
3.4.2.1 修改用户密码默认的自动过期时间
3.4.2.2 让用户密码立刻过期
3.4.2.3 让用户密码永不过期
3.5 删除无密码用户
3.5.1 方法一:手动删除无密码用户
3.5.1.1 查看无密码用户
3.5.1.1.1 MariaDB 和 MySQL 5.7 及以下版本查看无密码用户的方法
3.5.1.1.2 MySQL 8.0 及以上版本查看无密码用户的方法
3.5.1.2 手动删除不需要的用户的方法
3.5.1.2.1 手动删除用户的第一种方法:使用 drop 命令删除用户
3.5.1.2.2 手动删除用户的第二种方法:使用 delete 命令删除用户
3.5.2 方法二:使用工具删除无密码用户
3.6 禁止非 root 用户 拥有 mysql.user 表访问权限
3.7 让用户只拥有最小但够用的权限
3.7.1 查看所有用户
3.7.2 数据库权限层级
3.7.3 查看每一个用户的权限
3.7.4 删除用户多余的权限

内容四:数据库网络安全
4.1 禁止或者限制远程登陆
4.1.1 禁止远程登陆
4.1.1.1 通过 MariaDB & MySQL 的配置文件禁止远程登录
4.1.1.1.1 修改配置文件
4.1.1.1.2 重启数据库
4.1.1.2 通过防火墙禁止远程登录
4.1.2 如果非要进行远程登录则要限制远程登录
4.1.2.1 限制访问数据库 TCP 端口的具体 IP 地址
4.1.2.2 禁止有较大权限的用户被远程登陆
4.2 对网络数据进行加密传输
4.2.1 生成 SSL
4.2.1.1 创建 CA 证书
4.2.1.2 创建服务端证书,并去除加密,并使用刚刚的 CA 证书进行签名
4.2.1.3 创建客户端证书,并去除加密,并使用刚刚的 CA 证书进行签名
4.2.1.4 对生成的证书进行验证
4.2.2 将 SSL 添加到 MariaDB & MySQL
4.2.2.1 将 SSL 放在指定的位置
4.2.2.2 修改配置文件
4.2.3 重启数据库
4.2.4 验证 SSL
4.2.4.1 查看 have_ssl 和 ssl 变量
4.2.4.2 查看 SSL 的状态
4.2.5 确保所有数据库用户使用 SSL
4.2.6 用户通过 SSL 连接数据库的方法

内容五:开启审计
5.1 开启审计
5.1.1 MariaDB 和 MySQL 5.7 开启审计的方法
5.1.2 MySQL 8.0 开启审计的方法
5.2 查看 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 文件中添加免密登录参数
1.2 使修改的配置生效
1.2.1 MariaDB 使修改的配置生效
1.2.2 MySQL 使修改的配置生效

步骤二:将 root 密码设置为空
2.1 不使用密码进入数据库
2.2 清空 root 用户密码
2.2.1 MariaDB 和 MySQL 5.7 及以下的版本将 root 密码设置为空
2.2.2 MySQL 8.0 及以上的版本将 root 密码设置为空
2.3 退出数据库

步骤三:给 root 设置新密码
3.1 在 MariaDB&MySQL 文件中将免密登录参数注释掉
3.2 使修改的配置生效
3.2.1 MariaDB 使修改的配置生效
3.2.2 MySQL 使修改的配置生效
3.3 进入数据库
3.4 给 root 设置新密码
3.5 退出数据库

具体的操作步骤:

步骤一:免密进入数据库
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/

正文:

步骤目录:

步骤一:系统环境要求

步骤二:部署安装 MySQL 的环境
2.1 删除系统上的 MariaDB
2.2 确保当前目录下拥有如下安装包

步骤三:安装 MySQL 数据库

步骤四:启动 MySQL 数据库

步骤五:修改 MySQL 数据库的 root 密码
5.1 显示初始的 root 密码
5.2 进入数据库
5.3 修改 root 密码
5.4 退出数据库

具体的操作步骤:

步骤一:系统环境要求

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;