分布式缓存Redis之cluster集群

2024-06-09 19:38

本文主要是介绍分布式缓存Redis之cluster集群,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面

  本学习教程所有示例代码见GitHub:https://github.com/selfconzrr/Redis_Learning

  官方文档:
  集群教程:http://www.redis.cn/topics/cluster-tutorial.html
  集群规范:http://www.redis.cn/topics/cluster-spec.html

  这里写图片描述

  jedis客户端操作redis主要三种模式:单台模式、分片模式(ShardedJedis)、集群模式(BinaryJedisCluster),分片模式是一种轻量级集群。

  单台模式、分片模式(ShardedJedis)前面已经讲述过。这篇文章主要来看集群模式。

  现在项目上用redis的话,很少说不用集群的情况,毕竟如果生产上只有一台redis会有极大的风险,比如机器挂掉,或者内存爆掉,都会导致数据丢失。从Redis3.0,Jedis2.9版本开始有了cluster的概念。

一、Redis集群介绍

Redis 集群的特点

1)是一个提供在多个Redis间节点间共享数据的程序集;
2)并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误。
3)通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令。
4)Redis 集群是 Redis 的一个分布式实现;
5)所有的redis节点彼此互联**(PING-PONG机制),内部使用二进制协议优化传输速度和带宽;
6)节点的fail是通过
集群中超过半数的节点检测失效时**才生效;
7)客户端与redis节点直连,不需要中间proxy代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
8)Redis 集群是3.0之后才引入的,在3.0之前,使用哨兵(sentinel)机制(前面的文章已经介绍过)来监控各个节点之间的状态。

Redis 集群的优势
  • 自动分割数据到不同的节点上。
  • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
Redis 集群的数据分片

  Redis 集群没有使用一致性hash,而是引入了哈希槽的概念。Redis 集群有16384个哈希槽(slot),当需要在 Redis 集群中放置一个 key-value 时,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

  比如当前集群有3个节点,那么:

  • 节点 A 包含 0 到 5500号哈希槽
  • 节点 B 包含5501 到 11000 号哈希槽
  • 节点 C 包含11001 到 16383号哈希槽

  这种结构很容易添加或者删除节点。比如如果我想新添加个节点D, 我需要从节点 A, B, C中分部分槽到D上。如果我想移除节点A,需要将A中得槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。

  由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

Redis只会为主节点分配哈希槽

  集群分区,最主要的目的是在移除、添加一个节点时对已经存在的缓存数据的定位影响尽可能的降到最小。

  和memcached一样,Redis也采用一定的算法进行键-槽(key->slot)之间的映射。memcached采用一致性哈希(consistency hashing)算法进行键-节点(key-node)之间的映射,而redis集群使用集群公式来计算键 key 属于哪个槽:

HASH_SLOT(key)= CRC16(key) % 16384
Redis 集群的主从复制模型

  为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品。

  在我们的例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用。

  然而如果在集群创建的时候(或者过一段时间),我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了。不过当B和B1 都失败后,集群是不可用的。

什么时候整个集群不可用(cluster_state:fail)?

  • 如果集群任意master挂掉,且当前master没有slave,集群进入fail状态。也可以理解成集群的slot映射[0-16383]不完成时进入fail状态;
  • 如果集群超过半数以上master挂掉,无论是否有slave集群进入fail状态

  **ps:**当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误。

二、搭建并使用Redis集群

这两篇介绍的非常详细。
https://www.cnblogs.com/hjwublog/p/5681700.html
http://blog.csdn.net/boonya/article/details/49362819

  只在这总结一下经常遇到的问题:主要是随着年代的更新,版本的更新,很多源/库,现在都没了。

1、redis-trib.rb命令提示not command,即不能执行集群安装命令:

  redis-trib.rb是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下。因为redis-trib.rb是用ruby语言编写,系统没有安装ruby环境。

  **解决办法:**Ubuntu下安装ruby命令:

sudo apt-get install ruby

2、再进一步,提示出错:cannot load such file --redis

  这是因为需要安装驱动,在安装驱动之前,需要替换资源库,否则资源请求地址会报错,不知道从什么时候开始,使用淘宝的gemsruby资源库(https://ruby.taobao.org/),会提示Error fetching https://ruby.taobao.org/

  发现原来是taobao Gems 源已停止维护,现由 ruby-china 提供镜像服务,即我们要换源:http://gems.ruby-china.org/

  补充此处的几条命令:

1、删除默认的官方源:
gem sources -r https://rubygems.org/2、(以前的) 添加淘宝源:
gem sources -a https://ruby.taobao.org/3、(现在应该添加的)注意:这里是http而不是https
gem sources -a http://gems.ruby-china.org/4、查看当前源:
gem sources -l

3、redis-trib.rb具有以下功能:

  ● create :创建集群● check :检查集群● info :查看集群信息● fix :修复集群● reshard :在线迁移slot● rebalance :平衡集群节点slot数量● add-node :将新节点加入集群● del-node :从集群中删除节点● set-timeout :设置集群节点间心跳连接的超时时间● call :在集群全部节点上执行命令● import :将外部redis数据导入集群● redis-trib.rb主要有两个类: ClusterNode 和 RedisTrib 。 ClusterNode保存了节点本身以及处于集群中的所有节点的状态, RedisTrib 则是redis-trib.rb各个功能的实现。

  比如:

向集群中添加节点,7037是新增节点,7036是集群中已有的节点
./redis-trib.rb add-node 192.168.2.128:7037 192.168.2.128:7036
重新分配槽
./redis-trib.rb reshard 192.168.2.128:7031
指定当前节点的主节点
cluster replicate cf48228259def4e51e7e74448e05b7a6c8f5713f
删除节点
./redis-trib.rb del-node 192.168.2.128:7037 'a56461a171334560f16652408c2a45e629d268f6'

4、在安装redis-cluster过程中可以节省时间的操作集合

1)如何快速启动六个(或更多)服务器?

方法一:依次进入每个节点目录(时间都浪费在切换目录上了),执行 ./redis-server redis.conf.

方法二:写个shell脚本,vim startall.sh就会打开vim编辑器,创建一个空的文本:
即将方法一在命令行操作的指令集合到文本里。以一个节点为例:

cd redis01
./redis-server redis.conf
cd ..
cd redis02
blurblur....

  执行./startall.sh 提示permission denied说明权限不足,执行命令chmod 777 startall.sh修改权限即可。

方法三:用脚本循环启动,这样更方便省时

for((i=1;i<=6;i++)); do /usr/local/redis/bin/redis-server /usr/local/redis-cluster/703$i/redis.conf; done

三、redis cluster命令

集群(cluster)
cluster info 打印集群的信息
cluster nodes 列出集群当前已知的所有节点(node),以及这些节点的相关信息节点
cluster meet 将ip和port所指定的节点添加到集群当中,让它成为集群的一份子

cluster forget <node_id> 从集群中移除node_id指定的节点
cluster replicate <node_id> 将当前节点设置为node_id指定的节点的从节点
cluster saveconfig 将节点的配置文件保存到硬盘里面

cluster slaves <node_id> 列出该slave节点的master节点
cluster set-config-epoch 强制设置configEpoch槽(slot)

cluster addslots [slot …] 将一个或多个槽(slot)指派(assign)给当前节点
cluster delslots [slot …] 移除一个或多个槽对当前节点的指派
cluster flushslots 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点

cluster setslot node <node_id> 将槽slot指派给node_id指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派
cluster setslot migrating <node_id> 将本节点的槽slot迁移到node_id指定的节点中
cluster setslot importing <node_id> 从node_id 指定的节点中导入槽slot到本节点

cluster setslot stable 取消对槽slot的导入(import)或者迁移(migrate) 键
cluster keyslot 计算键key应该被放置在哪个槽上
cluster countkeysinslot 返回槽slot目前包含的键值对数量
cluster getkeysinslot 返回count个slot槽中的键

其它
cluster myid 返回节点的ID
cluster slots 返回节点负责的slot
cluster reset 重置集群,慎用

四、Redis集群方案

最早的Redis Sharding分片方案,然后Sentinel哨兵方案,前面介绍的是官方推出的Redis-cluster方案。

基于代理的分片方案:

  • Twemproxy(已经不维护了):GitHub链接:https://github.com/twitter/twemproxy
  • codis:现在比较推荐,可以参考博文学习:http://www.jianshu.com/p/14835303b07e

------至所有正在努力奋斗的程序猿们!加油!!
有码走遍天下 无码寸步难行
1024 - 梦想,永不止步!
爱编程 不爱Bug
爱加班 不爱黑眼圈
固执 但不偏执
疯狂 但不疯癫
生活里的菜鸟
工作中的大神
身怀宝藏,一心憧憬星辰大海
追求极致,目标始于高山之巅
一群怀揣好奇,梦想改变世界的孩子
一群追日逐浪,正在改变世界的极客
你们用最美的语言,诠释着科技的力量
你们用极速的创新,引领着时代的变迁

——乐于分享,共同进步,欢迎补充
——Any comments greatly appreciated
——诚心欢迎各位交流讨论!QQ:1138517609
——CSDN:https://blog.csdn.net/u011489043
——GitHub:https://github.com/selfconzrr

这篇关于分布式缓存Redis之cluster集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046112

相关文章

Eureka高可用注册中心registered-replicas没有分布式注册中心

自己在学习过程中发现,如果Eureka挂掉了,其他的Client就跑不起来了,那既然是商业项目,还是要处理好这个问题,所以决定用《Spring Cloud微服务实战》(PDF版在全栈技术交流群中自行获取)中说的“高可用注册中心”。 一开始我yml的配置是这样的 server:port: 8761eureka:instance:hostname: 127.0.0.1client:fetch-r

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

为什么要做Redis分区和分片

Redis分区(Partitioning)和分片(Sharding)是将数据分布在多个Redis实例或多个节点上的做法。这种技术用于提高性能、可扩展性和可用性。以下是执行Redis分区和分片的主要原因: 1. **提高吞吐量**:    - 通过将数据分散到多个节点,可以并行处理更多的操作,从而提高整体吞吐量。 2. **内存限制**:    - 单个Redis实例的内存是有限的。分区允许数据

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源

Redis-在springboot环境下执行lua脚本

文章目录 1、什么lua2、创建SpringBoot工程3、引入相关依赖4、创建LUA脚本5、创建配置类6、创建启动类7、创建测试类 1、什么lua “Lua”的英文全称是“Lightweight Userdata Abstraction Layer”,意思是“轻量级用户数据抽象层”。 2、创建SpringBoot工程 3、引入相关依赖 <?xml version

设置Nginx缓存策略

详细信息 Nginx服务器的缓存策略设置方法有两种:add_header或者expires。 1. add_header 1)语法:add_header name value。 2)默认值:none。 3)使用范围:http、server、location。 配置示例如下: add_header cache-control "max-age=86400";#设置缓存时间为1天。add

[分布式网络通讯框架]----Zookeeper客户端基本操作----ls、get、create、set、delete

Zookeeper数据结构 zk客户端常用命令 进入客户端 在bin目录下输入./zkCli.sh 查看根目录下数据ls / 注意:要查看哪一个节点,必须把路径写全 查看节点数据信息 get /第一行代码数据,没有的话表示没有数据 创建节点create /sl 20 /sl为节点的路径,20为节点的数据 注意,不能跨越创建,也就是说,创建sl2的时候,必须确保sl

大型网站架构演化(四)——使用应用服务器集群改善网站的并发能力

使用集群是网站解决高并发、海量数据问题的常用手段。当一台服务器的处理能力、存储空间不足时,不要企图去更换更强大的服务器,对大型服务器而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求。这种情况下,更恰当的做法是增加一台服务器分担原有服务器的访问及存储压力。 对网站架构而言,只要能通过增加一台服务器的方式改善负载压力,就可以以同样的方式持续增加服务器不断改善系统性能,从而实现系统

redis切换数据库的方法【jedis】

package com.test;import redis.clients.jedis.Jedis;public class readredis {public static void main(String[] args) {// 连接本地的 Redis 服务Jedis jedis = new Jedis("127.0.0.1", 6379);jedis.select(10);String v

Redis 高性能基本操作

单元素操作是基础 单元素操作,是指每一种集合类型对单个数据实现增删改查 例如,Hash 类型的 HGET、HSET 和 HDEL,Set 类型的 SADD、SREM、SRANDMEMBER 等这些操作的复杂度由集合采用的数据结构决定,例如,HGET、HSET 和 HDEL 是对哈希表做操作,所以它们的复杂度都是 O(1)Set 类型用哈希表作为底层数据结构时,它的 SADD、SREM、SRAN