一篇文章搞定:docker安装redis,集群,扩容,缩容

Hi,大家好,我是抢老婆酸奶的小肥仔。

今天我们直接进入主题,来说说docker安装redis的一些相关操作。

1、单机版

1.1 拉去镜像

使用docker pull拉取redis镜像,以redis:6.0.8版本为例。

docker pull redis:6.0.8

在这里插入图片描述

1.2 创建文件夹并创建配置文件

在home目录下创建redis目录,创建redis的配置文件redis.conf,并拷贝redis的原始配置内容。

配置事项:与linux安装配置一样。

mkdir -p /home/redis

vim /home/redis/redis.conf

原始配置文件内容,可以在网上找。

1、开启redis验证,即设置密码(可选项)

requirepass 123456

2、允许外部连接redis

即将bind 127.0.0.1进行注释,修改protected-mode为no或指定绑定ip。

# bind 127.0.0.1

protected-mode no

3、daemonize no

将daemonize yes进行注释或daemonize no设置。

daemonize no

# daenmonize yes

因为该设置和docker run 中-d参数冲突,会导致容器启动失败。

4、开启redis数据持久化(可选项)

appendonly yes

1.3 创建容器

使用docker run命令创建redis的容器。

docker run \
--restart=always \
--privileged=true \
-p 6379:6379 --name redis \
-v /home/redis/redis.conf:/etc/redis/redis.conf \
-v /home/redis/data:/data \
-d redis:6.0.8 redis-server /etc/redis/redis.conf

此时用命令查询,可以看到redis的容器。
在这里插入图片描述

1.4客户端连接redis

验证redis是否能够被客户端正常连接,并使用。

将配置文件中的将保护模式更改为no,即protected-mode yes改成protected-mode no。

protected-mode yes 改为 protected-mode no

使用客户端连接redis,我这边使用的是DbGate进行连接,改工具既可以连接mysql也可以连接redis,mongodb等,界面与其他客户端大同小异。
在这里插入图片描述

Connection-type:连接类型,选择redis,

Server:redis服务的ip

Port:端口

User:用户

Password:密码

点击连接,出现如下界面,即能看到redis的16个数据库,则表示连接成功。
在这里插入图片描述

至此,单机版的redis部署完成。

2、集群版

在搭建集群时,一般会涉及到节点的分区,在redis中节点分区有三种常见算法:哈希取余算法,一致性哈希算法,哈希槽算法。我们来分别 看下这些算法。

2.1 分区算法

2…1.1 哈希取余算法

算法描述:hash(key) %N:key:redis存储的键名,N:redis集群的机器台数。即通过对存储的键名进行hash计算,对机器台数进行取余来决定存储在那台机器上。

优点:1、简单直接,只需要规划好节点,就能支持一段书简的数据支撑。

2、负载均衡,分而治之:Hash算法能让固定的一部分数据落到同一台机器上,每台机器能固定处理一部分请求。

缺点对扩容/缩容不友好:节点的变动会导致N的变化,取模运算的结果会发生很大变化,导致根据公式获取的服务器变得不可控。导致hash取余的全部数据都要进行重新计算

2.1.2 一致性哈希算法

算法背景为了解决哈希算法中存在的分布式缓存数据变动和映射问题。即当服务器数量发生变化时,尽量减少影响到客户端与服务器端的映射关系

算法步骤1、构建一致性哈希环

一致性哈希环,即有个hash函数并按照算法产生hash值,然后将产生的哈希值构建成一个全量集,这个集合的hash空间[0,2^32-1],再通过适当逻辑将其首尾相连构成环形空间。一致性hash环是按照数字顺时针进行组织。如图:
在这里插入图片描述

一致性hash算法:是对2^32 取模,即将hash取余算法中的机器数N换成2^32即可。

2、服务器IP节点映射:服务器(IP或主机名)进行hash计算,从而确定其在hash环上的位置。

3、落键规则:即key落到服务器上的规则,即将要存储的数据key进行hash计算(hash(key)),然后沿环顺时针“行走”,遇到的第一台服务器就是该key定位到的服务器,并将该键值存储到该服务器上。

例如:在hash环上有4个服务器,需要保存键值数据kv,经过key的hash计算,发现匹配第一台到第二台服务器中间,则顺时针找到第二台服务器,并将kv保存到该服务器上。如图:
在这里插入图片描述

优点1、容错性:即解决了哈希取余算法中存在缺点,当某个节点服务器宕机时,该服务器上的数据则会顺时针移动到下一个节点服务器。例如上面说的server-2宕机后,保存在server-2上的k-v数据则会顺时针保存到server-3节点服务器上。

2、扩展性:当需要添加新节点服务器时,通过hash计算落在某两个节点服务器之间,此时受影响的只有当前两个节点服务器。

缺点数据倾斜问题,当节点比较少时,容易因为节点服务器分布不均匀而导致数据倾斜。
在这里插入图片描述

2.1.3 hash槽分区

算法描述:为了解决一致性hash算法中的数据倾斜问题。其相当于是一个数组,数组[0,2^14 - 1]形成的hash slot空间。相当于在数据和节点服务器之间又加入一层,在这一层就是哈希槽(slot),用于管理数据和节点之间的关系, 此时节点服务器中存放的是槽,而槽里面放的是数据。

槽解决的是粒度问题,相当于把粒度变大,这样便于数据移动。

哈希解决的是映射问题,使用key的哈希值来计算所在槽,便于数据分配。

redis集群只有16384个槽。

经典问题:为什么redis集群的最大槽数是16384个?

答:redis集群没有使用一致性hash算法而是引入哈希槽的概念,CRC16算法产生的hash值有16bit,可以产生2^16 = 65536值,但是为了心跳方便和数据传输最大化,因此才用2^14=16384个。

1、心跳过大,造成宽带浪费:如果槽个数是65536时,其心跳信息通过myslots[CLUSTER_SLOTS/8] = 65536/8/1024 = 8kb计算会达到8k,显得过于庞大,redis在每秒一定数据量的ping消息作为心跳时,就会造成宽带浪费。

2、主节点数量基本不可能超过1000个,当redis集群主节点数不可能超过1000个时,集群节点越多,心跳包的消息体携带的数据就越多。如果集群主节点数超过1000个时,就会造成网络拥堵。因此redis作者不建议redis集群主节点超过1000个,对于1000主节点以内的集群,16384个槽位足够使用,没必要扩展到65536个。

3、槽位越小,节点少的情况下压缩比越高,容易传输,主节点配置信息中它所负责的哈希槽是通过一张bitmap的形式来保存,在传输过程中会对bitmap进行压缩,但是如果bitmap的填充率slots/N(N节点数) 很高的话,bitmap的压缩率就很低,而哈希槽越多,节点越少,bitmap压缩率就越低。

Redis集群原理:即将16384个槽按照一定策略(可以指定编码的槽分配给主节点,也可以是redis集群自动分配)映射给主节点,当需要存储一个k-v时,redis先对key使用CRC16计算出一个结果,然后对16384取余,即slot = CRC16(key) % 16384 这样每个key都有对应一个在0到16383之间的哈希槽,也就能映射到某个节点上。

2.2 redis集群搭建

上面知道了redis分区的一些算法,下面我们来搭建一个3主3从的redis集群。

2.2.1 创建redis容器

搭建3主3从的集群,则需要创建6个容器。

# 启动第1台节点
docker run -d --name redis-master-6380 --net host --privileged=true -v /home/redis/cluster/master/6380:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6380

# 启动第2台节点
docker run -d --name redis-master-6381 --net host --privileged=true -v /home/redis/cluster/master/6381:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381

# 启动第3台节点
docker run -d --name redis-master-6382 --net host --privileged=true -v /home/redis/cluster/master/6382:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382

# 启动第4台节点
docker run -d --name redis-slave-6390 --net host --privileged=true -v /home/redis/cluster/slave/6390:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6390

# 启动第5台节点
docker run -d --name redis-master-6391 --net host --privileged=true -v /home/redis/cluster/slave/6391:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6391

# 启动第6台节点
docker run -d --name redis-master-6392 --net host --privileged=true -v /home/redis/cluster/slave/6392:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6392

参数说明:

--net host 使用宿主机的IP和端口,默认

--cluster-enabled yes开启redis集群

--appendonly yes 开启redis持久化

--port 6381 配置redis端口号

执行完上述命令后,此时6台容器已执行完成,使用docker ps -a查看容器。

在这里插入图片描述

2.2.2 构建主从关系

主要是通过redis-cli --cluster create进行构建,后面加上6个redis的ip:端口。

# 宿主机IP:端口
redis-cli --cluster create IP:端口 IP:端口 --cluster-replicas 1

--cluster-replicas 1:表示集群关联是一对一,即为每一个主节点创建一个从节点。

--cluster create:集群创建。

IP:端口:即我们需要创建集群的所有redis节点,例如我们需要构建6个节点的集群,则需要添加6个节点的ip和端口

选择进入一个我们认定的redis主节点容器执行该命令。

docker exec-it redis-master-6380 /bin/bash

执行上述命令。

# 宿主机IP:端口
redis-cli --cluster create 192.168.132.113:6380 192.168.132.113:6381 192.168.132.113:6382 192.168.132.113:6390 192.168.132.113:6391 192.168.132.113:6392 --cluster-replicas 1

执行完当前命令后,我们会看到如下信息:
在这里插入图片描述

redis自主帮我们分配了主节点,从节点。同时也完成了一对一的设置,如主节点6380挂载的从节点是6390。

细心的小伙伴会发现上面截图中会有一串警告:
在这里插入图片描述

通过翻译我们应该也知道是因为从节点与主节点都使用了相同的IP,这个警告可以直接忽略。

执行完命令后,会出现Can I set the above configuration? (type 'yes' to accept) 输入yes,redis会向其他节点发送信息加入集群,并真正地分配哈希槽。

2.2.3 查看集群状态

进入主节点容器,例如上面看到的6380.

docker exec -it redis-master-6380 /bin/bash

然后使用redis-cli连接其他主节点,例如连接6381节点

redis-cli -p 6381

在这里插入图片描述

此时是能正常进入该节点。

使用cluster info查看集群状态。

cluster info

在这里插入图片描述

此时会看到一些哈希槽的相关信息,例如cluster_slotexits_assigned:16384:表示哈希槽的个数,cluster_slots_ok:16384:状态良好的哈希槽个数等等。

cluster nodes

可以查看集群节点的信息。
在这里插入图片描述

进入任一节点容器,输入以下命令可以检查集群信息。

# 输入任意一台主节点地址都可以进行集群检查
redis-cli --cluster check 192.168.xxx.xxx:6380

在这里插入图片描述

2.3 集群读写

由于集群中每个节点都只是会分配到16384个哈希槽的一部分,在当前节点保存数据时,计算出key的值可能不在当前节点所分配的哈希槽范围内,此时如果仅仅使用redis-cli -p IP:端口进行节点连接进行操作的话就会出现问题。
在这里插入图片描述

此时就会报错提醒:(eroor)MOVED,也就是计算哈希槽在其他节点。

解决:要解决上述问题,只需要在连接节点时在命令后面加上-c即可

redis-cli -p IP:端口 -c

在这里插入图片描述

2.4 主从扩容

在现实使用redis集群时,有时候会因为空间不足,而需要对集群进行扩容,例如我们的三注三从,扩容成四主四从。接下来我们来看下redis的扩容。

2.4.1 添加容器

既然是四主四从,那我们就再添加两个节点。即根据2.2.1来分别添加6383,6393两个节点。

# 启动第7台节点
docker run -d --name redis-master-6383 --net host --privileged=true -v /home/redis/cluster/master/6383:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383

# 启动第8台节点
docker run -d --name redis-slave-6393 --net host --privileged=true -v /home/redis/cluster/master/6393:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6393

查看docker中redis的容器,发现已经创建了两个新的容器。
在这里插入图片描述

2.4.2 加入集群

将6383作为新的节点加入到集群中。

进入6383容器中

 docker exec -it redis-master-6383 /bin/bash

将6383作为主节点加入到集群中

redis-cli --cluster add-node 192.168.xxx.xxx:6383 192.168.xxx.xxx:6380

add-node:即要加入主节点,如上面的6383,其后是已加入集群的主节点ip:端口。
在这里插入图片描述

查看当前集群情况

redis-cli --cluster check 192.168.xxx.xxx:6380

在这里插入图片描述

查看集群情况会发现,6383节点已加入集群,但是没有分配任何哈希槽,接下来则需要分配哈希槽。

2.4.3 分配哈希槽

执行如下命令:

redis-cli --cluster reshard 192.168.132.113:6380

执行完命令后,我们会看到如下询问:How many slots do you want to move (from 1 to 16384)?,即需要移动多少个槽点。
在这里插入图片描述
分配槽点的计算方法:slot = 16384/主机数,如上面集群中存在4个主节点,则slot = 16384 / 4 = 4096,输入4096后,回车,则会出现:What is the receiving node ID?即需要分配槽点的节点Id,我们添加的是6383的节点,因此输入6383对应的节点id。
在这里插入图片描述

然后提示分配槽点的方式:
在这里插入图片描述

all:即从之前的主节点中,每一个都分配一部分给新加入的主节点。

down:即自己输入哪些节点分配槽点给新加入的主节点。

一般直接输入:all即可。redis自动开始从其他主节点移动槽点。
在这里插入图片描述

移动完成后,则需要继续执行计划,输入:yes
在这里插入图片描述

即可完成将移动的槽点移到新的主节点。
在这里插入图片描述

2.4.4 添加从节点

即将6393作为6383的从节点,加入到集群中,命令:

redis-cli --cluster add-node 192.168.132.113:6393 192.168.132.113:6383 --cluster-slave --cluster-master-id 主节点编码

在这里插入图片描述

查看节点信息,会发现6393已经作为6383的从节点,加入到集群中.
在这里插入图片描述

至此,完成了redis的主从扩容已完成。

2.5 主从缩容

有扩容,当然也有缩容,高峰期过后,我们需要将4主4从,改回3主3从,将添加的6383进行删除,下面我们来看看,redis的缩容。

具体步骤:1.删除从节点 2.移除主节点的哈希槽

2.5.1 获取编号

获取6383的编号,即需要删除节点的编号。进入集群任意主节点,然后检查集群,即可获取6383编号。
在这里插入图片描述

2.5.2 删除从节点

先将从节点6393进行删除

redis-cli --cluster del-node 192.168.132.113:6393 6393对应ID 

在这里插入图片描述

2.5.3 重新分配哈希槽

即需要集群中的主节点上的哈希槽进行重新分配,使用一个其他主节点来接收分配后的哈希槽,命令如下:

#reshard任意集群的主节点,例如:6383主节点
redis-cli --cluster reshard 192.168.xxx.xxx:6383

输入当前命令后,输入需要移除的槽点数量,之前我们计算得到4096个槽点数,因此当前也需要输入4096,然后输入需要接收这些槽点的节点Id。
在这里插入图片描述

注:上面参数必须要清楚对应,否则无法进行哈希槽重新分配.

配置上述节点后,输入done即可进行重新分配哈希槽.

此时会看到6383上的哈希槽已经被移除.
在这里插入图片描述

2.5.4 删除主节点

使用命令删除6383节点

redis-cli --cluster del-node IP:端口 节点编号

如果在没有移除哈希槽时进行删除节点则会报如下错误:
在这里插入图片描述

输入正确命令执行后,主节点被删除。
在这里插入图片描述

2.5.5 查看集群

再次查看集群,发现6383、6393已经被删除,完成了集群的缩容,恢复到3主3从。
在这里插入图片描述

docker安装redis就跟大家聊到这,如果觉得有用的话,记得点赞,收藏,关注哦。谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值