概述

接上一篇Docker实战之MySQL主从复制, 这里是Docker实战系列的第二篇,主要进行Redis-Cluster集群环境的快速搭建。Redis作为基于键值对的NoSQL数据库,具有高性能、丰富的数据结构、持久化、高可用、分布式等特性,同时Redis本身非常稳定,已经得到业界的广泛认可和使用。

在Redis中,集群的解决方案有三种

  1. 主从复制
  2. 哨兵机制
  3. Cluster

Redis Cluster是Redis的分布式解决方案,在 3.0 版本正式推出。

集群方案的对比

1. 主从复制

同Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,读写分离。一个Master可以有多个Slaves。

优点

  • 数据备份
  • 读写分离,提高服务器性能

缺点

  • 不能自动故障恢复,RedisHA系统(需要开发)
  • 无法实现动态扩容

2. 哨兵机制

Redis Sentinel是社区版本推出的原生高可用解决方案,其部署架构主要包括两部分:Redis Sentinel集群和Redis数据集群。

其中Redis Sentinel集群是由若干Sentinel节点组成的分布式集群,可以实现故障发现、故障自动转移、配置中心和客户端通知。Redis Sentinel的节点数量要满足2n+1(n>=1)的奇数个。

优点

  • 自动化故障恢复

缺点

  • Redis 数据节点中 slave 节点作为备份节点不提供服务
  • 无法实现动态扩容

3. Redis-Cluster

Redis Cluster是社区版推出的Redis分布式集群解决方案,主要解决Redis分布式方面的需求,比如,当遇到单机内存,并发和流量等瓶颈的时候,Redis Cluster能起到很好的负载均衡的目的。

Redis Cluster着眼于提高并发量

群集至少需要3主3从,且每个实例使用不同的配置文件。

在redis-cluster架构中,redis-master节点一般用于接收读写,而redis-slave节点则一般只用于备份, 其与对应的master拥有相同的slot集合,若某个redis-master意外失效,则再将其对应的slave进行升级为临时redis-master。

在redis的官方文档中,对redis-cluster架构上,有这样的说明:在cluster架构下,默认的,一般redis-master用于接收读写,而redis-slave则用于备份,当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。 但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可通过readonly命令,将slave设置成可读,然后通过slave获取相关的key,达到读写分离。具体可以参阅redis官方文档等相关内容

优点

  • 解决分布式负载均衡的问题。具体解决方案是分片/虚拟槽slot。
  • 可实现动态扩容
  • P2P模式,无中心化

缺点

  • 为了性能提升,客户端需要缓存路由表信息
  • Slave在集群中充当“冷备”,不能缓解读压力

网络规划

这里没有搭建虚拟机环境,全部在本地部署。本机的ip为 192.168.124.5

ip port
192.168.124.5 7001
192.168.124.5 7002
192.168.124.5 7003
192.168.124.5 7004
192.168.124.5 7005
192.168.124.5 7006

Redis配置文件

在docker环境中,配置文件映射宿主机的时候,(宿主机)必须有配置文件。附件在这里。大家可以根据自己的需求定制配置文件。

下边是我的配置文件 redis-cluster.tmpl

  1. # redis端口
  2. port ${PORT}
  3. # 关闭保护模式
  4. protected-mode no
  5. # 开启集群
  6. cluster-enabled yes
  7. # 集群节点配置
  8. cluster-config-file nodes.conf
  9. # 超时
  10. cluster-node-timeout 5000
  11. # 集群节点IP host模式为宿主机IP
  12. cluster-announce-ip 192.168.124.5
  13. # 集群节点端口 7001 - 7006
  14. cluster-announce-port ${PORT}
  15. cluster-announce-bus-port 1${PORT}
  16. # 开启 appendonly 备份模式
  17. appendonly yes
  18. # 每秒钟备份
  19. appendfsync everysec
  20. # 对aof文件进行压缩时,是否执行同步操作
  21. no-appendfsync-on-rewrite no
  22. # 当目前aof文件大小超过上一次重写时的aof文件大小的100%时会再次进行重写
  23. auto-aof-rewrite-percentage 100
  24. # 重写前AOF文件的大小最小值 默认 64mb
  25. auto-aof-rewrite-min-size 64mb

由于节点IP相同,只有端口上的差别,现在通过脚本 redis-cluster-config.sh 批量生成配置文件

  1. for port in `seq 7001 7006`; do \
  2. mkdir -p ./redis-cluster/${port}/conf \
  3. && PORT=${port} envsubst < ./redis-cluster.tmpl > ./redis-cluster/${port}/conf/redis.conf \
  4. && mkdir -p ./redis-cluster/${port}/data; \
  5. done

生成的配置文件如下图

Docker环境搭建

这里还是通过docker-compose进行测试环境的docker编排。

  1. version: '3.7'
  2. services:
  3. redis7001:
  4. image: 'redis'
  5. container_name: redis7001
  6. command:
  7. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  8. volumes:
  9. - ./redis-cluster/7001/conf/redis.conf:/usr/local/etc/redis/redis.conf
  10. - ./redis-cluster/7001/data:/data
  11. ports:
  12. - "7001:7001"
  13. - "17001:17001"
  14. environment:
  15. # 设置时区为上海,否则时间会有问题
  16. - TZ=Asia/Shanghai
  17. redis7002:
  18. image: 'redis'
  19. container_name: redis7002
  20. command:
  21. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  22. volumes:
  23. - ./redis-cluster/7002/conf/redis.conf:/usr/local/etc/redis/redis.conf
  24. - ./redis-cluster/7002/data:/data
  25. ports:
  26. - "7002:7002"
  27. - "17002:17002"
  28. environment:
  29. # 设置时区为上海,否则时间会有问题
  30. - TZ=Asia/Shanghai
  31. redis7003:
  32. image: 'redis'
  33. container_name: redis7003
  34. command:
  35. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  36. volumes:
  37. - ./redis-cluster/7003/conf/redis.conf:/usr/local/etc/redis/redis.conf
  38. - ./redis-cluster/7003/data:/data
  39. ports:
  40. - "7003:7003"
  41. - "17003:17003"
  42. environment:
  43. # 设置时区为上海,否则时间会有问题
  44. - TZ=Asia/Shanghai
  45. redis7004:
  46. image: 'redis'
  47. container_name: redis7004
  48. command:
  49. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  50. volumes:
  51. - ./redis-cluster/7004/conf/redis.conf:/usr/local/etc/redis/redis.conf
  52. - ./redis-cluster/7004/data:/data
  53. ports:
  54. - "7004:7004"
  55. - "17004:17004"
  56. environment:
  57. # 设置时区为上海,否则时间会有问题
  58. - TZ=Asia/Shanghai
  59. redis7005:
  60. image: 'redis'
  61. container_name: redis7005
  62. command:
  63. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  64. volumes:
  65. - ./redis-cluster/7005/conf/redis.conf:/usr/local/etc/redis/redis.conf
  66. - ./redis-cluster/7005/data:/data
  67. ports:
  68. - "7005:7005"
  69. - "17005:17005"
  70. environment:
  71. # 设置时区为上海,否则时间会有问题
  72. - TZ=Asia/Shanghai
  73. redis7006:
  74. image: 'redis'
  75. container_name: redis7006
  76. command:
  77. ["redis-server", "/usr/local/etc/redis/redis.conf"]
  78. volumes:
  79. - ./redis-cluster/7006/conf/redis.conf:/usr/local/etc/redis/redis.conf
  80. - ./redis-cluster/7006/data:/data
  81. ports:
  82. - "7006:7006"
  83. - "17006:17006"
  84. environment:
  85. # 设置时区为上海,否则时间会有问题
  86. - TZ=Asia/Shanghai

启动结果如图

集群配置

redis集群官方提供了配置脚本,4.x和5.x略有不同,具体可参见集群配置

下边是我自己的环境

  1. docker exec -it redis7001 redis-cli -p 7001 -a 123456 --cluster create 192.168.124.5:7001 192.168.124.5:7002 192.168.124.5:7003 192.168.124.5:7004 192.168.124.5:7005 192.168.124.5:7006 --cluster-replicas 1

看到如下结果说明集群配置成功

集群测试

接下来进行一些集群的基本测试

1. 查看集群通信是否正常

redis7001主节点对它的副本节点redis7005进行ping操作。

-h host -p port -a pwd

  1. docker docker exec -it redis7001 redis-cli -h 192.168.124.5 -p 7005 -a 123456 ping
  2. Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
  3. PONG

2. 测试简单存储

redis7001主节点客户端操作redis7003主节点

  1. docker docker exec -it redis7001 redis-cli -h 192.168.124.5 -p 7003 -a 123456
  2. Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
  3. 192.168.124.5:7003> set name admin
  4. (error) MOVED 5798 192.168.124.5:7002

由于Redis Cluster会根据key进行hash运算,然后将key分散到不同slots,name的hash运算结果在redis7002节点上的slots中。所以我们操作redis7003写操作会自动路由到7002。然而error提示无法路由?没关系,差一个 -c 参数而已。

再次运行查看结果如下:

  1. docker docker exec -it redis7001 redis-cli -h 192.168.124.5 -p 7003 -a 123456 -c
  2. Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
  3. 192.168.124.5:7003> set name admin
  4. -> Redirected to slot [5798] located at 192.168.124.5:7002
  5. OK
  6. 192.168.124.5:7002> get name
  7. "admin"
  8. 192.168.124.5:7002>

3. 查看集群状态

4. 查看slots分片

5. 查看集群信息

6. 测试读写分离

试试看,发现读不到,原来在redis cluster中,如果你要在slave读取数据,那么需要带先执行 readonly 指令,然后 get key

7. 简单压测

选项 描述
-t 指定命令
-c 客户端连接数
-n 总请求数
-d set、get的value大小(单位byte)

测试如下

  1. docker docker exec -it redis7001 bash
  2. root@cbc6e76a3ed2:/data# redis-benchmark -h 192.168.124.5 -p 7001 -t set -c 100 -n 50000 -d 20
  3. ====== SET ======
  4. 50000 requests completed in 10.65 seconds
  5. 100 parallel clients
  6. 20 bytes payload
  7. keep alive: 1
  8. 0.00% <= 2 milliseconds
  9. 0.01% <= 3 milliseconds
  10. ...
  11. 100.00% <= 48 milliseconds
  12. 100.00% <= 49 milliseconds
  13. 4692.63 requests per second

这里没啥实际意义,在工作业务上大家可以根据QPS和主机配置进行压测,计算规划出节点数量。

容灾演练

现在我们杀掉主节点redis7001,看从节点redis7005是否会接替它的位置。

  1. docker stop redis7001

再试着启动7001,它将自动作为slave挂载到7005

SpringBoot配置Redis集群

在SpringBoot2.x版本中,redis默认的连接池已经更换为Lettuce,而不再是jedis。

  1. 在pom.xml中引入相关依赖
  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.apache.commons</groupId>
  7. <artifactId>commons-pool2</artifactId>
  8. </dependency>
  1. application.yml
  1. spring:
  2. redis:
  3. timeout: 6000
  4. password: 123456
  5. cluster:
  6. max-redirects: 3 # 获取失败 最大重定向次数
  7. nodes:
  8. - 192.168.124.5:7001
  9. - 192.168.124.5:7002
  10. - 192.168.124.5:7003
  11. - 192.168.124.5:7004
  12. - 192.168.124.5:7005
  13. - 192.168.124.5:7006
  14. lettuce:
  15. pool:
  16. max-active: 1000 #连接池最大连接数(使用负值表示没有限制)
  17. max-idle: 10 # 连接池中的最大空闲连接
  18. min-idle: 5 # 连接池中的最小空闲连接
  19. max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
  20. cache:
  21. jcache:
  22. config: classpath:ehcache.xml
  1. redis配置
  1. @Configuration
  2. @AutoConfigureAfter(RedisAutoConfiguration.class)
  3. public class RedisConfig {
  4. @Bean
  5. public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
  6. RedisTemplate<String, Object> template = new RedisTemplate<>();
  7. template.setKeySerializer(new StringRedisSerializer());
  8. template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
  9. template.setConnectionFactory(redisConnectionFactory);
  10. return template;
  11. }
  12. }
  1. 基本测试
  1. @SpringBootTest
  2. public class RedisTest {
  3. @Autowired
  4. private RedisTemplate<String, String> redisTemplate;
  5. @Test
  6. public void test() {
  7. redisTemplate.opsForValue().set("name", "admin");
  8. String name = redisTemplate.opsForValue().get("name");
  9. System.out.println(name); //输出admin
  10. }
  11. }

总结

通过以上演示,基本上可以在本地环境下用我们的Redis Cluster集群了。最后再上一张本地映射文件的最终样子,帮助大家了解Redis持久化及集群相关的东西。感兴趣的小伙伴可以自行测试并查看其中的内容。

内容如有错漏,还望大家不吝赐教,同时,欢迎大家关注公众号【当我遇上你】,你们的支持就是我写作的最大动力。

参考

公众号 【当我遇上你】

Docker实战之Redis-Cluster集群的更多相关文章

  1. Docker Compose 搭建 Redis Cluster 集群环境

    在前文<Docker 搭建 Redis Cluster 集群环境>中我已经教过大家如何搭建了,本文使用 Docker Compose 再带大家搭建一遍,其目的主要是为了让大家感受 Dock ...

  2. docker下创建redis cluster集群

    概述 在Redis中,集群的解决方案有三种 主从复制 哨兵机制 Cluster Redis Cluster是Redis的分布式解决方案,在 3.0 版本正式推出. 准备工作 1.确定本机IP地址 2. ...

  3. Docker 搭建 Redis Cluster 集群环境

    使用 Docker 搭建 Redis Cluster,最重要的环节就是容器通信的问题,这一块我们在之前的文章中已经给大家解决了<Docker 网络模式详解及容器间网络通信>,本篇文章主要练 ...

  4. redis cluster 集群拓展

    redis cluster 集群拓展 准备工作 举例:添加2个节点(1主7006节点,1从7007节点) 在/home/redis-cluster下生成conf和data目标,并生成配置信息 `; d ...

  5. 搭建分布式 Redis Cluster 集群与 Redis 入门

    目录 Redis 集群搭建 Redis 是啥 集群(Cluster) Redis Cluster 说明 Redis Cluster 节点 Redis Cluster 集群模式 不能保证一致性 创建和使 ...

  6. K8S部署Redis Cluster集群

    kubernetes部署单节点redis: https://www.cnblogs.com/zisefeizhu/p/14282299.html Redis 介绍 • Redis代表REmote DI ...

  7. K8S部署Redis Cluster集群(三主三从模式) - 部署笔记

    一.Redis 介绍 Redis代表REmote DIctionary Server是一种开源的内存中数据存储,通常用作数据库,缓存或消息代理.它可以存储和操作高级数据类型,例如列表,地图,集合和排序 ...

  8. Redis Cluster集群搭建与配置

    Redis Cluster是一种服务器sharding分片技术,关于Redis的集群方案应该怎么做,请参考我的另一篇博客http://www.cnblogs.com/xckk/p/6134655.ht ...

  9. jedis处理redis cluster集群的密码问题

    环境介绍:jedis:2.8.0 redis版本:3.2 首先说一下redis集群的方式,一种是cluster的 一种是sentinel的,cluster的是redis 3.0之后出来新的集群方式 本 ...

  10. 深入分析redis cluster 集群

    深入分析redis cluster 集群安装配置详解 下面小编来为各位介绍一篇深入分析redis cluster 集群安装配置详解,如果你希望做数据库集群就可以来看看此文章的哦. http://rub ...

随机推荐

  1. Android如何制作自己的依赖库上传至github供别人下载使用

    Android如何制作自己的依赖库上传至github供别人下载使用 https://blog.csdn.net/xuchao_blog/article/details/62893851

  2. C# 使用 HttpPost 请求调用 WebService (转)

    转自 https://www.cnblogs.com/Brambling/p/7266482.html 之前调用 WebService 都是直接添加服务引用,然后调用 WebService 方法的,最 ...

  3. MTF的倾斜边缘计算方法

    光学系统性能的衡量方法有很多,常见的有点扩散函数法.瑞利判断法.点 列图法.光学传递函数(MTF)法等,其中 MTF 法在光学系统和镜头加工制造中 使用 最为广泛.MTF 曲线真实的反映了成像系统将物 ...

  4. Android开发学习3

    学习内容: 1.复选框CheckBox 2.ImageView & 使用第三方库加载网络图片 3.列表视图ListView 4.网格视图GridView 5.ScrollView & ...

  5. TPO3-1 Architecture

    Even development in architecture has been the result of major technological changes. Materials and m ...

  6. Opencv笔记(六)——把滑动条当调色板

    学习目标: 学会把滑动条绑定到 OpenCV 的窗口. 学习函数:cv2.getTrackbarPos(), cv2.creatTrackbar()等. 简单演示: 通过调节滑动条来设定画板颜色.我们 ...

  7. 《VSTO开发入门教程》配套资源下载

    <VSTO开发入门教程> 刘永富 著 清华大学出版社 封面截图 购书网址 京东网 淘宝网 配套资源到如下页面寻找: https://www.cnblogs.com/ryueifu-VBA/ ...

  8. 十、linux-mysql下的mysql数据库增量恢复

    1.全量备份 全量数据就是数据库中所有的数据,全量备份就是把数据库中所有的数据进行备份. 备份所有库: mysqldump -uroot -ppoldboy -S /data/3306/mysql.s ...

  9. 导入import的多种形式

    参考资料:anaconda官方资料 一.module(模块) 比如fibo是个模块(.py文件),其中有fib.fib2等函数 第一种形式:import fibo 在当前的符号表中,这并不会直接进入到 ...

  10. windows下使用apache相关资料汇总

    1.Apache httpd.conf配置详解 https://www.cnblogs.com/langren1992/p/5160912.html 2.windows下使用apache经验总结 ht ...