1.redis-cluster设计

Redis集群搭建的方式有多种,例如使用zookeeper,但从redis 3.0之后版本支持redis-cluster集群,redis-cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster架构图如下:

其结构特点

  1. 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  2. 节点的fail是通过集群中超过半数的节点检测失效时才生效。
  3. 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
  4. redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
  5. Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。

redis cluster节点分配

例如分配三个主节点分别是:7000, 7001, 7002。三个从节点分别是7003,7004,7005。它们可以是一台机器上的六个端口,也可以是六台不同的服务器。采用哈希槽 (hash slot)的方式来分配16384个slot 的话,六个节点分别承担的slot 区间如同所示:

    获取数据: 如果存入一个值,按照redis cluster哈希槽的算法: CRC16('key')%16384 = 6782。 就会把这个key 的存储分配到7001 上了。同样,当连接(7000,7001,7002)任何一个节点想获取'key'这个key时,也会这样的算法,然后内部跳转到7001节点上获取数据 。

2.redis-cluster主从模式

redis cluster为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。主从模式具有如下特点:

  1. 集群有7000,7001,7002三个主节点, 如果这3个节点都没有加入从节点,如果7001挂掉了,就无法访问整个集群,7000和7002的slot也无法访问。
  2. 主从节点同时挂掉后,如节点7001和7004同时挂了,Redis集群将无法继续正确地提供服务。
  3. 为每个主节点设置从节点, 比如像这样, 集群包含主节点7000,7001,7002 以及从节点7003,7004,7005, 那么即使7001挂掉系统也可以继续正确工作。7004节点替代了7001节点,所以Redis集群将会选择7004节点作为新的主节点,集群将会继续正确地提供服务。 当7001重新开启后,它就会变成7004的从节点。

2.redis-cluster集群搭建

搭建环境

本次测试采用虚拟机模式,在本机上做测试,虚拟机环境为Centos7.0。搭建集群需要如下相关依赖软件,下载地址为“

  1. rubygems软件包下载:https://rubygems.org/pages/download
  2. ruby软件包下载:http://www.ruby-lang.org/en/downloads/
  3. redis-3.2.2.gem依赖包下载:https://rubygems.global.ssl.fastly.net/gems/redis-3.2.2.gem
  4. openssl软件包下载: http://www.openssl.org/source/

下载文件包截图如下:

redis集群与大多数分布式中间件一样,redis的cluster也是依赖选举算法来保证集群的高可用,所以类似zookeeper一样,一般是奇数个节点(可以允许N/2以下的节点失效),再考虑到每个节点做Master-Slave互为备份,所以一个redis cluster集群最少也得6个节点。

步骤1:安装redis

下载最新版redis并安装在linux系统中。具体操作可参考网址:Redis介绍及Jedis基础操作

步骤2:新建集群文件夹目录

新建一个根目录data/cluster/。并在cluster目录下面建立6个子目录:mkdir 7000 7001 7002 7003 7004 7005。

步骤3:修改redis.conf配置文件

修改redis的配置文件redis.conf,复制原有解压redis文件中的redis.conf文件到7000目录中,操作指令如:cp /usr/software/redis-4.0.6/redis.conf /data/cluster/7000。修改redis.conf文件中的配置字段,修改字段如下:

daemonize yes #后台启动
port 7000 #修改端口号,从7000到7005
cluster-enabled yes #开启cluster,去掉注释
cluster-config-file nodes-7000.conf
cluster-node-timeout 15000
appendonly yes
pidfile /var/run/redis_7000.pid

相同操作处理其他五个文件夹,配置文件redis.conf中,将7000替换为对应的值。比如:7001文件下替换为7001。处理完成后,一次运行定义的每个文件夹下面的redis,查看是否启动成功。

步骤4:安装Ruby环境

安装Ruby环境。网上很多博客都是采用yum模式安装的,但考虑到FQ等限制条件,本文采用离线模式安装。

Ruby简介

Ruby是一种纯粹的面向对象编程语言。它由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)创建于1993年。可以在 www.ruby-lang.org 的 Ruby 邮件列表上找到松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)的名字。在 Ruby 社区,松本也被称为马茨(Matz)。Ruby 是"程序员的最佳朋友"。Ruby 的特性与 Smalltalk、Perl 和 Python 类似。Perl、Python 和 Smalltalk 是脚本语言。Smalltalk 是一个真正的面向对象语言。Ruby,与 Smalltalk 一样,是一个完美的面向对象语言。使用 Ruby 的语法比使用 Smalltalk 的语法要容易得多。

Ruby离线安装

  1. Ruby下载地址:http://www.ruby-lang.org/en/downloads/  ,最新的版本为2.5.0。
  2. Ruby安装参考网址:Linux 安装Ruby详解(在线和离线安装)
  3. 在安装之前,请确保使用账号具有Root权限,将下载的Ruby安装包上传到服务器当中,通过xtfp5工具进行文件上传:解压上传文件, tar -zxvf ruby-2.5.0.tar.gz,进入到ruby-2.5.0目录执行指令make && make install安装,安装成功可通过指令:ruby -v查看版本号:

步骤5:安装RubyGems环境

安装RubyGems环境。网上很多博客都是采用yum模式安装的,但考虑到FQ等限制条件,本文采用离线模式安装。

RubyGems简介

RubyGems 是 Ruby 的一个包管理器,它提供一个分发 Ruby 程序和库的标准格式,还提供一个管理程序包安装的工具。RubyGems 旨在方便地管理 gem 安装的工具,以及用于分发 gem 的服务器。这类似于 Ubuntu 下的apt-get, Centos 的 yum,Python 的 pip。RubyGems大约创建于2003年11月,从Ruby 1.9版起成为Ruby标准库的一部分。

离线安装RubyGems

如果你的 Ruby 低于 1.9 版本,也可以通过手动安装:

  1. RubyGems下载地址:https://rubygems.org/pages/download
  2. RubyGems安装参考网址:Linux 离线安装Rubygems详解
  3. 解压下载文件并进入目录,解压指令tar -zxvf rubygems-2.7.4.tgz,执行命令:ruby setup.rb

       

步骤6:安装openssl

使用gem install 安装 ruby redis。直接操作会报如下错误,查看原因是因为缺少openssl。

离线安装openssl

  1. openssl下载地址:http://www.openssl.org/source/
  2. openssl安装参考网址:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby
  3. 解压下载文件并进入目录,解压指令如: tar -xzvf openssl-1.0.2n.tar.gz  ,执行以下命令:
tar -xzvf openssl-1.0.2n.tar.gz
cd openssl-1.0.2n
./config -fPIC --prefix=/usr/local/openssl enable-shared
./config -t  make && make install

  1. 执行以上命令安装openssl,安装后查看版本号如下:

  1. 解决ssl.h文件找不到的问题,配置ruby文件,# ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/ --with-openssl-lib=/usr/local/openssl/lib
  2. 设置软链接:ln -s /usr/local/src/ruby-2.2.3/include /
  3. 再次编译安装,成功后如下图所示:

步骤7:  安装redis-trib.rb运行依赖的ruby的包redis-3.2.2.gem

  1. redis-3.2.2.gem下载地址:https://rubygems.global.ssl.fastly.net/gems/redis-3.2.2.gem
  2. 下载完成后上传到服务器上面,执行安装命令如:gem install /usr/software/redis-3.2.2.gem

步骤8:  使用redis-trib.rb创建集群

使用create命令 --replicas 1 参数表示为每个主节点创建一个从节点,其他参数是实例的地址集合。可利用命令:./redis-trib.rb help查看使用介绍。运行集群创建shell脚本,cluster就创建成功了。最终的结果是后面的192.168.210.128:7000~192.168.210.128:7005中,会有3个会指定成master,而其它3个会指定成slave。

注:利用redis-trib创建cluster的操作,只需要一次即可,假设系统关机,把所有6个节点全关闭后,下次重启后,即自动进入cluster模式,不用再次redis-trib.rb create。

查看redis进程启动状态,并开放防火墙中的对应端口。

查看节点分配指令为:./redis-trib.rb check 192.168.210.128:7002  (任意一个集群的ip地址)

3.redis-cluster集群节点选举,扩容与删除

集群选举

现在模拟将7002节点挂掉,按照redis-cluster原理会选举将 7002的从节点7005选举为主节点。直接关闭7002的进程,在重新check可发现7005已经被自动选举为主节点。当启动7002后,7002将作为7005的从节点。

新增主节点

新增一个节点D,redis cluster的这种做法是从各个节点的前面各拿取一部分slot到新增点上,也可设置从指定部分节点获取。举例如:在A,B,C节点上新增节点D。

  • 节点A覆盖1365-5460
  • 节点B覆盖6827-10922
  • 节点C覆盖12288-16383
  • 节点D覆盖0-1364,5461-6826,10923-12287

新增一个节点7006作为主节点,操作步骤如下:

  1. 修改配置文件,新建一个对应的文件7006,并把复制配置文件redis.conf放入到文件7006下面,并修改配置文件,把端口修改为7006,其他配置信息也参考前面的案例对应修改。节点配置信息成功后,启动7006下面的redis。
  2. 将7006加入到现有的集群中,输入指令:./redis-trib.rb add-node 192.168.210.128:7006 192.168.210.128:7002。指令说明:dd-node是加入集群节点,192.168.210.128:7006为要加入的节点,192.168.210.128:7002 表示加入的集群的一个节点,用来辨识是哪个集群,理论上那个集群的节点都可以。
  3. 目前cluster已经定义7006为主节点,但是Cluster并未给7006分配哈希卡槽(0 slots)。
  4. redis-cluster在新增节点时并未分配卡槽,需要操作者手动对集群进行重新分片迁移数据,需要重新分片命令:reshard。操作如:redis-trib.rb reshard 192.168.210.128:7002。指令说明:这个命令是用来迁移slot节点的,后面的192.168.210.128:7002是表示是哪个集群,端口填[7000-7006]都可以,执行后:它提示需要迁移多少slot到7006上平分16384个哈希槽给4个节点:16384/4 = 4096,可移动4096个槽点到7006上。填写7006的id:如ee3efb90e5ac0725f15238a64fc60a18a71205d7。

  1. redis-trib 会向你询问重新分片的源节点(source node),即,要从特定的哪个节点中取出 4096 个哈希槽,还是从全部节点提取4096个哈希槽, 并将这些槽移动到7006节点上。如果不打算从特定的节点上取出指定数量的哈希槽,那么可以向redis-trib输入 all,这样的话, 集群中的所有主节点都会成为源节点,redis-trib从各个源节点中各取出一部分哈希槽,凑够4096个,然后移动到7006节点上。操作命令为:Source node #1:all  。

  1. 确认之后,redis-trib就开始执行分片操作,将哈希槽一个一个从源主节点移动到7006目标主节点。重新分片结束后可以check以下节点的分配情况。指令为:./redis-trib.rb check 192.168.210.128:7002。可查看扩容主节点是否成功。

新增从节点

  1. 新增一个节点7007作为从节点修改配置文件,新建一个对应的文件7007,并把复制配置文件redis.conf放入到文件7007下面,并修改配置文件,把端口修改为7007,其他配置信息也参考前面的案例对应修改。节点配置信息成功后,启动7007下面的redis并加入到现有集群中。
  2. redis-trib增加从节点的命令为:./redis-trib.rb add-node --slave --master-id $[nodeid] 192.168.210.128:7007 192.168.210.128:7000 。操作指令含义:nodeid为要加到master主节点的node id,192.168.210.128:7007为新增的从节点,192.168.210.128:7000为集群的一个节点(集群的任意节点都行),用来辨识是哪个集群;如果没有给定那个主节点--master-id的话,redis-trib将会将新增的从节点随机到从节点较少的主节点上。
  3. 从节点不存在分片操作,与主节点对应的片一致。

移除主节点

  1. 移除节点使用redis-trib的del-node命令,redis-trib del-node 192.168.210.128:7002  ${node-id}  。操作指令含义: 192.168.210.128:7000为指定集群,node-id为要删除的主节点。 和添加节点不同,移除节点node-id是必需的。

  2. 测试删除7001主节点,redis cluster提示7001已经有数据了,不能够被删除,需要将他的数据转移出去,也就是和新增主节点一样需重新分片。

  3. 分区指令: ./redis-trib.rb reshard 192.168.210.128:7002
  4. 输入提示的需要移动的分片大小,分配给7001的slots为4096,输入需要移动的片为4096。
  5. 输入这些移除的slots如何分配给其他node,可指定一个具体node的id或者选择所有。
  6. 最后确认后,开始移除节点。

移除从节点

  1. 移除节点使用redis-trib的del-node命令,redis-trib del-node 192.168.210.128:7002  ${node-id}  。操作指令含义: 192.168.210.128:7000为指定集群,node-id为要删除的节点。 和添加节点不同,移除节点node-id是必需的。
  2. 从节点不存在分片问题,直接执行命令,确认移除即可。

4.redis-cluster集群与分布式连接池区别

ShardedJedisPool是redis没有集群功能之前客户端实现的一个数据分布式方案,redis3.0提供集群之后,客户端则采用JedisCluster实现连接redis集群环境。 ShardedJedisPool使用的是JedisShardInfo的instance的顺序或者name来做的一致性哈希,JedisCluster使用的是CRC16算法来做的哈希槽。

集群环境各个服务之间的数据是隔离的。无论是ShardedJedisPool的一致性哈希算法还是JedisCluster的CRC16哈希槽算法,都是把所有的服务叠加然后进行均匀的分割,分割出来的每一个段或槽都是不重复的,所以导致存储的数据彼此之间也是处于隔离状态的。

jediscluster通过在客户端调用捕捉异常,可实现集群环境下的高可用。Jedis还提供了对jedis sentinel pool的封装,所以ShardedJedisPool发生主从切换的时候,web server都不需要重新配置和deploy。高可用性的极佳体现啊。

5.java客户端调用redis-cluster

更新pom文件中redis-clients的版本,低版本会报错。<redis-clients.version>2.9.0</redis-clients.version>

java客户端调用redis-cluster可通过在java代码中直接填写地址或通过spring配置文件填写,具体可参考上传的代码。在java中调用集群案例代码如下:

/*** Description:  redis cluster 测试* Copyright:  2018 CSNT. All rights reserved.* Company:CSNT** @author wangling* @version 1.0*/
public class RedisClusterTestDemo {@Testpublic void testRedisCluster() throws Exception {JedisPoolConfig poolConfig = new JedisPoolConfig();Set<HostAndPort> nodes = new HashSet<HostAndPort>();HostAndPort hostAndPort = new HostAndPort("192.168.210.128", 7000);HostAndPort hostAndPort1 = new HostAndPort("192.168.210.128", 7001);HostAndPort hostAndPort2 = new HostAndPort("192.168.210.128", 7002);HostAndPort hostAndPort3 = new HostAndPort("192.168.210.128", 7003);HostAndPort hostAndPort4 = new HostAndPort("192.168.210.128", 7004);HostAndPort hostAndPort5 = new HostAndPort("192.168.210.128", 7005);nodes.add(hostAndPort);nodes.add(hostAndPort1);nodes.add(hostAndPort2);nodes.add(hostAndPort3);nodes.add(hostAndPort4);nodes.add(hostAndPort5);JedisCluster jedisCluster = new JedisCluster(nodes,5000,1000);jedisCluster.set("jedisKey","wangling test jedisKey");//redis内部会创建连接池,从连接池中获取连接使用,然后再把连接返回给连接池String string = jedisCluster.get("jedisKey");System.out.println(string);}}

//基于配置文件调用,完整配置信息参考上传的源代码
/*** Description:  redis cluster 测试* Copyright:  2018 CSNT. All rights reserved.* Company:CSNT** @author wangling* @version 1.0*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:redis-cluster-context.xml")
public class JedeisClusterTest {@Autowiredprivate JedisCluster jedisCluster;@Testpublic void testJedisCluster(){jedisCluster.set("jedisCluster", "wangling test jedisCluster");String val = jedisCluster.get("jedisCluster");System.out.println(val);}
}

软件运行截图如下:

6.参考网址

  • 分布式缓存技术redis学习系列(七)——spring整合jediscluster
  • Linux 安装Ruby详解(在线和离线安装)
  • 解决方法:配置群集时gem install redis 报错
  • redis 学习笔记(6)-cluster集群搭建
  • Redis介绍及Jedis基础操作

7.源码下载

在Git上面下载:https://github.com/wuya11/redisClusterDemo

转载于:https://www.cnblogs.com/wlandwl/p/rediscluster.html

Redis Cluster集群搭建与应用相关推荐

  1. Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)

    前提:先安装好Redis,参考:http://www.cnblogs.com/EasonJim/p/7599941.html 说明:Redis Cluster集群模式可以做到动态增加节点和下线节点,使 ...

  2. Ubuntu 16.04 下Redis Cluster集群搭建

    实际操作如下: 准备工作 版本:4.0.2 下载地址:https://redis.io/download 离线版本:(链接: https://pan.baidu.com/s/1bpwDtOr 密码: ...

  3. centos7 docker-compose安装_Docker Compose 搭建 Redis Cluster 集群环境

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

  4. Redis Cluster 集群详解

    Redis 分布式扩展之 Redis Cluster 方案 主从切换的过程中会丢失数据,因为只有一个 master,只能单点写,没有解决水平扩容的问题.而且每个节点都保存了所有数据,一个是内存的占用率 ...

  5. python连接redis集群如何释放内存_python 连接 redis cluster 集群

    一. redis集群模式有多种, cluster模式只是其中的一种实现方式, 其原理请自行谷歌或者百度, 这里只举例如何使用Python操作 redis cluster 集群 二. python 连接 ...

  6. Redis Cluster集群的搭建与实践[转]

    Redis Cluster集群的搭建与实践 Redis Cluster集群 一.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后 ...

  7. Redis Cluster集群的搭建与实践

    Redis Cluster集群 一.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Re ...

  8. redis映射的概念_搭建分布式Redis Cluster集群与Redis入门

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

  9. Docker搭建3主3从Redis Cluster集群

    本文使用镜像由慕课网的神思者老师提供 本文使用镜像是已经配置好了的Redis镜像, 如果需要自定义可修改配置文件或用官方Redis镜像进行部署 1. 拉取配置好的Redis镜像 docker pull ...

  10. redis集群扩容和缩容_深入理解Redis Cluster集群

    一.背景 前面的文章<深入理解Redis哨兵机制>一文中介绍了Redis哨兵集群的工作原理,哨兵集群虽然满足了高可用的特性,但是依然存在这样的问题:即数据只能往一个主节点上进行写入. 只能 ...

最新文章

  1. 有段位的管理者,都是怎么管理的?
  2. Axure8.0深入一点(篇)
  3. 安装nvidia-docker2
  4. 权限框架 - shiro 简单入门实例
  5. linux运行星际争霸1
  6. 关于反射的我的一些看法
  7. 链表查找java_Java 实例 – 链表元素查找
  8. S3C2440之MMU
  9. [MySQL][Spider][VP]Spider-3.1 VP-1.0 发布
  10. Flutter打包apk中的一些巨坑
  11. 戴尔计算机软件的安装,买的新戴尔电脑怎么安装软件
  12. github java 性能,JavaGuide/手把手教你定位常见Java性能问题.md at master · Github-Programer/JavaGuide · GitHub...
  13. java 切图 软件_Java 切图
  14. 深度学习论文-Cyclical Learning Rates for Training Neural Networks
  15. arm服务器运行onlyoffice
  16. mysql管理工具10.1,NavicatforMySQL10
  17. STM32F103C8T6寄存器简单应用(流水灯)
  18. 西宁计算机二级辅导班,西宁的计算机二级去哪里考啊?
  19. 关于静态文本框透明度的问题
  20. php strchr函数,C语言入门知识:strchr函数

热门文章

  1. thinkphp 5.0 模块设计
  2. 《转》常用的正则表达式
  3. SDUT_2012省赛选拔赛2 部分题目
  4. sizeof(空类或空结构体)
  5. 最近运气不好。很不爽!!!!!
  6. 煤矿行业设备管理系统
  7. docker--删除container和image
  8. nginx 服务器并发优化
  9. 【转】化学怀旧风:用扑热息痛冲胶卷!
  10. 200个化工网站批量爬取