一、Redis单机配置
1、从配置的公开仓库,拉取Redis镜像到本地
$ docker pull redis:版本号
# 不加版本号,默认下载最新版本(docker pull redis等同于docker pull redis:lastest)
2、配置redis.conf,确保Redis实例正常启动(两种方式)
进入文件——vim redis.conf
# 指定redis服务器监听任意端口,以便远程访问
bind 0.0.0.0
# 设置密码
requirepass 密码
# 设置守护进程方式为no,因为Docker启动Redis容器实例时,是以守护进程方式启动,这里设置yes可能会干扰容器正常运行
daemonize no
# 设置AOF持久化,以便宿主主机可以同步Docker容器实例中的Redis数据库操作
appendonly yes
3、以守护进程方式启动Redis容器实例
# --name=容器名称(指定容器名称),
# --privileged=true(表示给Redis容器赋予root权限,否则Redis容器只是普通用户权限),
# -v 宿主主机目录或文件:容器目录或文件:rw/ro(指定映射,两者同步,ro代表容器只能读,rw代表容器可以读写),
# -d 表示以守护进程方式运行,
# -p 外部端口:容器端口(指定端口)
# reids镜像:版本号(指定redis镜像和版本)
docker run --name=容器名称 --privileged=ture \
-v 用户指定宿主主机目录/redis.conf:/etc/redis/redis.conf:ro \
-v 用户指定宿主主机目录/data:/data:rw \
-d -p 外部端口:容器端口 redis镜像:版本号
二、Redis集群
1、Redis集群三种算法(对应三种模式)
1.1、哈希取余算法
1.2、一致性哈希算法
1.3、哈希槽算法
1.1、哈希取余算法
通过hash函数对key取余选择存储的服务器节点,假设有n个节点构成集群,那么hash(key)%n选择服务器存储
-
优点:
-
可以达到负载均衡+分而治之(最简单的集群)
-
-
缺点:
-
容错差,一旦有节点宕机,那么相应的数据就无法写入
-
扩容/缩容性差,一旦想加入或取消挂载某个节点,取余算法就变了,所有数据需要重新洗牌
-
1.2、一致性哈希算法
通过算法构建hash环,把服务器IP(或者唯一标识符)通过hash(IP)映射到环上,形成服务器节点;当存储key时,先计算hash(key),顺时针寻找最近的一个hash(IP)对应的节点进行存储
-
优点:
-
容错好,由服务器宕机,本来存储到该节点的key顺时针自动到下一个最近节点
-
扩容性好,当新增服务器节点,比如在A,B之间加入一个X,只需要把原来处于A-X之间的key,有B节点转移到X节点即可,不用把所有数据重新计算
-
缩容性好,本来存储到该节点的key顺时针自动到下一个最近节点
-
-
缺点:
-
数据倾斜,如果服务器节点很少,在hash环上分布不均匀,那么有的服务器负载会很大,有的却很小(却决于自己所管理的环上的一段区域)
-
可以通过增加虚拟节点,并把虚拟节点重新分配给物理节点,来解决该问题
-
1.3、哈希槽算法
通过CRC16算法,Redis分出2^14(16384)个槽来,通过把槽划分给不同的服务器节点,实现存储,新的KEY计算CRC16(KEY)得到hash槽的位置,存入对应的Redis服务器
-
优点:
-
扩容性好,当新增服务器节点,只需要从某几个节点划分一些槽号给新的节点,此时这些槽号对应的key数据也一同转移到新节点上
-
缩容性好,当减少服务器节点,只需要该节点的槽号和对应的key数据转移给其他节点即
-
2 、Redis集群配置
2.1 创建Redis集群(以三主三从为例)
# 首先创建Redis容器实例,端口号从6381-6386
for port in $(seq 6381 6386); \
do \
docker run -d --name=redis-node-${port} --net host --privileged=true \
-v 宿主主机目录/redis-node-${port-node}/data:/data \
redis镜像:版本号 \
--cluster-enabled yes \
--appendonly yes \
--port ${port} \
; done
# 完整命令
for port in $(seq 6381 6386); \
do \
docker run -d --name=redis-node-${port} --net host --privileged=true \
-v /xhbb/docker/redis-node-${port}/data:/data \
redis \
--cluster-enabled yes \
--appendonly yes \
--port ${port} \
; done
# 查看容器实例是否正常启动(一定检查,确保配置正确,且容器实例运行正常)
docker ps
# 以交互式模式进入其中任意一个容器实例的bash(以名称为redis-node-6382的容器实例为例)
docker exec -it redis-node-6382 /bin/bash
# 配置集群,--cluster-replicas 1指定每个master有一个slave
redis-cli --cluster create 宿主主机IP(非127.0.0.1):端口1 宿主主机IP:端口2 ... --cluster-replicas 1
# 完整命令
redis-cli --cluster create 192.168.1.11:6381 192.168.1.11:6382 192.168.1.11:6383 192.168.1.11:6384 192.168.1.11:6385 192.168.1.11:6386 --cluster-replicas 1
# 查看集群中已上线的节点(未上线的不显示)
redis-cli --cluster check 宿主主机IP:集群任意节点的端口
# 进入redis客户端也可以查看
redis-cli -p 6381 -c # 设置-c参数,可以在CREC16(key)对应的槽号不是本服务器时,跳转到相应的服务器(否则会报错)
cluster info # 查看集群的部署信息(即便节点未上线)
cluster nodes # 查看集群的节点的信息(即便未上线)
2.2 Redis集群增加和删除节点(扩容、缩容)
2.2.1 Redis集群增加节点
Redis集群增加节点时,主从节点的添加方式有所区别:
(1)新增主节点:
新建一个Redis容器实例;
进入集群任意容器实例,把新增节点加入集群;
重新分配槽号,把集群其他节点的槽号划分部分出来,给到新节点,同时这些槽号对应的数据也转移到新节点上
(2)新增从节点
新建一个Redis容器实例;
进入集群任意容器实例,把新增节点加入集群,同时设置它为集群任意一个主节点的从节点
# 增加master节点分三步,先新建一个Redis容器实例,再加入集群,最后分配槽号给它
# 1、新建节点
docker run -d \
--name 新建节点名称 \
--net host \
--privileged=true -v 用户指定的宿主主机目录/data:/data \
redis \
--cluster-enabled yes \
--appendonly yes \
--port 新建节点的端口
# 2、添加到Redis集群
redis-cli --cluster add-node 宿主主机IP:新增的端口 宿主主机IP:集群任意上线节点的端口
# 3、分配槽号,需要从集群的其他节点划分槽号,并把这些槽号对应的数据转移到新节点上
redis-cli --cluster reshard 宿主主机IP:新增的端口
# 完整命令,以新增6387端口的节点为例,从所有节点划分4096个槽给它
docker run -d \
--name redis-node-6387 \
--net host \
--privileged=true -v /xhbb/docker/redis-clusters/node-6387/data:/data \
redis \
--cluster-enabled yes \
--appendonly yes \
--port 6387
# 进入任意一个节点的容器实例后
redis-cli --cluster add-node 192.168.1.11:6387 192.168.1.11:6382
redis-cli --cluster reshard 192.168.1.11:6387
#########################################################################################
# 增加slave节点分两部步,新建一个Redis容器实例,加入集群同时设置为其他master的slave
# 加入集群并设置为slave的命令如下
redis-cli --cluster add-node 宿主主机IP:新增节点端口 宿主主机IP:集群任意节点的端口 --cluster-slave --cluster-master-id 指定的master在集群中的ID
# 以新建一个端口为6388的节点,设置为6387的slave为例
docker run -d \
--name redis-node-6388 \
--net host \
--privileged=true -v /xhbb/docker/redis-clusters/node-6388/data:/data \
redis \
--cluster-enabled yes \
--appendonly yes \
--port 6388
# 进入任意一个节点的容器实例后
redis-cli --cluster add-node 192.168.1.11:6388 192.168.1.11:6382 --cluster-slave --cluster-master-id 5f0981d6c17d001bec6a36d0b2ae33c5bc11f77e
2.2.2 Redis集群删除节点
Redis删除节点时,主从节点的删除有所区别(一般先删除从节点,后删除主节点)
(1)删除从节点:
直接删除
(2)删除主节点:
先把主节点上的槽号划分给集群其他节点,同时槽号对应数据转移到其他节点,此时要删除的主节点的槽号为0,没有key数据
删除该节点
# 删除从节点
redis-cli --cluster del-node 宿主主机IP:要删除节点的端口 要删除节点在集群中的ID
# 以删除端口为6388的从节点为例
redis-cli --cluster del-node 192.168.1.11:6388 b8d2b89e01f9959f0710ece0beb534cf3e78d1da
###########################################################################################
# 删除主节点,先把槽号清空(划分给其他节点,对应key数据也转移)
redis-cli --cluster reshard 宿主主机IP:要删除节点的端口
# 查看集群状态(确保该节点没有槽号和数据)
redis-cli --cluster check 宿主主机IP:集群任意节点的端口
# 删除节点
redis-cli --cluster del-node 宿主主机IP:要删除节点的端口 要删除节点在集群中的ID
# 以删除端口为6387的主节点为例
redis-cli --cluster reshard 192.168.1.11:6387
# 查看集群状态(确保该节点没有槽号和数据)
redis-cli --cluster check 192.168.1.11:6381
# 删除节点
redis-cli --cluster del-node 192.168.1.11:6387 5f0981d6c17d001bec6a36d0b2ae33c5bc11f77e
2.2 Redis集群扩容、缩容
(1)扩容:
在原有集群的基础上,新增一组主从节点即可(先新增主节点、再新增从节点)
(2)缩容:
删除集群中的某组或几组主从节点(先删除从节点、再删除主节点)
2.3 Redis集群的主从机宕机说明(假设节点A为原主机、节点B为原从机)
(1)节点A宕机,此时节点B会自动变为主机
(2)当(1)发生后,节点A又恢复运行,此时节点A自动变为从机
(3)当(2)发生后,节点B又宕机,此时节点A重新变为主机
备注:
若集群的一组主从机全部宕机,则集群无法正常运行(因为会有一组槽号没有对应的服务器)
本文详细介绍了如何在Docker环境下配置Redis单机和集群,包括Redis配置文件的修改、容器的启动以及三种集群算法的优缺点。在集群配置中,重点阐述了创建、扩容和缩容的过程,以及主从节点的故障转移情况。此外,还讨论了Redis集群的主从机宕机处理策略。
989

被折叠的 条评论
为什么被折叠?



