【006】Redis主从/哨兵/分片集群Docker搭建
迪丽瓦拉
2024-06-01 01:35:27
0

项目源码合集 https://gitee.com/qiuyusy/small-project-study

搭建过程疯狂踩坑,记录一下希望各位少走弯路

目录

    • 主从搭建
      • 配置文件redis.conf
      • 运行容器
      • 测试
      • 优化
    • 哨兵集群
      • 配置文件
      • 运行容器
      • 测试
      • 代码
      • 读写分离
    • 分片集群

mkdir -p /opt/docker/redis_study/redis_0/conf
mkdir -p /opt/docker/redis_study/redis_0/datadocker run -p 6379:6379 --name redis_0 \
-v /opt/docker/redis_study/redis_0/data:/data \
-v /opt/docker/redis_study/redis_0/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf --appendonly yes

主从搭建

主 redis_0 7001

从 redis_1 7002

从 redis_2 7003

mkdir -p /opt/docker/redis_study/redis_0/conf
mkdir -p /opt/docker/redis_study/redis_0/data
mkdir -p /opt/docker/redis_study/redis_1/conf
mkdir -p /opt/docker/redis_study/redis_1/data
mkdir -p /opt/docker/redis_study/redis_2/conf
mkdir -p /opt/docker/redis_study/redis_2/data

配置文件redis.conf

/opt/docker/redis_study/redis_0/conf

记得配置文件需要关闭aof appendonly no

replica-announce-ip 192.168.222.128 设置IP地址

加入bind 0.0.0.0,这个很重要

把配置文件cp 到 两个从的目录下

然后在两个从机的配置中添加replicaof 192.168.222.128 7001,设定为主机的从机

5.0之前用 slaveof 5.0以后用replicaof

运行容器

注意这里三个节点容器内的端口别都设为6379!这样IP和端口相同会导致后面哨兵集群无法选出新的主节点

主 redis_0 7001

docker run -p 7001:7001 --name redis_0 \
-v /opt/docker/redis_study/redis_0/data:/data \
-v /opt/docker/redis_study/redis_0/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

从 redis_1 7002

docker run -p 7002:7002 --name redis_1 \
-v /opt/docker/redis_study/redis_1/data:/data \
-v /opt/docker/redis_study/redis_1/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf 

从 redis_2 7003

docker run -p 7003:7003 --name redis_2 \
-v /opt/docker/redis_study/redis_2/data:/data \
-v /opt/docker/redis_study/redis_2/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

测试

主机redis_0 set name qiuyu

image-20230309182711575

从机redis_2 get name

image-20230309182847869

主从设置成功

可以使用 info replication查看集群信息

image-20230309183119716

从节点只能读无法写

image-20230309183238843

优化

磁盘慢但网络快的话,主节点可以开启repl-diskless-sync no,提高全量同步性能

哨兵集群

sentinel_0 27001

sentinel_1 27002

sentinel_2 27003

mkdir -p /opt/docker/redis_study/sentinel_0/conf
mkdir -p /opt/docker/redis_study/sentinel_1/conf
mkdir -p /opt/docker/redis_study/sentinel_2/conf
mkdir -p /opt/docker/redis_study/sentinel_0/log
mkdir -p /opt/docker/redis_study/sentinel_1/log
mkdir -p /opt/docker/redis_study/sentinel_2/log

配置文件

protected-mode no
bind 0.0.0.0
# 后台运行 docker -d 这里就无需开启
daemonize no
port 27001 # 27001 27002 27003
# log
dir "/home/redis_sentinel/log"
logfile "/home/redis_sentinel/log/27001.log"
# sentinel
sentinel monitor mymaster 192.168.222.128 7001 2
# 超时
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000sentinel announce-ip 192.168.222.128
sentinel announce-port 27001 # 27001 27002 27003

其他两个哨兵也配置一下,记得修改port 和 log

运行容器

docker run -p 27001:27001 --name sentinel_0 \
--sysctl net.core.somaxconn=1024 \
--privileged=true \
-v /opt/docker/redis_study/sentinel_0/conf:/usr/local/etc/redis/conf/ \
-v /opt/docker/redis_study/sentinel_0/log:/home/redis_sentinel/log \
-d redis redis-sentinel /usr/local/etc/redis/conf/sentinel.confdocker run -p 27002:27002 --name sentinel_1 \
--sysctl net.core.somaxconn=1024 \
--privileged=true \
-v /opt/docker/redis_study/sentinel_1/conf:/usr/local/etc/redis/conf/ \
-v /opt/docker/redis_study/sentinel_1/log:/home/redis_sentinel/log \
-d redis redis-sentinel /usr/local/etc/redis/conf/sentinel.confdocker run -p 27003:27003 --name sentinel_2 \
--sysctl net.core.somaxconn=1024 \
--privileged=true \
-v /opt/docker/redis_study/sentinel_2/conf:/usr/local/etc/redis/conf/ \
-v /opt/docker/redis_study/sentinel_2/log:/home/redis_sentinel/log \
-d redis redis-sentinel /usr/local/etc/redis/conf/sentinel.conf

这里坑贼多,配吐了

  • 指定sentinel.conf配置文件映射到容器内时直接使用文件映射, 这么做有可能导致哨兵没有写入配置文件的权限, 表现为WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy. 解决方案:使用文件夹映射或者加上--privileged=true用来提升root权限

  • docker redis The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn 解决 : 加上 --sysctl net.core.somaxconn=1024

测试

关闭redis_0后,sentinel_1被选举为leader,然后sentinel_1选择redis_1成为主节点

1:X 09 Mar 2023 16:17:39.478 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 09 Mar 2023 16:17:39.478 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 09 Mar 2023 16:17:39.478 # Configuration loaded
1:X 09 Mar 2023 16:17:39.479 * monotonic clock: POSIX clock_gettime
1:X 09 Mar 2023 16:17:39.479 * Running mode=sentinel, port=27001.
1:X 09 Mar 2023 16:17:39.483 # Sentinel ID is bdc44c4a16815f0a2050c378df49c26e5de22874
1:X 09 Mar 2023 16:17:39.483 # +monitor master mymaster 192.168.222.128 7001 quorum 2
1:X 09 Mar 2023 16:17:39.484 * +slave slave 192.168.222.128:7002 192.168.222.128 7002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:17:39.484 * +slave slave 192.168.222.128:7003 192.168.222.128 7003 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:17:41.738 * +sentinel sentinel dc564ce67b88380c9befc8324bee0c021995e570 192.168.222.128 27002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:17:42.290 * +sentinel sentinel 201d9e4b941d7adc262058975dab2f25e587e1cf 192.168.222.128 27003 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.428 # +sdown master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.513 # +odown master mymaster 192.168.222.128 7001 #quorum 3/2
1:X 09 Mar 2023 16:19:05.513 # +new-epoch 1
1:X 09 Mar 2023 16:19:05.513 # +try-failover master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.515 # +vote-for-leader bdc44c4a16815f0a2050c378df49c26e5de22874 1
1:X 09 Mar 2023 16:19:05.521 # dc564ce67b88380c9befc8324bee0c021995e570 voted for bdc44c4a16815f0a2050c378df49c26e5de22874 1
1:X 09 Mar 2023 16:19:05.521 # 201d9e4b941d7adc262058975dab2f25e587e1cf voted for bdc44c4a16815f0a2050c378df49c26e5de22874 1
1:X 09 Mar 2023 16:19:05.587 # +elected-leader master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.587 # +failover-state-select-slave master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.688 # +selected-slave slave 192.168.222.128:7002 192.168.222.128 7002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.688 * +failover-state-send-slaveof-noone slave 192.168.222.128:7002 192.168.222.128 7002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:05.780 * +failover-state-wait-promotion slave 192.168.222.128:7002 192.168.222.128 7002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:06.542 # +promoted-slave slave 192.168.222.128:7002 192.168.222.128 7002 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:06.542 # +failover-state-reconf-slaves master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:06.642 * +slave-reconf-sent slave 192.168.222.128:7003 192.168.222.128 7003 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:07.594 * +slave-reconf-inprog slave 192.168.222.128:7003 192.168.222.128 7003 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:07.594 * +slave-reconf-done slave 192.168.222.128:7003 192.168.222.128 7003 @ mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:07.677 # -odown master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:07.677 # +failover-end master mymaster 192.168.222.128 7001
1:X 09 Mar 2023 16:19:07.677 # +switch-master mymaster 192.168.222.128 7001 192.168.222.128 7002
1:X 09 Mar 2023 16:19:07.677 * +slave slave 192.168.222.128:7003 192.168.222.128 7003 @ mymaster 192.168.222.128 7002
1:X 09 Mar 2023 16:19:07.677 * +slave slave 192.168.222.128:7001 192.168.222.128 7001 @ mymaster 192.168.222.128 7002
1:X 09 Mar 2023 16:19:12.702 # +sdown slave 192.168.222.128:7001 192.168.222.128 7001 @ mymaster 192.168.222.128 7002

image-20230310002039070

然后恢复redis_0 ,成为redis_0的从节点

1:X 09 Mar 2023 16:22:34.113 # -sdown slave 192.168.222.128:7001 192.168.222.128 7001 @ mymaster 192.168.222.128 7002
1:X 09 Mar 2023 16:22:44.100 * +convert-to-slave slave 192.168.222.128:7001 192.168.222.128 7001 @ mymaster 192.168.222.128 7002

代码

导入依赖


org.springframework.bootspring-boot-starter-data-redis

配置: 无需配置redis节点,直接配置哨兵就行

spring:redis:sentinel:master: mymasternodes:- 192.168.222.128:27001- 192.168.222.128:27002- 192.168.222.128:27003

简单测一下,都是OK的

@SpringBootTest
class MyTest {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Testvoid testSelect(){String name = stringRedisTemplate.opsForValue().get("name");System.out.println(name);}@Testvoid testInset(){stringRedisTemplate.opsForValue().set("test","test");}
}

读写分离

启动类中配置下这个@Bean就行了

@SpringBootApplication
public class Main {public static void main(String[] args) {SpringApplication.run(Main.class,args);}@Beanpublic LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){return new LettuceClientConfigurationBuilderCustomizer() {@Overridepublic void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder) {clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);}};}// 或者直接lambda@Beanpublic LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);}
}

这个bean中配置的就是读写策略,包括四种:

  • MASTER:从主节点读取
  • MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica
  • REPLICA:从slave(replica)节点读取
  • REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取master

分片集群

相关内容