Redis 5.0.7 讲解,单机、集群模式搭建

一、Redis 介绍

不管你是从事 Python、Java、Go、PHP、Ruby等等... Redis都应该是一个比较熟悉的中间件。而大部分经常写业务代码的程序员,实际工作中或许只用到了 set value、get value 两个操作。

Redis 概念

Redis 是一个开源的底层使用 C 语言编写的 key-value 存储数据库。可用于缓存、事件发布订阅、高速队列等场景。而且支持丰富的数据类型:string(字符串)、hash(哈希)、list(列表)、set(无序集合)、zset(有序集合)

Redis 在 3.0 版本前只支持单实例模式,虽然支持主从模式、哨兵模式部署来解决单点故障,但是现在互联网企业动辄大几百 G 的数据,可完全是没法满足业务的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。

Redis 应用场景

  1. 缓存数据:最常用,对经常需要查询且变动不是很频繁的数据。
  2. 消息队列:相当于消息订阅系统,类似与 RabbitMQ、ActiveMQ、RocketMQ。如果对数据有较高一致性要求时,还是建议使用 MQ。
  3. 计数器:比如统计点击率、点赞率,Redis 具有原子性,可以避免并发问题。
  4. 电商网站信息:大型电商平台初始化页面数据的缓存。比如去哪儿网购买机票的时候首页的价格和你点进去的价格会有差异。
  5. 热点数据:比如新闻网站实时热点、微博热搜等,需要频繁更新。总数据量比较大的时候直接从数据库查询会影响性能。
  6. 分布式锁:分布式程序可以用 Redis 来存储锁信息。

Redis 数据类型

类型 说明
string(字符串) string 是 Redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。string 类型是二进制安全的。意思是 Redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象 。string 类型是 Redis 最基本的数据类型,一个键最大能存储 512MB。
hash(哈希) Redis hash 是一个键值对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。每个 hash 可以存储 2 * 32 - 1 键值对(4294967295, 每个哈希可存储 40 多亿个成员)。
list(列表) Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。列表最多可存储 2 * 32 - 1元素 (4294967295, 每个列表可存储 40 多亿个成员)。
set(无序集合) Redis 的 set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。集合中最大的成员数为 2 * 32 - 1 (4294967295, 每个集合可存储 40 多亿个成员)。
zset(有序集合) Redis zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double 类型的分数。Redis 正是通过分数来为集合中的成员进行从小到大的排序。 zset 的成员是唯一的,但分数(score)却可以重复。

Redis 数据类型应用场景

前面提到了 Redis 支持五种丰富的数据类型,那么在不同场景下的选择

string

字符串是最常用的数据类型,他能够存储任何类型的字符串,当然也包括二进制、JSON化的对象、甚至是base64编码之后的图片。在Redis中一个字符串最大的容量为512MB,可以说是无所不能了。

hash

常用作存储结构化数据、比如论坛系统中可以用来存储用户的Id、昵称、头像、积分等信息。如果需要修改其中的信息,只需要通过Key取出Value进行反序列化修改某一项的值,再序列化存储到Redis中,Hash结构存储,由于Hash结构会在单个Hash元素在不足一定数量时进行压缩存储,所以可以大量节约内存。这一点在String结构里是不存在的。

list

List的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis 内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。另外,可以利用 lrange 命令,做基于 Redis 的分页功能,性能极佳,用户体验好。

set

set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,这个时候就可以选择使用set。

zset

可以按照某个条件的权重进行排序,比如可以通过点击数做出排行榜的数据应用。

Redis 优势和缺点

优势:

  1. 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)。
  2. 支持丰富数据类型,支持string,list,set,sorted set,hash。
  3. 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行。
  4. 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除。

缺点:

  1. 由于 Redis 是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然 Redis 本身有 Key 过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
  2. Redis 是单线程的,单台服务器无法充分利用多核服务器的 CPU。

Redis 相比同类型的 Memcached 有哪些优势?

  1. Memcached 所有的值均是简单的字符串,Redis 作为其替代者,支持更为丰富的数据类型。
  2. Redis 的速度比 Memcached 快很多
  3. Redis 可以持久化其数据到硬盘

Redis 常见性能问题和解决方案

  1. Master 最好不要做任何持久化工作,如 RDB 内存快照和 AOF 日志文件
  2. 如果数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
  3. 为了主从复制的速度和连接的稳定性,Master 和 Slave 最好在同一个局域网内
  4. 尽量避免在压力很大的主库上增加从库
  5. 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3…这样的结构方便解决单点故障问题,实现 Slave 对 Master 的替换。如果 Master 挂了,可以立刻启用 Slave1 做 Master,其他不变。

二、Redis 单机安装

服务器系统为 centos 7.5,Redis 版本为 5.0.7,采用源码方式安装。

安装

yum install -y gcc
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
tar xzf redis-5.0.7.tar.gz
cd redis-5.0.7
make
mkdir -p /usr/local/redis/bin
cp src/redis-server /usr/local/redis/bin
cp src/redis-cli /usr/local/redis/bin
cp src/redis-sentinel /usr/local/redis/bin
cp src/redis-trib.rb /usr/local/redis/bin
cp src/redis-check-aof /usr/local/redis/bin
cp src/redis-check-rdb /usr/local/redis/bin
cp src/redis-benchmark /usr/local/redis/bin
echo 'export PATH=$PATH:/usr/local/redis/bin' >> .bash_profile
. .bash_profile
cp ./redis.conf /etc

配置

vim /etc/redis.conf,修改其中配置:

bind 0.0.0.0	# 把 127.0.0.1 改为 0.0.0.0,监听所有 IPV4 地址,可以根据需求设置
daemonize yes # 把 no 修改为 yes,后台运行

启动

$ redis-server /etc/redis.conf

验证

$ redis-cli
127.0.0.1:6379>
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>

也可以通过桌面客户端验证:redis desktop manager - https://github.com/uglide/RedisDesktopManager/releases

设置开机启动

vim /usr/lib/systemd/system/redis.service:

[Unit]
Description=Redis Server
After=network.target [Service]
Type=simple
# User=redis
# Group=redis
PIDFile=/var/run/redis.pid
ExecStart=/usr/local/redis/bin/redis-server /etc/redis.conf --daemonize no
# ExecStop=/usr/local/redis/bin/redis-cli shutdown
ExecStop=/usr/local/redis/bin/redis-cli -p 6379 shutdown
Restart=always [Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start redis
systemctl enable redis

三、Redis 集群安装

2018 年 10 月 Redis 发布了稳定版本的 5.0 版本,推出了各种新特性,其中一点是放弃 Ruby 的集群方式,改为 使用 C 语言编写的 redis-cli 的方式,是集群的构建方式复杂度大大降低。

服务器系统为 centos 7.5,Redis 版本为 5.0.7,采用源码方式安装。在一台服务器上搭建有 6 个节点的 Redis 集群。(因为Redis 集群最低 6 个节点,不然无法创建)

安装

yum install -y gcc
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
tar xzf redis-5.0.7.tar.gz
cd redis-5.0.7
make
mkdir -p /usr/local/redis/bin
cp src/redis-server /usr/local/redis/bin
cp src/redis-cli /usr/local/redis/bin
cp src/redis-sentinel /usr/local/redis/bin
cp src/redis-trib.rb /usr/local/redis/bin
cp src/redis-check-aof /usr/local/redis/bin
cp src/redis-check-rdb /usr/local/redis/bin
cp src/redis-benchmark /usr/local/redis/bin
echo 'export PATH=$PATH:/usr/local/redis/bin' >> .bash_profile
. .bash_profile

创建 6 个配置文件并配置

mkdir /etc/redis-cluster
cp redis.conf /etc/redis-cluster/redis-7001.conf
cp redis.conf /etc/redis-cluster/redis-7002.conf
cp redis.conf /etc/redis-cluster/redis-7003.conf
cp redis.conf /etc/redis-cluster/redis-7004.conf
cp redis.conf /etc/redis-cluster/redis-7005.conf
cp redis.conf /etc/redis-cluster/redis-7006.conf
mkdir /opt/redis-7001
mkdir /opt/redis-7002
mkdir /opt/redis-7003
mkdir /opt/redis-7004
mkdir /opt/redis-7005
mkdir /opt/redis-7006

修改所有的配置文件 (端口以及目录依次类推)

port 7001	# 监听端口
bind 0.0.0.0 # 监听 ip
dir /opt/redis-7001 # 指定文件存放路径 ( .rdb .aof nodes-xxxx.conf 这样的文件都会在此路径下)
cluster-enabled yes # 启动集群模式
cluster-config-file nodes-7001.conf # 集群节点配置文件
daemonize yes # 后台启动
cluster-node-timeout 5000 # 集群节点超时时间​
appendonly yes # 指定持久化方式,开启 AOF 模式
protected-mode no # 非保护模式

启动节点

redis-server /etc/redis-cluster/redis-7001.conf
redis-server /etc/redis-cluster/redis-7002.conf
redis-server /etc/redis-cluster/redis-7003.conf
redis-server /etc/redis-cluster/redis-7004.conf
redis-server /etc/redis-cluster/redis-7005.conf
redis-server /etc/redis-cluster/redis-7006.conf

创建集群

redis-cli --cluster create 192.168.223.111:7001 192.168.223.111:7002 192.168.223.111:7003 192.168.223.111:7004 192.168.223.111:7005 192.168.223.111:7006 --cluster-replicas 1
  • --replicas 1 表示为集群中的每个主节点创建一个从节点,6 个节点就是 3 主 3 从。

结果

>>> 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.223.111:7005 to 192.168.223.111:7001
Adding replica 192.168.223.111:7006 to 192.168.223.111:7002
Adding replica 192.168.223.111:7004 to 192.168.223.111:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[0-5460] (5461 slots) master
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
slots:[5461-10922] (5462 slots) master
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
slots:[10923-16383] (5461 slots) master
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
replicates 15e768a013d6042de80b82aa2274ffcf30381085
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
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.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
slots: (0 slots) slave
replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
slots: (0 slots) slave
replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
slots: (0 slots) slave
replicates 15e768a013d6042de80b82aa2274ffcf30381085
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群信息

$ redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111:7001> 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:371
cluster_stats_messages_pong_sent:382
cluster_stats_messages_sent:753
cluster_stats_messages_ping_received:377
cluster_stats_messages_pong_received:371
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:753
192.168.223.111:7001>

查看节点信息

$ redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111:7001> cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575617014596 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master - 0 1575617015504 3 connected 10923-16383
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 slave 9a347d87b115ab8be8662771aa2d0579465ae6ff 0 1575617014496 4 connected
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 slave 15e768a013d6042de80b82aa2274ffcf30381085 0 1575617014000 5 connected
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575617013000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 master - 0 1575617015000 2 connected 5461-10922
192.168.223.111:7001>

或者

$ redis-cli --cluster check 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 5461 slots | 1 slaves.
192.168.223.111:7003 (15e768a0...) -> 0 keys | 5461 slots | 1 slaves.
192.168.223.111:7002 (9a347d87...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 2 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
slots: (0 slots) slave
replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
M: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
slots: (0 slots) slave
replicates 9a347d87b115ab8be8662771aa2d0579465ae6ff
S: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
slots: (0 slots) slave
replicates 15e768a013d6042de80b82aa2274ffcf30381085
M: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

集群测试

[root@k8s1 ~]# redis-cli -c -h 192.168.223.111 -p 7001
192.168.223.111:7001> set name test
-> Redirected to slot [5798] located at 192.168.223.111:7002
OK
192.168.223.111:7002> set age 18
-> Redirected to slot [741] located at 192.168.223.111:7001
OK
192.168.223.111:7001> get name
-> Redirected to slot [5798] located at 192.168.223.111:7002
"test"
192.168.223.111:7002> get age
-> Redirected to slot [741] located at 192.168.223.111:7001
"18"
192.168.223.111:7001>

可以看到,客户端连接加 -c 选项的时候,存储和提取 key 的时候不断在 7001 和 7002 之间跳转,这个称为客户端重定向。之所以发生客户端重定向,是因为

Redis Cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽(hash slot)的方式来分配的。Redis Cluster 默认分配了 16384 个 slot,当 set 一个 key 时,会用 CRC16 算法来取模得到所属的 slot,然后将这个 key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。所以在测试的时候看到set 和 get 的时候,会跳转节点。Redis 集群会把数据存在一个 Master 节点,然后在这个 Master 节点和其对应的 Salve 节点之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个 Master 节点挂掉之后,才会启动一个对应的 Salve 节点,充当 Master 节点。

扩充:客户端默认只能从 Master 节点上获取数据,不能从 Slave 节点获取;如果需要直接从 Slave 节点获取数据,客户端可以设置为 readonly 模式,具体参考官方文档。

集群故障切换测试

首先查看当前主节点信息:

$ redis-cli -p 7001 cluster nodes | grep master
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master - 0 1575618684601 3 connected 10923-16383
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575618685000 7 connected 5461-10922
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575618685000 1 connected 0-5460

模拟崩溃主节点 7003:

$ redis-cli -p 7003 debug segfault
Error: Server closed the connection

debug segfault 命令执行一个非法的内存访问从而让 Redis 崩溃,仅在开发时用于 bug 调试。

再次查看当前主节点信息:

$ redis-cli -p 7001 cluster nodes | grep master
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 master,fail - 1575618827980 1575618827074 3 disconnected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575618873502 7 connected 5461-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575618875000 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575618873000 1 connected 0-5460

可以看到 7003 已是 fail 状态,并且 7005 已经成为新的 Master 节点

重新启动 7003:

$ redis-server /etc/redis-cluster/redis-7003.conf
81882:C 06 Dec 2019 15:57:17.086 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
81882:C 06 Dec 2019 15:57:17.086 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=81882, just started
81882:C 06 Dec 2019 15:57:17.086 # Configuration loaded $ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575619045171 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575619044666 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575619044000 7 connected 5461-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575619045000 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575619045000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575619044565 7 connected

可以看到重新启动的 7003 已经成为 7005 的 Slave 节点

注意: 当存活的 Master 节点小于总节点数的一半时,整个集群就无法提供服务了。

添加节点

两种情况,添加一个 Master 节点或者 Slave 节点。

添加 Master 节点

redis-cli --cluster add-node 192.168.223.111:7007 192.168.223.111:7001
  • 第一个参数(192.168.223.111:7007) 为新加入的节点,具体配置参照前面部分。
  • 第二个参数(192.168.223.111:7001)为集群中任一正常节点。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575619906900 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575619907405 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575619906601 7 connected 5461-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575619906000 0 connected
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575619907908 9 connected 10923-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575619907000 1 connected 0-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575619906000 7 connected

可以看到已经成功的向集群中添加了 Master 节点 7007,但是这个 Master 节点还没有成为真正的 Master 节点,因为还没有分配槽(slot),也没有从节点,现在要给它分配槽(slot)。

[root@k8s1 ~]# redis-cli --cluster reshard 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
slots: (0 slots) slave
replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
S: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
slots: (0 slots) slave
replicates 478491a5f75d8fbceeaa7a61bbc4866b5893b99c
M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
slots: (0 slots) master
M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
slots: (0 slots) slave
replicates 70b40a69c2ee564cf1e1ff59f26b1a754443509e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 2048 # 指定分配多少个槽
What is the receiving node ID? 0be08034ff73657bb525158821ab0210894af917 # 分配到哪个节点(ID)?
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all # 选择 all Ready to move 2048 slots.
Source nodes:
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
Destination node:
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
slots: (0 slots) master
Resharding plan:
Moving slot 5461 from 70b40a69c2ee564cf1e1ff59f26b1a754443509e
...
...
...
Moving slot 11604 from 192.168.223.111:7005 to 192.168.223.111:7007: $ redis-cli --cluster check 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 4779 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4779 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 1 keys | 2047 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4779 slots | 1 slaves.
[OK] 2 keys in 4 masters.
...
...
...
[OK] All 16384 slots covered.

可以看到新的 Master 节点 7007 已经获取到了新分配的槽,并且其目前还没有 Slave 节点。

添加 Slave 节点

redis-cli --cluster add-node 192.168.223.111:7008 192.168.223.111:7001 --cluster-slave --cluster-master-id 0be08034ff73657bb525158821ab0210894af917
  • 如果不指定 --cluster-master-id 参数, Redis Cluster 会将新加入的 Slave 节点随机分配给一个 Master 节点,这里指定 Master 节点 7007。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575621163000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575621163562 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575621164067 7 connected 6144-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575621163057 10 connected 0-681 5461-6143 10923-11604
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575621164572 9 connected 11605-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575621162000 1 connected 682-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575621165077 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575621163000 7 connected

可以看到 7008 已经成为 7007 的 Slave 节点。

平衡各节点槽数量

当前新加 Master 节点后各节点的槽可能会分配不均匀。

$ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 1 keys | 4779 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4779 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 1 keys | 2047 slots | 1 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4779 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以重新分配

$ redis-cli --cluster rebalance --cluster-threshold 1 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 4 nodes. Total weight = 4.00
...
...
... $ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 2 keys | 4096 slots | 1 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以看到已重新分配。

Slave 节点重新分配

首先查看集群信息

$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622162000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622162506 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622162000 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622162706 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622162000 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622161000 1 connected 1365-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575622161000 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575622162202 7 connected
[root@k8s1 ~]#
[root@k8s1 ~]#

可以看到当前 7002 是 7004 的 Slave 节点,如果想把 7002 变成 7001 的 Slave 节点,则首先登陆 7002 节点执行以下操作:

$ redis-cli -c -h 192.168.223.111 -p 7002
192.168.223.111:7002> cluster replicate b3919787aa7bc4123e5f87b8995680e2187bf4cc
OK
192.168.223.111:7002> exit $ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622409000 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622410891 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622410588 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622409881 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622410083 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622410000 1 connected 1365-5460
629a4e7bafac9522b974b0a12f7cd28d7be51cfd 192.168.223.111:7008@17008 slave 0be08034ff73657bb525158821ab0210894af917 0 1575622409000 10 connected
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622410000 7 connected
[root@k8s1 ~]#
  • b3919787aa7bc4123e5f87b8995680e2187bf4cc 为 7001 的 ID。
  • 可以看到 7002 已经变成 7001 的 Slave 节点。

删除节点

分两种情况:删除 Master 节点和 Slave 节点。

删除 Slave 节点

比较简单

$ redis-cli  --cluster del-node 192.168.223.111:7001 629a4e7bafac9522b974b0a12f7cd28d7be51cfd
>>> Removing node 629a4e7bafac9522b974b0a12f7cd28d7be51cfd from cluster 192.168.223.111:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
  • 629a4e7bafac9522b974b0a12f7cd28d7be51cfd 为 Slave 节点 7008 的 ID。
$ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575622972929 6 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575622972000 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575622972525 7 connected 6827-10922
0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007@17007 master - 0 1575622971515 10 connected 0-1364 5461-6826 10923-12287
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575622971000 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575622972000 1 connected 1365-5460
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575622973030 7 connected

可以看出 7008 已被删除。

删除 Master 节点

删除 Master 节点相对来说就是复杂一点,主要步骤:

  1. 如果 Master 节点有 Slave 节点,则首先要将 Slave 节点重新分配到其他 Master 节点或者删除。
  2. 如果 Master 节点有槽(slot),则需要去掉分配的槽(slot),然后再删除主节点

Slave 节点重新分配与删除 Slave 参考前面部分,这里主要讲下怎么去掉分配的槽(slot),已 7007 节点为例:

$ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 2 keys | 4096 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
  • 7007 有槽
$ redis-cli --cluster reshard 192.168.223.111:7001
>>> Performing Cluster Check (using node 192.168.223.111:7001)
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[1365-5460] (4096 slots) master
1 additional replica(s)
S: ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006
slots: (0 slots) slave
replicates b3919787aa7bc4123e5f87b8995680e2187bf4cc
S: 15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003
slots: (0 slots) slave
replicates 478491a5f75d8fbceeaa7a61bbc4866b5893b99c
M: 70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004
slots:[6827-10922] (4096 slots) master
1 additional replica(s)
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
M: 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005
slots:[12288-16383] (4096 slots) master
1 additional replica(s)
S: 9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002
slots: (0 slots) slave
replicates 70b40a69c2ee564cf1e1ff59f26b1a754443509e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 4096 # 7007 的槽个数
What is the receiving node ID? b3919787aa7bc4123e5f87b8995680e2187bf4cc # 由谁来接手 7007 的槽
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: 0be08034ff73657bb525158821ab0210894af917 # 7007 节点 ID
Source node #2: done Ready to move 4096 slots.
Source nodes:
M: 0be08034ff73657bb525158821ab0210894af917 192.168.223.111:7007
slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
Destination node:
M: b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001
slots:[1365-5460] (4096 slots) master
1 additional replica(s)
Resharding plan:
Moving slot 0 from 0be08034ff73657bb525158821ab0210894af917
...
...
... $ redis-cli --cluster info 192.168.223.111:7001
192.168.223.111:7001 (b3919787...) -> 2 keys | 8192 slots | 1 slaves.
192.168.223.111:7004 (70b40a69...) -> 0 keys | 4096 slots | 1 slaves.
192.168.223.111:7007 (0be08034...) -> 0 keys | 0 slots | 0 slaves.
192.168.223.111:7005 (478491a5...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.

可以看到 7007 的槽个数已经为 0。执行删除:

$ redis-cli  --cluster del-node 192.168.223.111:7001 0be08034ff73657bb525158821ab0210894af917
>>> Removing node 0be08034ff73657bb525158821ab0210894af917 from cluster 192.168.223.111:7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node. $ redis-cli -p 7001 cluster nodes
ec514db1730a466cf10d3ee54f32003c7690602a 192.168.223.111:7006@17006 slave b3919787aa7bc4123e5f87b8995680e2187bf4cc 0 1575623784000 11 connected
15e768a013d6042de80b82aa2274ffcf30381085 192.168.223.111:7003@17003 slave 478491a5f75d8fbceeaa7a61bbc4866b5893b99c 0 1575623785208 9 connected
70b40a69c2ee564cf1e1ff59f26b1a754443509e 192.168.223.111:7004@17004 master - 0 1575623784000 7 connected 6827-10922
478491a5f75d8fbceeaa7a61bbc4866b5893b99c 192.168.223.111:7005@17005 master - 0 1575623784703 9 connected 12288-16383
b3919787aa7bc4123e5f87b8995680e2187bf4cc 192.168.223.111:7001@17001 myself,master - 0 1575623784000 11 connected 0-6826 10923-12287
9a347d87b115ab8be8662771aa2d0579465ae6ff 192.168.223.111:7002@17002 slave 70b40a69c2ee564cf1e1ff59f26b1a754443509e 0 1575623784198 7 connected

可以看到已删除 7007 节点。

集群升级

分两种情况:升级 Master 节点和 Slave 节点。

升级 Slave 节点

升级 Slave 节点比较简单,只需要停止 Slave 节点,然后升级 Redis 程序,最后重启即可。

升级 Master 节点

升级 Master 节点相对来说复杂一点,主要步骤:

  1. 使用 debug segfault 使 Master 节点发生故障转换为 Slave 节点(参考前面部分)。
  2. 然后再照升级 Slave 节点的方法升级此节点。

Redis 5.0.7 讲解,单机、集群模式搭建的更多相关文章

  1. redis 5.0.3 讲解、集群搭建

    REDIS 一 .redis 介绍 不管你是从事Python.Java.Go.PHP.Ruby等等... Redis都应该是一个比较熟悉的中间件.而大部分经常写业务代码的程序员,实际工作中或许只用到了 ...

  2. Presto单机/集群模式安装笔记

    Presto单机/集群模式安装笔记 一.安装环境 二.安装步骤 三.集群模式安装: 3.1 集群模式修改配置部分 3.1.1 coordinator 节点配置. Node172配置 3.1.2 nod ...

  3. 深入剖析Redis系列: Redis集群模式搭建与原理详解

    前言 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...

  4. Zookeeper实战之单机集群模式

    前一篇文章介绍了Zookeeper的单机模式的安装及应用,但是Zookeeper是为了解决分布式应用场景的,所以通常都会运行在集群模式下.今天由于手头机器不足,所以今天打算在一台机器上部署三个Zook ...

  5. Apache Spark 2.2.0 中文文档 - 集群模式概述 | ApacheCN

    集群模式概述 该文档给出了 Spark 如何在集群上运行.使之更容易来理解所涉及到的组件的简短概述.通过阅读 应用提交指南 来学习关于在集群上启动应用. 组件 Spark 应用在集群上作为独立的进程组 ...

  6. Zookeeper简介及单机、集群模式搭建

    1.zookeeper简介 一个开源的分布式的,为分布式应用提供协调服务的apache项目. 提供一个简单的原语集合,以便于分布式应用可以在它之上构建更高层次的同步服务. 设计非常易于编程,它使用的是 ...

  7. Zookeeper的单机&amp;集群环境搭建

    单机环境的安装 首先下载ZK的二进制安装包:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/ 将安装包上传到Linux上: 进行解 ...

  8. 微服务管理平台nacos虚拟ip负载均衡集群模式搭建

    一.Nacos简介 Nacos是用于微服务管理的平台,其核心功能是服务注册与发现.服务配置管理. Nacos作为服务注册发现组件,可以替换Spring Cloud应用中传统的服务注册于发现组件,如:E ...

  9. Spring集成Jedis(不依赖spring-data-redis)(单机/集群模式)(待实践)

    Jedis是Redis的Java客户端,Spring将Jedis连接池作为一个Bean来配置.如果在Spring Data的官网上可以发现,Spring Data Redis已经将Jedis集成进去了 ...

随机推荐

  1. S3C2440的Linux启动过程分析(一)——SC2440处理器结构

    1.1.     S3C2440处理器结构 S3C2440处理器的结构如下图所示,其核心单元为ARM9TDMI处理器核,主要包括16K的指令Cache和16K的数据Cache,以及分开的指令和数据MM ...

  2. win8自动升级win8.1后 wampserver无法启动

    原因是升级时win8把其他的系统服务都给停止了. 解决办法是左键点击wamp的小图标,选择apache/mysql - service - 安装服务. 然后再选择启动服务,即可.

  3. 使用window2003安装邮件服务器最新实际操作记录

    关于使用windows 2003自带的服务组件来安装简单的pop3 协议邮件服务器网上教程很多,可以搜索出来,就是安装IIS选中smtp和添加window是组件的应用程序服务器,这点这里不多说. 安装 ...

  4. Python基础:数值(布尔型、整型、长整型、浮点型、复数)

    一.概述 Python中的 数值类型(Numeric Types)共有5种:布尔型(bool).整型(int).长整型(long).浮点型(float)和复数(complex). 数值类型支持的主要操 ...

  5. SDAccel-FPGA将带来至多25倍单位功耗性能提升

    很久没有看FPGA了,本来想继续学习HLS,就上Xilinx的网站看了看.结果发现了SDx 开发环境,很新的一个东西.由于我对这方面了解不多,本篇博文仅仅只是资料的整合和介绍. 1.SDx开发环境 X ...

  6. OC: Block回调的使用demo

    Block 的用法 对于类的继承问题,子类在实现的时候,一般是自下而上,先看看下面的实现没有,没实现就向上找方法去实现. // // main.m #import <Foundation/Fou ...

  7. 以字符串形式读取github上.json文件

    如下: https://github.com/hpu-spring87/ebooks/blob/master/update.json 如果直接用httpclient读取该URL地址,得到结果是这样的: ...

  8. Python之hashlib模块

    hashlib 在做一个授权管理系统,需要生产动态生成密码,故使用hashlib >>> import time >>> import hashlib >&g ...

  9. Mybatis执行BatchExecutor(四)

    BatchExecutor:顾名思义就是进行批量操作,通过批量操作来提高性能 public class BatchExecutor extends BaseExecutor { public stat ...

  10. python3处理json数据

    获取actuator的值 [root@mongo_rs1 tmp]# cat test.py import requests import json url = 'http://wxtest.mayo ...