[实验] 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

[命令] Linux 命令 sed (修改和打印文本的行)

内容目录:

内容一:sed 格式

内容二:sed 选项

内容三:sed 的参数

内容四:sed 的使用案例
4.1 案例一:使用 p 参数打印某一行数据
4.1.1 在 test.txt 文本里打印第二行的数据
4.1.2 在 test.txt 文本里打印第二行到第四行的数据
4.1.3 在 test.txt 文本里打印最后一行的数据
4.1.4 在 test.txt 文本里打印包含 eternalcenter 的数据
4.1.5 在 test.txt 文本里打印以 eternalcenter 结尾的数据
4.1.6 在 test.txt 文本里输出总行数
4.1.7 在 test.txt 文本里输出奇数行
4.1.8 在 test.txt 文本里输出偶数行
4.2 案例二:使用 a 参数在某一行下面追加一行数据
4.2.1 在 test.txt 文本里在第二行下面追加一行 eternalcenter
4.2.2 在 test.txt 文本里在 abc 那一行下面添加一行 eternalcenter
4.2.3 在 test.txt 文本里在以 a 开头的行下面添加 eternalcenter
4.2.4 在 test.txt 文本里在以 [a] 开头的行下面添加 eternalcenter
4.2.5 在 test.txt 文本里最后一行下面添加 eternalcenter
4.3 案例三:使用 i 参数在某一行上面插入一行数据
4.3.1 在 test.txt 文本里在第二行上面插入一行 eternalcenter
4.3.2 在 test.txt 文本里在 abc 那一行上面添加一行 eternalcenter
4.3.3 在 test.txt 文本里在以 a 开头的行上面添加 eternalcenter
4.3.4 在 test.txt 文本里在以 [a] 开头的行上面添加 eternalcenter
4.3.5 在 test.txt 文本里最后一行上面添加 eternalcenter
4.4 案例四:使用 c 参数替换某一行数据
4.4.1 在 test.txt 文本里将第二行替换成 eternalcenter
4.4.2 在 test.txt 文本里将 abc 那一行替换成 eternalcenter
4.4.3 在 test.txt 文本里将以 a 开头的那一行替换成 eternalcenter
4.4.4 在 test.txt 文本里将以 [a] 开头的那一行替换成 eternalcenter
4.4.5 在 test.txt 文本里将以 eternalcentre 开头的那一行替换成 eternalcenter ALL=(ALL) NOPASSWD: ALL
4.5 案例五:使用 d 参数删除某一行
4.5.1 在 test.txt 文本里删除第二行
4.5.2 在 test.txt 文本里删除包含 abc 的那一行
4.5.3 在 test.txt 文本里删除以 a 开头的那一行
4.5.4 在 test.txt 文本里删除以 [a] 开头的那一行
4.5.5 在 test.txt 文本里删除第二行到第四行
4.6 案例六:使用 s 参数替换某一行某些数据
4.6.1 在 test.txt 文本里将所有行的第一个 eternalcentre 换成 eternalcenter
4.6.2 在 test.txt 文本里将所有行的所有 eternalcentre 换成 eternalcenter
4.6.3 在 test.txt 文本里将包含 eternalcentre 的行换成 eternalcenter
4.6.4 在 test.txt 文本里将第三行的第二个 eternalcentre 换成 eternalcenter
4.6.5 在 test.txt 文本里在所有行前面添加 eternalcenter
4.6.6 在 test.txt 文本里将第二行替换成 eternalcenter
4.6.7 在 test.txt 文本里将最后一行替换成 eternalcenter
4.6.8 在 test.txt 文中里将第二到第三行替换成 eternalcenter
4.6.9 在 test.txt 文本里将 eternalcenter 前面的数据和后面的数据对调位置
4.6.10 在 test.txt 文本里删除每行的第一个字符和最后一个字符
4.6.11 在 test.txt 文本里删除每行的第二个字符和最后一个字符
4.6.12 在 test.txt 文本里删除所有的数字和空格
4.6.13 在 test.txt 文本里将所有的大写字母都添加括号
4.6.14 在 test.txt 文本里给第七行和第九行前面添加 “#”
4.6.15 在 test.txt 文本里删除第一个空格
4.7 案例七:使用 h、H、g、G 参数复制和粘贴
4.7.1 sed 命令的工作原理
4.7.2 h、H、g、G、d、D 参数的讲解
4.7.2.1 h、H、g、G、d、D 参数的作用简介
4.7.2.2 h、H、g、G、d、D 的功能示意图
4.7.3 h、H、g、G、d、D 的使用案例
4.7.3.1 将第一行的数据添加到第三行后面
4.7.3.2 将第一行的数据替换第三行
4.7.3.3 将第一行和第二行的数据添加到第三行后面
4.7.3.4 将第一行和第二行的数据替换第三行
4.7.3.5 将第一个以 a 开头的行的数据添加到第三行后面
4.7.3.6 将第一个和第二个以 a 开头的行的数据添加到第三行后面
4.8 案例八:sed 一次匹配多个参数

具体的内容:

内容一:sed 格式

# sed <option> <parameter> <file>

内容二:sed 选项

1) -n 或 –quiet 或 –silent 仅显示处理后的内容,没处理的内容就不显示了
2) -i 实现数据的变更
3) -e <脚本> 或 –expression=<脚本> 以指定的脚本来处理输入的文本
4) -r 支持扩展正则
5) -f <脚本文件> 或 –file=<脚本文件> 以指定的脚本文件来处理输入的文本
6) -h 或 –help 显示帮助内容
7) -V 或 –version 显示版本信息

内容三:sed 的参数

1) p 打印某一行的数据
2) a 在某一行下面追加一行的数据
3) i 在某一行上面插入一行的数据
4) c 替换某一行的数据
5) d 删除某一行
6) s 替换某一行的某些数据
7) h、H、g、G 复制和粘贴某些行的数据

内容四:sed 的使用案例
4.1 案例一:使用 p 参数打印某一行数据
4.1.1 在 test.txt 文本里打印第二行的数据

# sed -n 2p test.txt

4.1.2 在 test.txt 文本里打印第二行到第四行的数据

# sed -n 2,4p test.txt

4.1.3 在 test.txt 文本里打印最后一行的数据

# sed -n '$p' test.txt

4.1.4 在 test.txt 文本里打印包含 eternalcenter 的数据

# sed -n '/eternalcenter/p' test.txt

4.1.5 在 test.txt 文本里打印以 eternalcenter 结尾的数据

# sed -n '/eternalcenter$/p' test.txt

4.1.6 在 test.txt 文本里输出总行数

# sed -n $= test.txt

4.1.7 在 test.txt 文本里输出奇数行

# sed -n 'p;n' test.txt

4.1.8 在 test.txt 文本里输出偶数行

# sed -n 'n;p' test.txt

4.2 案例二:使用 a 参数在某一行下面追加一行数据
4.2.1 在 test.txt 文本里在第二行下面追加一行 eternalcenter

# sed "2a eternalcenter" test.txt

4.2.2 在 test.txt 文本里在 abc 那一行下面添加一行 eternalcenter

# sed "/abc/a eternalcenter" test.txt

4.2.3 在 test.txt 文本里在以 a 开头的行下面添加 eternalcenter

# sed "/^a/a eternalcenter" test.txt

4.2.4 在 test.txt 文本里在以 [a] 开头的行下面添加 eternalcenter

# sed "/^\[a\]/a eternalcenter" test.txt

4.2.5 在 test.txt 文本里最后一行下面添加 eternalcenter

# sed "$a eternalcenter" test.txt

4.3 案例三:使用 i 参数在某一行上面插入一行数据
4.3.1 在 test.txt 文本里在第二行上面插入一行 eternalcenter

# sed "2i eternalcenter" test.txt

4.3.2 在 test.txt 文本里在 abc 那一行上面添加一行 eternalcenter

# sed "/abc/i eternalcenter" test.txt

4.3.3 在 test.txt 文本里在以 a 开头的行上面添加 eternalcenter

# sed "/^a/i eternalcenter" test.txt

4.3.4 在 test.txt 文本里在以 [a] 开头的行上面添加 eternalcenter

# sed "/^\[a\]/i eternalcenter" test.txt

4.3.5 在 test.txt 文本里最后一行上面添加 eternalcenter

# sed "$a eternalcenter" test.txt

4.4 案例四:使用 c 参数替换某一行数据
4.4.1 在 test.txt 文本里将第二行替换成 eternalcenter

# sed "2c\ eternalcenter" test.txt

或者:

# sed "2ceternalcenter" test.txt

4.4.2 在 test.txt 文本里将 abc 那一行替换成 eternalcenter

# sed "/abc/c\ eternalcenter" test.txt

或者:

# sed "/abc/ceternalcenter" test.txt

4.4.3 在 test.txt 文本里将以 a 开头的那一行替换成 eternalcenter

# sed "/^a/c\ eternalcenter" test.txt

或者:

# sed "/^a/ceternalcenter" test.txt

4.4.4 在 test.txt 文本里将以 [a] 开头的那一行替换成 eternalcenter

# sed "/^\[a\]/c\ eternalcenter" test.txt

或者:

# sed "/^\[a\]/ceternalcenter" test.txt

4.4.5 在 test.txt 文本里将以 eternalcentre 开头的那一行替换成 eternalcenter ALL=(ALL) NOPASSWD: ALL

# sed "/^eternalcentre/c\ eternalcenter\ ALL=\(ALL\)\ NOPASSWD:\ ALL" test.txt

或者:

# sed "/^eternalcentre/c\eternalcenter\ ALL=\(ALL\)\ NOPASSWD:\ ALL" test.txt

4.5 案例五:使用 d 参数删除某一行
4.5.1 在 test.txt 文本里删除第二行

# sed 2d test.txt

4.5.2 在 test.txt 文本里删除包含 abc 的那一行

# sed /"abc"/d test.txt

4.5.3 在 test.txt 文本里删除以 a 开头的那一行

# sed /"^a"/d test.txt

4.5.4 在 test.txt 文本里删除以 [a] 开头的那一行

# sed /"^\[a\]"/d test.txt

4.5.5 在 test.txt 文本里删除第二行到第四行

# sed '2,4d' test.txt

4.6 案例六:使用 s 参数替换某一行某些数据
4.6.1 在 test.txt 文本里将所有行的第一个 eternalcentre 换成 eternalcenter

# sed 's/eternalcentre/eternalcneter/' test.txt

4.6.2 在 test.txt 文本里将所有行的所有 eternalcentre 换成 eternalcenter

# sed 's/eternalcentre/eternalcneter/g' test.txt

4.6.3 在 test.txt 文本里将包含 eternalcentre 的行换成 eternalcenter

# sed 's/.*eternalcentre.*/eternalcneter/' test.txt

4.6.4 在 test.txt 文本里将第三行的第二个 eternalcentre 换成 eternalcenter

# sed '3s/eternalcentre/eternalcenter/2' 1.txt

4.6.5 在 test.txt 文本里在所有行前面添加 eternalcenter

# sed 's/^/eternalcenter/g' test.txt

4.6.6 在 test.txt 文本里将第二行替换成 eternalcenter

# sed '2s/.*/eternalcenter/' test.txt

4.6.7 在 test.txt 文本里将最后一行替换成 eternalcenter

# sed '$s/.*/eternalcenter/' test.txt

4.6.8 在 test.txt 文中里将第二到第三行替换成 eternalcenter

# sed '2,3s/.*/eternalcenter/' test.txt

4.6.9 在 test.txt 文本里将 eternalcenter 前面的数据和后面的数据对调位置

# sed "s/^\(.*\)\(eternalcenter\)\(.*\)$/\3\2\1/" test.txt

或者:

# sed -r "s/(.*)(eternalcenter)(.*)/\3\2\1/" test.txt

4.6.10 在 test.txt 文本里删除每行的第一个字符和最后一个字符

# sed 's/.//1;s/.$//' test.txt

4.6.11 在 test.txt 文本里删除每行的第二个字符和最后一个字符

# sed 's/.//2;s/.$//' test.txt

4.6.12 在 test.txt 文本里删除所有的数字和空格

# sed -r 's/[0-9]//g;s/^( )+//' test.txt

4.6.13 在 test.txt 文本里将所有的大写字母都添加括号

# sed 's/[A-Z]/(&)/g' test.txt

4.6.14 在 test.txt 文本里给第七行和第九行前面添加 “#”

# sed '7,9s/^/#/' test.txt

4.6.15 在 test.txt 文本里删除第一个空格

# sed -r 's/( )(.*)/\2/'

4.7 案例七:使用 h、H、g、G 参数复制和粘贴
4.7.1 sed 命令的工作原理

1) 从第一行开始一行一行地读取文本里的内容
2) 每读取一行就将数据存入到 pattern space 里面
3) 在 pattern sapce 中执行 sed 命令
4) 再打印 pattern space 中的内容然后将其清空
5) 之后重复以上操作再开始读取文本里的下一行
6) pattern space 里的数据可以存储到 hold space 里面


补充:
pattern space 相当于处理数据的流水线
hold space 相当于暂时存储数据的仓库

4.7.2 h、H、g、G、d、D 参数的讲解
4.7.2.1 h、H、g、G、d、D 参数的作用简介

1) g 将 hold space 中的内容拷贝到 pattern space 中,原来 pattern space 里的内容清除
2) G 将 hold space 中的内容 append 到 pattern space\n 后
3) h 将 pattern space 中的内容拷贝到 hold space 中,原来的 hold space 里的内容被清除
4) H 将 pattern space 中的内容 append 到 hold space\n 后
5) d 删除 pattern 中的所有行,并读入下一新行到 pattern 中
6) D 删除 multiline pattern 中的第一行,不读入下一行

4.7.2.2 h、H、g、G、d、D 的功能示意图

P H     P H     P H
1    h  1 1  d    1

P H     P H     P H     P H
2 1  G  2 1  H  2 1  d    1
        1       1 2       2
                  1       1

P H     P H     P H
3 2  G  3 2  h  3 3
  1     2 1     2 2
        1       1 1

P H     P H
3 2  g  2 2
  1     1 1


注意:
1) 这里的 P 指的是 pattern space
2) 这里的 H 指的是 hold space


补充:
h 其实就是清空现在粘贴板里的内容然后重新复制
H 其实就是不清空现在粘贴板里的内容然后再再原来粘贴版的内容基础上再追加复制
g 其实就是替换粘贴
G 其实就是追加粘贴

4.7.3 h、H、g、G、d、D 的使用案例
4.7.3.1 将第一行的数据添加到第三行后面

# sed -e '1h' -e '3G' test.txt

4.7.3.2 将第一行的数据替换第三行

# sed -e '1h' -e '3g' test.txt

4.7.3.3 将第一行和第二行的数据添加到第三行后面

# sed -e '1h' -e '2H' -e '3G' test.txt

4.7.3.4 将第一行和第二行的数据替换第三行

# sed -e '1h' -e '2H' -e '3g' test.txt

4.7.3.5 将第一个以 a 开头的行的数据添加到第三行后面

# sed -e '/^a/h' -e '3G' 1.txt

4.7.3.6 将第一个和第二个以 a 开头的行的数据添加到第三行后面

# sed -e '/^a/h' -e'/^a/H' -e '3G' 1.txt

4.8 案例八:sed 一次匹配多个参数

分别在 test.txt 文本里在 abc 和 bbb 那两行下面添加一行 eternalcenter

# sed -e "/abc/a eternalcenter" -e "/^bbb/a eternalcenter" test.txt

[命令] Linux 命令 grep (打印文本的行)

案例一:grep 使用正则表达式匹配

# grep -E '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

或者:

# egrep '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例二:grep 显示行号
2.1 grep 显示某些关键字所在行行号

# egrep -n '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
16:IPADDR=192.168.8.31
18:GATEWAY=192.168.8.55

2.2 grep 显示哪些行号是空行

# egrep -n ^$ /etc/resolv.conf

案例三:grep 取反匹配
3.1 grep 取反不匹配某些关键字

# egrep -v '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens192
UUID=5cda4d03-45c9-4856-80a6-f0bd0962d871
DEVICE=ens192
ONBOOT=yes
NETMASK=255.255.255.0
ZONE=public

3.2 grep 取反不显示空行

# egrep -v ^$ /etc/resolve.conf
### /etc/resolv.conf is a symlink to /var/run/netconfig/resolv.conf
### autogenerated by netconfig!
#
# Before you change this file manually, consider to define the
# static DNS configuration using the following variables in the
# /etc/sysconfig/network/config file:
#     NETCONFIG_DNS_STATIC_SEARCHLIST
#     NETCONFIG_DNS_STATIC_SERVERS
#     NETCONFIG_DNS_FORWARDER
# or disable DNS configuration updates via netconfig by setting:
#     NETCONFIG_DNS_POLICY=''
#
# See also the netconfig(8) manual page and other documentation.
#
### Call "netconfig update -f" to force adjusting of /etc/resolv.conf.
nameserver 192.168.0.1

案例四:grep 完全匹配

# egrep -o '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
192.168.8.31
192.168.8.55

案例五:grep 匹配区分大小写

# egrep -i '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例六:grep 统计匹配成功次数

# egrep -c '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
2

案例七:grep 将匹配成功的部分自动添加颜色

# egrep --color=auto '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例八:grep 将匹配成功的部分自动取消颜色

# egrep --color=no '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192  
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例九:grep 一次匹配多个参数

# grep -e root -e zhumingyu /etc/passwd
root:x:0:0:root:/root:/bin/bash
zhumingyu:x:1001:1001:root:/root:/bin/bash

[排错] Linux 解决删除数据后依旧无法释放空间

解决方法:

步骤一:理解出现问题的原因

当删除某些数据时,此数据正在被某个进程使用,则这些数据需要 kill 掉这个进程后才能被删除掉

步骤二:查看目录的使用状态

# df -h

(注意:如果出现已用存储加剩余存储小于总存储的情况,就代表出现了被删除的数据正在被进程使用的情况 )

步骤三:查看对应目录里所有一级子目录的大小

# du -ah --max-depth=1

步骤四:查看是否有进程在使用正在被删除的数据

# lsof | grep delete

步骤五:kill 这些进程以让这些数据被成功删除

# kill -9 `lsof | grep delete | awk '{print $2}'` 

(注意:kill 进程有一定的风险,请小心执行)

[排错] openSUSE&SUSE 解决 yast 配置 IP 地址时报错 “Network is currently handled by NetworkManager”

报错代码:

Network is currently handled by NetworkManager

解决方法:

步骤一:报错现象和原因分析
1.1 报错现象

通过 yast 给 openSUSE 和 SUSE 配置 IP 地址时可能会出现以下报错

(图:1)

1.2 原因分析

如果是带桌面安装 openSUSE 和 SUSE ,系统则会默认使用 NetworkManager 管理网络,这样会导致 yast 无法配置 IP 地址

步骤二:排错
2.1 取消开机自启 NetworkManager

# systemctl disable NetworkManager

2.2 停止 NetworkManager 服务

# systemctl stop NetworkManager

2.3 在 yast 中将 General Network Settings 从 NetworkManager Service 换成 Wicked Service
2.3.1 进入 yast

# yast

2.3.2 进入 System 下面的 Network Settings

2.3.3 在 Global Options 选项中将 General Network Settings 从 NetworkManager Service 换成 Wicked Service

(图:2)