Redis Cluster集群搭建与应用
1.redis-cluster设计
Redis集群搭建的方式有多种,例如使用zookeeper,但从redis 3.0之后版本支持redis-cluster集群,redis-cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster架构图如下:
其结构特点
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
- 节点的fail是通过集群中超过半数的节点检测失效时才生效。
- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
- redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
- 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为了保证数据的高可用性,加入了主从模式,一个主节点对应一个或多个从节点,主节点提供数据存取,从节点则是从主节点拉取数据备份,当这个主节点挂掉后,就会有这个从节点选取一个来充当主节点,从而保证集群不会挂掉。主从模式具有如下特点:
- 集群有7000,7001,7002三个主节点, 如果这3个节点都没有加入从节点,如果7001挂掉了,就无法访问整个集群,7000和7002的slot也无法访问。
- 主从节点同时挂掉后,如节点7001和7004同时挂了,Redis集群将无法继续正确地提供服务。
- 为每个主节点设置从节点, 比如像这样, 集群包含主节点7000,7001,7002 以及从节点7003,7004,7005, 那么即使7001挂掉系统也可以继续正确工作。7004节点替代了7001节点,所以Redis集群将会选择7004节点作为新的主节点,集群将会继续正确地提供服务。 当7001重新开启后,它就会变成7004的从节点。
2.redis-cluster集群搭建
搭建环境
本次测试采用虚拟机模式,在本机上做测试,虚拟机环境为Centos7.0。搭建集群需要如下相关依赖软件,下载地址为“
- rubygems软件包下载:https://rubygems.org/pages/download
- ruby软件包下载:http://www.ruby-lang.org/en/downloads/
- redis-3.2.2.gem依赖包下载:https://rubygems.global.ssl.fastly.net/gems/redis-3.2.2.gem
- 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模式安装的,但考虑到翻墙等限制条件,本文采用离线模式安装。
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离线安装
- Ruby下载地址:http://www.ruby-lang.org/en/downloads/ ,最新的版本为2.5.0。
- Ruby安装参考网址:Linux 安装Ruby详解(在线和离线安装)
- 在安装之前,请确保使用账号具有Root权限,将下载的Ruby安装包上传到服务器当中,通过xtfp5工具进行文件上传:解压上传文件, tar -zxvf ruby-2.5.0.tar.gz,进入到ruby-2.5.0目录执行指令make && make install安装,安装成功可通过指令:ruby -v查看版本号:
步骤5:安装RubyGems环境
安装RubyGems环境。网上很多博客都是采用yum模式安装的,但考虑到翻墙等限制条件,本文采用离线模式安装。
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 版本,也可以通过手动安装:
- RubyGems下载地址:https://rubygems.org/pages/download
- RubyGems安装参考网址:Linux 离线安装Rubygems详解
- 解压下载文件并进入目录,解压指令tar -zxvf rubygems-2.7.4.tgz,执行命令:ruby setup.rb
步骤6:安装openssl
使用gem install 安装 ruby redis。直接操作会报如下错误,查看原因是因为缺少openssl。
离线安装openssl
- openssl下载地址:http://www.openssl.org/source/
- openssl安装参考网址:配置群集时# gem install redis 报错:Unable to require openssl, install OpenSSL and rebuild ruby
- 解压下载文件并进入目录,解压指令如: 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
- 执行以上命令安装openssl,安装后查看版本号如下:
- 解决ssl.h文件找不到的问题,配置ruby文件,# ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/ --with-openssl-lib=/usr/local/openssl/lib
- 设置软链接:ln -s /usr/local/src/ruby-2.2.3/include /
- 再次编译安装,成功后如下图所示:
步骤7: 安装redis-trib.rb运行依赖的ruby的包redis-3.2.2.gem
- redis-3.2.2.gem下载地址:https://rubygems.global.ssl.fastly.net/gems/redis-3.2.2.gem
- 下载完成后上传到服务器上面,执行安装命令如: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作为主节点,操作步骤如下:
- 修改配置文件,新建一个对应的文件7006,并把复制配置文件redis.conf放入到文件7006下面,并修改配置文件,把端口修改为7006,其他配置信息也参考前面的案例对应修改。节点配置信息成功后,启动7006下面的redis。
- 将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 表示加入的集群的一个节点,用来辨识是哪个集群,理论上那个集群的节点都可以。
- 目前cluster已经定义7006为主节点,但是Cluster并未给7006分配哈希卡槽(0 slots)。
- 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。
- redis-trib 会向你询问重新分片的源节点(source node),即,要从特定的哪个节点中取出 4096 个哈希槽,还是从全部节点提取4096个哈希槽, 并将这些槽移动到7006节点上。如果不打算从特定的节点上取出指定数量的哈希槽,那么可以向redis-trib输入 all,这样的话, 集群中的所有主节点都会成为源节点,redis-trib从各个源节点中各取出一部分哈希槽,凑够4096个,然后移动到7006节点上。操作命令为:Source node #1:all 。
- 确认之后,redis-trib就开始执行分片操作,将哈希槽一个一个从源主节点移动到7006目标主节点。重新分片结束后可以check以下节点的分配情况。指令为:./redis-trib.rb check 192.168.210.128:7002。可查看扩容主节点是否成功。
新增从节点
- 新增一个节点7007作为从节点修改配置文件,新建一个对应的文件7007,并把复制配置文件redis.conf放入到文件7007下面,并修改配置文件,把端口修改为7007,其他配置信息也参考前面的案例对应修改。节点配置信息成功后,启动7007下面的redis并加入到现有集群中。
- 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将会将新增的从节点随机到从节点较少的主节点上。
- 从节点不存在分片操作,与主节点对应的片一致。
移除主节点
移除节点使用redis-trib的del-node命令,redis-trib del-node 192.168.210.128:7002 ${node-id} 。操作指令含义: 192.168.210.128:7000为指定集群,node-id为要删除的主节点。 和添加节点不同,移除节点node-id是必需的。
测试删除7001主节点,redis cluster提示7001已经有数据了,不能够被删除,需要将他的数据转移出去,也就是和新增主节点一样需重新分片。
- 分区指令: ./redis-trib.rb reshard 192.168.210.128:7002
- 输入提示的需要移动的分片大小,分配给7001的slots为4096,输入需要移动的片为4096。
- 输入这些移除的slots如何分配给其他node,可指定一个具体node的id或者选择所有。
- 最后确认后,开始移除节点。
移除从节点
- 移除节点使用redis-trib的del-node命令,redis-trib del-node 192.168.210.128:7002 ${node-id} 。操作指令含义: 192.168.210.128:7000为指定集群,node-id为要删除的节点。 和添加节点不同,移除节点node-id是必需的。
- 从节点不存在分片问题,直接执行命令,确认移除即可。
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 {
@Test
public 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 {
@Autowired
private JedisCluster jedisCluster; @Test
public 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
Redis Cluster集群搭建与应用的更多相关文章
- Redis Cluster集群搭建与配置
Redis Cluster是一种服务器sharding分片技术,关于Redis的集群方案应该怎么做,请参考我的另一篇博客http://www.cnblogs.com/xckk/p/6134655.ht ...
- Redis Cluster集群搭建<原>
一.环境配置 一台window 7上安装虚拟机,虚拟机中安装的是centos系统. 二.目标 Redis集群搭建的方式有多种,根据集群逻辑的位置,大致可以分为三大类:基于客户端分片的Redis ...
- Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)
前提:先安装好Redis,参考:http://www.cnblogs.com/EasonJim/p/7599941.html 说明:Redis Cluster集群模式可以做到动态增加节点和下线节点,使 ...
- 【Redis】Redis cluster集群搭建
Redis集群基本介绍 Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施installation. Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行 ...
- Redis Cluster集群搭建后,客户端的连接研究(Spring/Jedis)(待实践)
说明:无论是否已经搭建好集群,还是使用什么样的客户端去连接,都是必须把全部IP列表集成进去,然后随机往其中一个IP写. 这样做的好处: 1.随机IP写入之后,Redis Cluster代理层会自动根据 ...
- centos8平台redis cluster集群搭建(redis5.0.7)
一,规划 redis cluster 1,cluster采用六台redis,3主3从 redis1 : ip: 172.17.0.2 redis2 : ip: 172.17.0.3 red ...
- Redis Cluster 集群搭建与扩容、缩容
说明:仍然是伪集群,所有的Redis节点,都在一个服务器上,采用不同配置文件,不同端口的形式实现 前提:已经安装好了Redis,本文的redis的版本是redis-6.2.3 Redis的下载.安装参 ...
- redis cluster 集群搭建步骤和注意事项
1.安装Ubuntu ,修改root的密码. sudo passwd (apt-get update 更新系统) 2.安装 Gcc 和G++ sudo apt-get install build- ...
- Ubuntu 16.04 下Redis Cluster集群搭建
实际操作如下: 准备工作 版本:4.0.2 下载地址:https://redis.io/download 离线版本:(链接: https://pan.baidu.com/s/1bpwDtOr 密码: ...
随机推荐
- IDE 、SATA、SCSI 的区别
http://chuanwang66.iteye.com/blog/1134784 IDE IDE的英文全称为“Integrated Drive Electronics”,即“电子集成驱动器”,它的 ...
- Webpack 2 视频教程 010 - 配置 ESLint 实现代码规范自动测试 (下)
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- 深入.NET数据类型(2)
一.装箱和拆箱 将值类型转换为引用类型的过程称为装箱,反之称为拆箱 实际开发尽量避免 装/拆 箱 原因: 装/拆 箱都会降低程序性能 示例代码: static void Main(string[] a ...
- 微服务时代TestOps工程师学习总结
TestOps很新鲜,也是近期衍生的新型职位.那TestOps主要目的是推动整个研发体系与发布体系更多在质量方面.可以这样理解DevOps是从研发推动配合运维和测试,而TestOps是从测试角度推动研 ...
- \Process(sqlservr)\% Processor Time 计数器飙高
计数器" \Process(sqlservr)\% Processor Time",是经常监测,看看SQL Server如何消耗CPU资源.sqlserver是如何利用现有的资源; ...
- 在commons-lang3包中StringUtils类的ordinalIndexOf中有一个错误
* StringUtils.ordinalIndexOf(null, *, *) = -1 * StringUtils.ordinalIndexOf(*, null, *) = -1 * String ...
- SQLAlchemy基础操作一
用前安装 pip3 install sqlalchemy ORM ORM就是运用面向对象的知识,将数据库中的每个表对应一个类,将数据库表中的记录对应一个类的对象.将复杂的sql语句转换成类和对象的操作 ...
- dom4j 间隔插入节点 处理复杂的xml文档
前几周跟着老师做了一个小项目,个人主要负责xml文档处理,处理过程还是比较复杂的.此外这篇文章并不是讲基本的dom4j读写xml文档, 所以阅读此文的前提是你已经有了dom4j或jdom等处理xml文 ...
- Coursera课程 Programming Languages, Part B 总结
Programming Languages, Part A Programming Languages, Part B Part A 笔记 碎言碎语 很多没有写过 Lisp 程序的人都会对 Lisp ...
- 运算符、单双分支&多分支、while循环
一 .运算符: 1. 算术运算符: " + "." - " ." * " ." / " 分别为加.减.乘.除. % 是& ...