首页 > 数据库 >Redis 分片集群搭建并使用 RedisTemplate 实现读写分离

Redis 分片集群搭建并使用 RedisTemplate 实现读写分离

时间:2023-12-24 18:56:55浏览次数:32  
标签:slot Redis redis cluster 集群 分片 节点 RedisTemplate

上篇博客介绍了 Redis 哨兵集群的搭建,虽然已经解决了 master 在宕机后,与 slave 之间会自动切换的问题,但是其承载的数据量天花板仍然是单机的最大内存容量,无法承载更多的数据量。

本篇博客介绍 Redis 分片集群的搭建,集群内部拥有多个 master 节点,每个 master 存放的数据不一样,从而使 Redis 集群能够承载更多的数据量。每个 master 有自己的 slave 节点,在宕机后也能够与 slave 节点自动切换,保障 Redis 集群的高可用。

本篇博客的代码 Demo 仍然在前两篇博客的基础上拷贝过来,不需要修改任何代码,只需要修改一下 application.yml 文件,即可实现 RedisTemplate 连接分片集群实现读写分离的效果,在博客的最后会提供源代码的下载。


一、分片集群的搭建

Redis 分片集群的搭建非常简单,本篇博客搭建一个拥有 3 个 master 和 3 个 slave 的分片集群,主要分为 2 个步骤:首先启动 6 个 Redis 实例,然后运行以下创建集群的命令即可。本篇博客仍然使用虚拟机进行模拟搭建,我的虚拟机操作系统是 CentOS7(ip 地址是 192.168.136.128),已经安装好了 docker 和 docker-compose ,首先我们先创建好相关的目录,我创建的主目录是 /app/redis-cluster-slot ,具体结构如下:

image

上图是我已经搭建好的 Redis 分片集群目录结构,直接拿来用了。其中 dump.rdb 和 redis.log 是各个 Redis 服务启动后自动生成的,可以忽略。这里创建了 6 个子目录 redis6379、redis6479、redis6579、redis7379、redis7479、redis7579,里面用来存放每个 Redis 的配置文件、备份数据、日志。

由于每个 Redis 实例的配置文件,基本上一模一样,只是启动端口不一样而已,所以这里只列出一个即可:

protected-mode no
bind 0.0.0.0
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /data

# 日志存放位置
logfile /data/redis.log
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 关闭 aof 日志备份
appendonly no
# 启动端口
port 6379
# 自定义密码
requirepass root
# 访问 master 节点时需要提供的密码
masterauth root
# 虚拟机会有多个 ip,这里指定具体一个 ip 地址
replica-announce-ip 192.168.136.128

以上列出的是 redis6379 目录下的配置文件,其端口是 6379,其它目录下的配置文件只需要改一下端口即可,端口与目录名称中的数字保持一致,配置文件中的其余部分一模一样。需要注意以下几点即可:

  • cluster-enabled yes 表示开启集群功能
  • cluster-config-file /tmp/nodes.conf 集群的配置文件名称,不需要我们创建,由redis自己维护
  • cluster-node-timeout 5000 节点心跳失败的超时时间
  • requirepass root 和 masterauth root 这里设置 redis 本身的密码,以及访问 master 节点的密码,由于集群中每个节点都有可能是 master 节点,因此如果 Redis 节点设置了访问密码的话,必须也要设置访问 master 节点的密码
  • replica-announce-ip 192.168.136.128 本篇博客的集群搭建,仍然使用 docker 的 host 模式,因此这里指定虚拟机的 ip

然后在 /app/redis-cluster-slot 目录下,创建 docker-compose.yml 文件,内容如下:

version: "3.5"
services:
  redis6379:
    image: redis
    container_name: redis6379
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis6379/data:/data
      - /app/redis-cluster-slot/redis6379/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

  redis6479:
    image: redis
    container_name: redis6479
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis6479/data:/data
      - /app/redis-cluster-slot/redis6479/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

  redis6579:
    image: redis
    container_name: redis6579
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis6579/data:/data
      - /app/redis-cluster-slot/redis6579/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

  redis7379:
    image: redis
    container_name: redis7379
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis7379/data:/data
      - /app/redis-cluster-slot/redis7379/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

  redis7479:
    image: redis
    container_name: redis7479
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis7479/data:/data
      - /app/redis-cluster-slot/redis7479/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

  redis7579:
    image: redis
    container_name: redis7579
    restart: always
    privileged: true
    network_mode: "host"
    volumes:
      - /app/redis-cluster-slot/redis7579/data:/data
      - /app/redis-cluster-slot/redis7579/redis.conf:/etc/redis.conf
    command:
      redis-server /etc/redis.conf

可以发现,docker-compose.yml 文件中,启动了 6 个 Redis 实例,但是彼此之间没有任何关系。我们运行 docker-compose up -d 先把 6 个 Redis 实例服务启动起来,使用 docker-compose ps 查看其运行状态:

image

由于采用 docker 的 host 模式部署,这里看不到启动端口,可以使用 netstat -tulnp | grep redis 查看:

image

下面开始使用 cluster 命令去创建分片集群。我使用 RDM 客户端工具测试,发现其不支持 cluster 命令。然后我又使用微软的 windows 版本的 redis-cli 测试,发现其版本太老,也不支持 cluster 命令,因此我们只能进入上面启动的其中一个 redis 容器中运行 cluster 命令去创建集群了。

我们就进入 redis6379 这个服务的容器中去创建分片集群吧:

首先运行 docker exec -it redis6379 bash 进入 redis6379 服务的容器中,然后运行以下命令创建分片集群:

redis-cli --cluster create --cluster-replicas 1 192.168.136.128:6379 192.168.136.128:6479 192.168.136.128:6579 192.168.136.128:7379 192.168.136.128:7479 192.168.136.128:7579 -a root

以上命令的参数说明:

  • --cluster 表示执行的是集群命令,create 表示创建分片集群
  • --cluster-replicas 1 表示集群中每个 master 节点有 1 个 slave 节点
  • -a 表示访问每个 redis 实例的密码,本篇博客配置的访问 redis 的密码是 root

image

集群创建命令运行之后,系统会提示把最前面的 3 个 ip端口的节点作为主节点,后面的 3 个ip端口的节点作为 slave 节点,如果你认为没问题的话,输入 yes 即可,系统就会自动创建分片集群,最终效果去下所示:

image

可以发现每个 master 节点都分配了一定数量的 slots(插槽),Redis 的数据是存放在具体的某个 slot 中的,数据跟着 slot 走,而不是跟随具体的 Redis 节点或服务器走。如果添加了新的 master 节点后,可以迁移 slot,数据也将随着 slot 的迁移而迁移。对于 Redis 分片集群来说,一共拥有 16384 个 slot(序号为 0 到 16383)可以使用。

然后我们可以登录到任意一个 Redis 服务中,运行 cluster nodes 命令查看集群节点信息:

image

从上面可以看出,哪些是 master 节点,以及其拥有的 slot 范围,通过 slave 后面的很长的一串字符串,可以看出它所属的 master 节点。到此为止,Redis 的分片集群已经搭建成功。

你可以连接任意一个 redis 节点,master 和 slave 都可以,运行相关的 redis 读写命令,Redis 集群会根据 key 计算出 slot 值,然后切换到 slot 所在的节点去写入或者读取数据。如果你给 Redis 设置了密码的话,跳转到具体的 redis 节点后,会提示你先输入密码,才能写入或读取数据,可能体验不是很好,但实际上我们下面要使用 RedisTemplate 去访问才做分片集群的话,是很方便的,以为 RedisTemplate 内部切换不同的节点时会自动发送密码验证。

另外分片集群中某个 master 宕机的话,其所属的 slave 会自动切换为 master 节点,原来的 master 节点恢复后会变成 slave 节点。如果你想手动进行 master 和 slave 切换的话,也可以先使用客户端工具连接到 slave 节点,然后运行 cluster failover 命令即可。这里就不再进行演示了,大家可以自行验证。


二、RedisTemplate 操作分片集群实现读写分离

本篇博客仍然使用前两篇博客的 Demo 代码,一行代码都不需要更改,只需要更改配置文件即可。

这里仅仅列出 application.yml 配置文件的具体内容:

spring:
  redis:
    # 这里配置的是连接具体的 redis 节点的密码
    password: root
    # 把集群中的所有master节点和slave节点都配置上即可
    cluster:
      nodes:
        - 192.168.136.128:6379
        - 192.168.136.128:6479
        - 192.168.136.128:6579
        - 192.168.136.128:7379
        - 192.168.136.128:7479
        - 192.168.136.128:7579
    jedis:
      pool:
        # 最大连接数
        max-active: 10
        # 最大空闲连接数
        max-idle: 5
        # 最小空闲
        min-idle: 1
        # 连接超时时间(毫秒)
        max-wait: 3000

跟前篇博客的 Demo 运行情况相似,从控制台日志中,无法看出 RedisTemplate 是从哪个节点读取的数据

验证 RedisTemplate 操作分片集群实现读写分离的方法跟上篇博客的方案一样,这里就不再赘述。


本篇博客的源代码下载地址为:https://files.cnblogs.com/files/blogs/699532/springboot_redis_cluster3.zip

标签:slot,Redis,redis,cluster,集群,分片,节点,RedisTemplate
From: https://www.cnblogs.com/studyjobs/p/17924704.html

相关文章

  • Spring cache整合Redis
    Springcache整合Redis,并给它一个过期时间!转载自:https://zhuanlan.zhihu.com/p/138295935不知道你们有没给cache设置过过期时间,来试试?上一篇文章中,我们使用springboot集成了redis,并使用RedisTemplate来操作缓存数据,可以灵活使用。今天我们要讲的是Spring为我们提供......
  • 大文件分片上传
    文件传输是一个常见的需求。对于大文件的下载和上传,直接使用传统的方式可能会遇到性能和用户体验方面的问题。幸运的是,前端技术提供了一些高效的解决方案:文件流操作和切片下载与上传。本文将深入探讨这些技术,帮助你理解它们的原理和实现方法,以优化文件传输效率和提升用户体验。一......
  • day03 Redis
    day03RedisRedis是一个基于内存的key-value结构数据库,方便存储。1.1Redis服务启动与停止服务启动命令redis-server.exeredis.windows.conf修改Redis配置文件设置Redis服务密码,修改redis.windows.con重启Redis后,再次连接Redis时,需加上密码,否则连接失败。redis......
  • Redis_实战2
    Redis_实战2秒杀优化异步秒杀流程将判断库存&判断重复下单逻辑交给Redis将耗时长的写数据库操作交给异步线程。Redis:Key-stock:优惠券id,value-库存String(判断库存充足)Redis:Key-order:优惠券id,value-用户idSet(判断重复下单)流程1交给Lua脚本流程2交给阻塞队列数据库-......
  • redis数据类型及指令
    ......1、list----------队列(先进先出)2、set-----------无序、两端取值、可遍历3、zset-----------有序set、两端取值、可遍历 String常用指令1、setkeyvalue2、getkey3、msetkey1val1key2val2.....4、mgetkey1key2.....5、setkey5----------设置字符......
  • 【Redis】BigKey问题
    面试题海量数据里查询某一固定前缀的key生产上如何限制keys*/flushdb/flushall等危险命令以防止误删误用?MEMORYUSAGE命令用过吗?BigKey问题,多大算big?如何发现?如何删除?如何处理?BigKey你做过调优吗?惰性释放lazyfree了解过吗?MoreKey问题,生产上Redis数据库有1000万条记......
  • Shiro 框架中如何更新Redis的超时登录时间?
    在Shiro框架中,可以通过实现SessionDAO接口来将会话信息保存到Redis中,并且可以通过实现SessionValidationScheduler接口来定期检查会话是否过期。因此,要更新Redis中的超时登录时间,可以按照以下步骤进行操作:实现SessionDAO接口,将会话信息保存到Redis中。在实现SessionDAO接口时,可以使......
  • 【Java 进阶篇】Jedis 操作 Hash:Redis中的散列类型
    在Redis中,Hash是一种存储键值对的数据结构,它适用于存储对象的多个属性。Jedis作为Java开发者与Redis交互的工具,提供了丰富的API来操作Hash类型。本文将深入介绍Jedis如何操作Redis中的Hash类型数据,通过生动的代码示例和详细的解释,助你轻松掌握Jedis中Hash的各种操作。Jedis中Hash的......
  • redis配置
    1、redis-server配置文件名&------------------以哪个配置文件启动,不知道配置文件名以默认配置启动(默认配置≠redis.conf),可以复制redis.conf启动过个redis服务。  配置:1、daemonizeno|yes------------配置redis服务为守护模式2、pidfile/var/run/redis_6379.pid---......
  • Redis 哨兵集群搭建并使用 RedisTemplate 实现读写分离
    上篇博客介绍的Redis主从集群搭建,有一个缺点就是master和slave的角色是固定的,不会发生变化。一旦master节点宕机,那么集群就只能提供读服务,无法提供写服务。本篇博客介绍Redis哨兵集群的搭建,可以监控Redis集群的master和slave节点,最重要的是一旦master宕机,哨兵集......