Redis-cluster-docker版
小编个人喜好实战,涉及的理论请自行百度,废话不多说,下面开始实操,以下安装教程是以前小编搭建的时候记录的笔记,小编不让大家踩坑,近期已经按照以下步骤重新尝试过
1,Redis的演变过程
单机模式
最简单的,直接安装一个redis,启动之后,业务调用即可,需要注意的就是redis.conf,里面的几个参数需要改改,比如守护进程,ip限制等等
-
优点
- 零成本,部署很简单
- 没有备用节点,不需要那么大的开支
- 不需要同步数据,不用担心数据不一致问题
-
缺点
- 高峰下容易宕机
- 处理业务有限
- 受限于CPU处理能力,因为是单机的
主从模式
主从是基于单机演变的,讲述的是单机版的redis,对所有的读和写操作都是基于一个redis去操作的,当达到一定请求量时会导致处理速度变慢和宕机,所以就演变出了主从复制,主 -> 写,从 -> 读,读写分离,不再是由一台redis进行工作
-
优点
- 能承受更多的并发,读写不再是一个redis处理了
- 高性能,当主宕机了,从机能上位,但是需要手动调整
- 作为redis高可用的基石,主宕机了从可以随时替代上来(不自动)
-
缺点
- 不具备自动处理容错和恢复功能,当主宕机了,从必须手动调整才能变成主
- 主节点的写能力受到单机的限制
哨兵模式
在redis 2.9版本开始引入哨兵模式,实现类自动化故障修复,哨兵模式是从主从复制继续演变的,基于主从复制进行了升华和扩展,当主节点宕机时,能够自动进行选举机制,选出一位从节点上位当主节点
- 优点
- 哨兵模式基于主从,主从所具有的优点,哨兵都具有
- 能够自动化故障修复,主宕机了,从自动上位
- 缺点
- 很难支持在线扩容,集群越多越复杂
集群模式
既然都有哨兵模式了,那为什么还需要redis集群呢?哨兵模式虽然能自动化修复故障,但是单台redis写和存,访问是有上限的,所以redis集群是基于哨兵模式的升级版,解决了哨兵模式单台redis写和存,访问的瓶颈
Redis Cluster 集群模式具有 高可用、可扩展性、分布式、容错 等特性
数据存储:通过数据分片的方式来进行数据共享问题,同时提供数据复制和故障转移功能
每个集群存储的全部key最多就只能有16384个,我们称之为槽,当有写的命令时,会对该key进行计算,最后得出来的值是什么,就会存到对应的槽位 -> HASH_SLOT = CRC16(key) & 16384
CRC16是一种循环校验算法,这里用了位运算得到取模结果,位运算的速度高于取模运算
- 优点
- 对集群的每个主节点都分配了一片区域,减少缓存雪崩导致数据丢失带来的意外风险
- 支持在线扩容,高可用,不再是单个主节点进行写操作
- 容错性高,无需Sentinel哨兵监控,主节点宕机了从节点自动顶替,Redis Cluster内部自动将Slave切换Master
- 缺点
- 不支持多数据库空间,单机下的 redis 可以支持到 16 个数据库,集群模式下只能使用 1 个数据库空间,即 db 0
- 重试时间应该大于 cluster-node-time 时间
- 数据通过异步复制,不保证数据的强一致性
- 多个业务使用同一套集群时,无法根据统计区分冷热数据,资源隔离性较差,容易出现相互影响的情况
- Slave 在集群中充当“冷备”,不能缓解读压力,当然可以通过 SDK 的合理设计来提高 Slave 资源的利用率
- Key 作为数据分区的最小粒度,不能将一个很大的键值对象如 hash、list 等映射到不同的节点
- 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构
- master宕机到salve选举master恢复期间服务不可用
2,拉取镜像
docker pull redis:6.0.8
3,新建配置文件redis.tmpl模板
1. 创建文件
# 进入你想放置redis-cluster.tmpl的路径
cd 放置redis-cluster.tmpl的路径
# 开始创建文件
cat >>redis-cluster.tmpl<< 'END'
复制下面的2.文件内容
# 写完文件内容后输入END代表退出并保存
2. 文件内容
# redis 相关配置
# redis 端口号
port ${port}
# RDB 持久化,快照保存频率
# 900秒内,如果超过1个key被修改,则发起快照保存
# 300秒内,如果超过10个key被修改,则发起快照保存
# 60秒内,如果1万个key被修改,则发起快照保存
save 900 1
save 300 10
save 60 10000
# 在进行数据镜像备份时,是否启用rdb文件压缩手段,默认为yes。
rdbcompression yes
# 解决 Redis 被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。
stop-writes-on-bgsave-error no
# 开启 AOF 持久化
appendonly yes
# 设置密码
# requirepass "123456"
# 开启保护模式
protected-mode no
# 设置主库的密码,挂了切换,也需要密码
# masterauth "123456"
# 不限制访问
bind 0.0.0.0
# cluster 相关配置
# 启动集群模式
cluster-enabled yes
# 配置文件指定名称,这个配置文件主要 redis 自己维护,我们不需要管
cluster-config-file nodes.conf
# 连接超时时间
cluster-node-timeout 5000
# 集群 IP,即服务器 IP 改成自己服务器的ip
cluster-announce-ip ip
# 集群端口 - 可以不用动,也可以换成自己的
cluster-announce-port ${port}
# 集群总线端口,用于集群之间进行通信 - 可以不用动,也可以换成自己的
cluster-announce-bus-port 1${port}
4,生成redis集群文件
# 循环根据redis.tmpl模板 生成redis.conf
# 6371 6379代表从6371开始循环,直到6379
# 下面的redis.tmpl路径和要生成的redis.conf路径改成自己的,我的是/application/docker/redis/cluster
for port in `seq 6371 6379`;
do \
mkdir -p /application/docker/redis/cluster/${port}/conf \
&& port=${port} envsubst < /application/docker/redis/cluster/redis-cluster.tmpl > /application/docker/redis/cluster/${port}/conf/redis.conf \
&& mkdir -p /application/docker/redis/cluster/${port}/data; \
done
5,创建网络
docker network create redis-cluster
6,启动redis
# 循环启动redis
# 6371 6379代表从6371开始循环,直到6379
# 下面的redis路径改成自己的,我的是/application/docker/redis/cluster
for port in $(seq 6371 6379); \
do \
docker run -d --name redis-${port} \
-p ${port}:${port} -p 1${port}:1${port} \
--net redis-cluster \
--restart always \
--sysctl net.core.somaxconn=1024 \
-v /application/docker/redis/cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /application/docker/redis/cluster/${port}/data:/data \
redis:6.0.8 redis-server /usr/local/etc/redis/redis.conf; \
done
7,检查redis是否全部启动成功
docker ps
8,检查是否以集群启动
ps -ef | grep redis
# 只要是后面带cluster的,代表该redis是以集群模式启动的,如果不是说明有问题
9,进入redis的容器内部
# 可以随意进入一个,这里我就直接进入6371这个redis了
docker exec -it redis-6371 /bin/bash
10,打开安全组
redis的端口:
6371 - 6379
redis-cluster的端口
16371 - 16379
因为redis-cluster内部通信是用集群总线的端口进行通信的
11,组建redis集群
# --cluster create代表创建集群
# ip:port 代表当前想哪些redis服务组成的集群,因为我搭建的是3主6从,所以要有9个redis服务,每个主下面有2 个从,如果搭建3主3从,那就要6个服务就好
# --cluster-replicas 2 代表每个主有几个从,我是9个redis,所以定义2,刚好就是3主,每主2从,如果想3主3从,那就把2改成1就行了
redis-cli --cluster create
ip:port ip:port
ip:port ip:port
ip:port ip:port
ip:port ip:port
ip:port
--cluster-replicas 2
举例:
redis-cli --cluster create ip:port ip:port ip:port ip:port ip:port ip:port ip:port ip:port ip:port --cluster-replicas 2 -a 密码
-a 代表有密码的时候才加
# 输入组建集群指令之后,会问你,这样分配是否可以,输入:yes就行,然后redis就会按照上面的分配去创建集群
yes
12,登录redis
redis-cli -c -p 端口
-c代表以集群形式登录
到这代表redis-cluster已经安装好,以下是一些扩展命令
13,扩展命令 -
1. 循环停止并删除容器
# 循环停止并且以redis-6371到redis-6379开头的容器
for port in $(seq 6371 6379); \
do \
docker stop redis-${port} && docker rm redis-${port}; \
done
2. 添加指定某个主节点下的从节点
方式1
# ip1和port1 代表即将新增的节点
# ip2和port2 代表已经存在的节点
# 主节点id 代表你要指定添加的主节点id
redis-cli
--cluster add-nodes
ip1:port1 ip2:port2
--cluster-slave --cluster-master-id 主节点id
方式2
# 需要先添加一个节点(默认为主,但不分配槽位)
docker exec -it 即将变成从节点的容器名字 /bin/bash
# 比如我新加了redis服务,端口为6389,我想让6389成为某个主节点的从节点,那下面就填6389
redis-cli -c -p 即将要变成从节点的端口
# 登入进redis客户端之后,执行该命令,主节点id要换成你想要添加6389做为从节点的id,不是容器id,是节点id
cluster replicate 主节点的id
3. 添加主节点
redis-cli --cluster add-node 新增redis到的ip:新增redis到的port 原集群任一redis的ip:原集群任一redis的port
4,删除节点
redis-cli --cluster del-node 要删除的ip:要删除的port 要删除的节点id
5,移动槽位
# ip和port是集群里面任一一台的ip和port就行了
redis-cli --cluster reshard ip:port
# 然后会问你要分配多少槽位出来 填对应的槽位就行了
# 然后会问你这些槽位要添加到哪个服务,填主节点的节点id就行了
# 然后会问你,是每个主节点都贡献一点凑齐,还是从单个节点去扣,一般选择all,代表从全部主节点一起贡献
# 然后输入yes就行了
6,查看集群节点
cluster nodes
7,查看集群信息
cluster info
14,注意点
注:当连接redis客户端时,如果没有加-c,set值不能达到路由分发,get值也是一样