设为首页 收藏本站
查看: 778|回复: 0

[经验分享] 170103、Redis官方集群方案 Redis Cluster

[复制链接]

尚未签到

发表于 2017-12-21 06:04:03 | 显示全部楼层 |阅读模式
  前面我们谈了Redis Sharding多服务器集群技术,Redis Sharding是客户端Sharding技术,对于服务端来说,各个Redis服务器彼此是相互独立的,这对于服务端根据需要灵活部署Redis非常轻便,Redis Sharding具有很好的灵活性、可伸缩性,是一种轻量级集群技术。
  本篇,介绍另外一种多Redis服务器集群技术,即Redis Cluster。Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供。
  Redis Cluster中,Sharding采用slot(槽)的概念,一共分成16384个槽,这有点儿类似前面讲的pre sharding思路。对于每个进入Redis的键值对,根据key进行散列,分配到这16384个slot中的某一个中。使用的hash算法也比较简单,就是CRC16后16384取模。
  Redis集群中的每个node(节点)负责分摊这16384个slot中的一部分,也就是说,每个slot都对应一个node负责处理。当动态添加或减少node节点时,需要将16384个槽做个再分配,槽中的键值也要迁移。当然,这一过程,在目前实现中,还处于半自动状态,需要人工介入。
  Redis集群,要保证16384个槽对应的node都正常工作,如果某个node发生故障,那它负责的slots也就失效,整个集群将不能工作。
  为了增加集群的可访问性,官方推荐的方案是将node配置成主从结构,即一个master主节点,挂n个slave从节点。这时,如果主节点失效,Redis Cluster会根据选举算法从slave节点中选择一个上升为主节点,整个集群继续对外提供服务。这非常类似前篇文章提到的Redis Sharding场景下服务器节点通过Sentinel监控架构成主从结构,只是Redis Cluster本身提供了故障转移容错的能力。
  Redis Cluster的新节点识别能力、故障判断及故障转移能力是通过集群中的每个node都在和其它nodes进行通信,这被称为集群总线(cluster bus)。它们使用特殊的端口号,即对外服务端口号加10000。例如如果某个node的端口号是6379,那么它与其它nodes通信的端口号是16379。nodes之间的通信采用特殊的二进制协议。
  对客户端来说,整个cluster被看做是一个整体,客户端可以连接任意一个node进行操作,就像操作单一Redis实例一样,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node,这有点儿像浏览器页面的302 redirect跳转。
  Redis Cluster是Redis 3.0以后才正式推出,时间较晚,目前能证明在大规模生产环境下成功的案例还不是很多,需要时间检验。
  集群搭建R
  下面,我们就实际操作建立一个Redis Cluster。我们将建立3个node,每个node架构成一主一从,故总共有6个redis实例,端口号从7000-7005。
  Cluster下的Redis实例,和普通Redis实例一样,只是处于cluster模式方式下运行。
  实操步骤如下:
  1. 以3.0.5为例,建立cluster目录,其下再建6个子目录代表6实例环境
  mkdir cluster
  mkdir 7000 7001 7002 7003 7004 7005
  2. 将redis.conf模板分别copy到上面6子目录中,并做如下修改,以7000为例:
  修改如下信息
  daemonize yes
  pidfile /var/run/redis-7000.pid
  port 7000
  logfile "/var/log/redis-7000.log"
  注释掉如下信息, 不需要RDB持久化
  #save 900 1
  #save 300 10
  #save 60 10000
  修改如下信息
  appendonly yes
  appendfilename "appendonly-7000.aof"
  取消如下注释,让Redis在集群模式下运行
  cluster-enabled yes 启动cluster模式
  cluster-config-file nodes-7000.conf 集群信息文件名,由redis自己维护
  cluster-node-timeout 15000 15秒中联系不到对方node,即认为对方有故障可能
  3. 在各个目录下执行 redis-server redis.conf 启动redis实例
  这时,这几个实例都是各自是一个集群状态在运行,并没有形成一个整体集群态,我们需要Redis提供的基于ruby开发的工具进行人工设置。
  4.安装ruby环境
  yum install ruby ruby-devel rubygems
  5.安装Redis的ruby依赖接口
  gem install redis
  6.利用脚本工具建立集群
  ./redis-trib.rb create --replicas 1 192.168.1.142:7000 192.168.1.142:7001 192.168.1.142:7002 192.168.1.142:7003 192.168.1.142:7004 192.168.1.142:7005
  该脚本自动执行节点分配方案,将前3个redis实例作为主节点,后三个作为从节点,如图:
DSC0000.jpg

  按提示敲入"yes",执行方案,将6个节点组成集群,3主3从。
  执行redis-cli -p 7000 info Replication 命令,观察7000这个节点,发现其复制配置信息已配置成主节点,并有一个从节点7003
DSC0001.jpg

  再执行redis-cli -p 7003 info Replication发现,该节点已设置成从节点。这些主从设置,都是在创建集群时自动完成的。
DSC0002.jpg

  至此,3主3从的Redis集群建立起来了。接下来我们做个故障转移试验,将主节点7001 shutdown掉,看看发生什么?
DSC0003.jpg

  我们看到,从节点7004会上升为主节点继续提供集群服务。那又重新启动7001节点呢?
DSC0004.jpg

  我们发现7001节点已经成为从节点,不会成为取代7004成为主节点。那如果将主节点7001和从节点7004都shutdown掉呢?
DSC0005.jpg

  这时,整个cluster是拒绝提供服务的。因为原来7001分配的slot现在无节点接管,需要人工介入重新分配slots。
  增删集群节点R
  下面我们操作下,如果修改集群节点架构:
  删除一个从节点。注意,如果删除主节点,其负责的slots必须为空。
  ./redis-trib.rb del-node 192.168.1.142:7000 ee2fc0ea6e630f54e3b811caedf8896b26a99cba
  将7001节点的slot都转移到7000
  ./redis-trib.rb reshard 192.168.1.142:7000
  按提示操作即可。
  加一个节点。注意新添加的节点还没有分配slot,用reshard给它分配一定比例的slots
  ./redis-trib.rb add-node 192.168.1.142:7001 192.168.1.142:7000
  给指定一个主节点添加一个从节点。
  ./redis-trib.rb add-node --slave --master-id f4d17d56a9dda1a102da7cd799192beff7cba69e 192.168.1.142:7004 192.168.1.142:7000
  注意如果此redis实例参与过集群,需先cluster reset 清除重置一下。
  Jedis客户端访问R
  上面介绍了服务端Redis Cluster搭建过程。下面来看看客户端如何使用?
  Java语言的客户端驱动Jedis是支持Redis Cluster的。我们具体实操下:
  1. pom.xml中配置jedis jar包
  <dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.0</version> <!-- 最近升级了 -->
  </dependency>
  2. spring配置文件中配置JedisCluster
  <bean>
  <property name="maxTotal" value="4096"/>
  <property name="maxIdle" value="200"/>
  <property name="maxWaitMillis" value="3000"/>
  <property name="testOnBorrow" value="true" />
  <property name="testOnReturn" value="true" />
  </bean>
  <bean>
  <constructor-arg index="0">
  <set>
  <bean>
  <constructor-arg index="0" value="192.168.1.142" />
  <constructor-arg index="1" value="7002" />
  </bean>
  </set>
  </constructor-arg>
  <constructor-arg index="1" value="2000" type="int"/>
  <constructor-arg index="2" value="2" type="int"/>
  <constructor-arg index="3" ref="poolConfig"/>
  </bean>
  3.编写测试代码
  @Test
  public void basicOpTestForCluster(){
  long begin = System.currentTimeMillis();
  for(int i=0;i<10000; i++){
  jedis.set("person." + i + ".name", "frank");
  jedis.set("person." + i + ".city", "beijing");
  String name = jedis.get("person." + i + ".name");
  String city = jedis.get("person." + i + ".city");
  assertEquals("frank",name);
  assertEquals("beijing",city);
  jedis.del("person." + i + ".name");
  Boolean result = jedis.exists("person." + i + ".name");
  assertEquals(false,result);
  result = jedis.exists("person." + i + ".city");
  assertEquals(true,result);
  }
  long end = System.currentTimeMillis();
  System.out.println("total time: " + (end-begin)/1000);
  }
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-426270-1-1.html 上篇帖子: Redis在电商中的实际应用 下篇帖子: redis的面试题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表