精华内容
下载资源
问答
  • redis cluster配置文件

    2018-08-12 14:51:48
    redis cluster配置文件,配置后的参考; 创建目录: mkdir -p /etc/redis-cluster mkdir -p /var/log/redis mkdir -p /var/redis/7001 mkdir -p /var/redis/7002 拷贝配置文件: cp /usr/local/redis-3.2.8/redis....
  • 主要给大家介绍了关于php成功操作redis cluster集群的实例教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Redis Cluster 某个分片(10.20.2.53:7101)内存飙升,明显比其它高跟多,而且持续增长并达到了峰值。并且主从的内存使用量不一致。 IP 监听端口 主/从 实例状态 内存使用 对象数 连接数 命中率 10.20.0.40 ...
  • Redis Cluster数据分片机制 Redis 集群简介 Redis ClusterRedis 的分布式解决方案,在 3.0 版本正式推出,有效地解决了 Redis 分布式方面的需求。 Redis Cluster 一般由多个节点组成,节点数量至少为 6 个才能...
  • 主要介绍了如何用docker部署redis cluster的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • RedisCluster集群(Spring访问Redis),初学者实例源码
  • redisCluster集群demo

    2018-04-10 16:36:05
    redisCluster集群demo,java语言用于获取Redis集群的数据连接池并获取数据。
  • RedisCluster本身提供了自动将数据分散到RedisCluster不同节点的能力,分区实现的关键点问题包括:如何将数据自动地打散到不同的节点,使得不同节点的存储数据相对均匀;如何保证客户端能够访问到正确的节点和数据;...
  • RedisCluster

    2018-10-17 20:43:49
    参照网上资源,自己尝试搭建的 Windows 下 Redis集群搭建Demo.
  • docker 运行redis-trib 带密码创建redis cluster集群配置,没有密码的请自己去下载一个redis-trib.rb替换
  • 基于Redis Cluster;PowerPoint 演示文稿;PowerPoint 演示文稿;架构演进;PowerPoint 演示文稿;灾备与多活的价值;PowerPoint 演示文稿;灾备与双活演进;被动持久化-RDB;响应时间波动的原因;主动持久化-RDB;跨机房灾备;...
  • redis-cluster-operator 概述 Redis Cluster Operator在Kubernetes上管理 。 操作员本身是用。 每个主节点及其从节点都由statefulSet管理,为每个statefulSet创建一个无头svc,并为所有节点创建clusterIP服务。 ...
  • 带监控设置的RedisCluster 使用:首先运行TF以提供基础架构,然后可以配置REDIS集群 cd terraform /资源/ aws / us-west-2 / prod / 地形初始化 地形图 terraform适用 重点说明 角色扮演: 集群设置 关于Redis设置...
  • 一、redis cluster 介绍 自动将数据进行分片,每个 master 上放一部分数据 提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的 redis cluster架构下的每个redis都要开放两个端口号,比如一个是6379...
  • 一个比较全的redis cluster的部署文档,介绍在linux环境中下载、安装redis,配置各个节点,并最终形成集群,本人已用该文档在多套环境中进行部署,真实可用
  • 主要介绍了spring集成redis cluster详解,分享了maven依赖,Spring配置,增加connect-redis.properties 配置文件等相关内容,具有一定参考价值,需要的朋友可以了解下。
  • 详细描述了搭建Redis集群的的步骤及注意事项,并给出详细的命令。
  • 目录介绍测试redis cluster测试多master写入 -> 支撑海量数据的分布式存储测试不同master各自的slave读取 -> 读写分离测试主备自动故障切换 -> 高可用性思想redis cluster去掉主从架构,读写分离扩展思想–如何学习...
  • 主要介绍了Windows环境下Redis Cluster环境搭建(图文),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • rediscluster.rar

    2019-05-31 10:47:42
    集群版redis,使用MySQL数据库,里面有批处理的SQL,性能十分卓越,单机版经供参考,抛转引玉,doc中包含数据库文件
  • redis cluster 是很流行的缓存机制,本人配合博客上传部分配置,给大家参考学习。有需要可以看我的博客,配置只是辅助。有错误还请 指教
  • redis cluster 总体架构: 1、在这个图中,每一个redis服务器节点,它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点,对其进行存取和其他操作。 2、集群...

    redis cluster 总体架构:

    在这里插入图片描述

    1、在这个图中,每一个redis服务器节点,它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,可以访问集群中的任何一个节点,对其进行存取和其他操作。

    2、集群节点属性

    集群中每个Master node负责存储数据、集群状态,包括slots与nodes对应关系。Master nodes能够自动发现其他nodes,检测failure节点,当某个Master节点失效时,集群能将核实的Slave提升为Master。下图是节点的关联信息,节点定时会将这些信息发送给其他节点:
    在这里插入图片描述

    从左至右分别是:

    节点ID、IP地址和端口、节点角色标志、最后发送ping时间、最后接收到pong时间、连接状态、节点负责处理的hash slot。

    3、各节点通过Gossip进行通讯

    cluster 服务端节点直接使用 gossip 协议进行节点间通信,可以自动识别出ip/port的变化,并通过Gossip(最终一致性,分布式服务数据同步算法)协议广播给其他节点知道。Gossip也称“病毒感染算法”、“谣言传播算法”。
    

    (1)主要使用 cluster meet ,ping ,pong 三个命令来完成。

    (2)通信由 meet 或 ping 命令发起。

    (3)meet 命令主要用于节点间的初次通信(?待确认)。

    (4)节点间的握手,类似于 tcp 的三次握手,都会确保对方知道自己已经收到消息。

    (5)定时任务 clusterCron 会向随机节点发其 ping 通信(标记下线,疑似下线,即获知其他节点的存活情况)。

    (6)在定时心跳通信时,会附带上随机两个节点的信息,包括 ip,端口,以及节点所包含的槽位信息

    (7)收到心跳信息的节点,会判断附加的节点信息是否在本地记录中,

    本地无记录,会发其 meet 通信(握手);
    本地有记录,会进行更新(判断 epoch)。
    

    (8)数据结构

    使用 bitmap 来表示一个节点持有的槽位信息;
    集群消息处理函数 clusterProcessPacket。
    

    4、 Redis 集群的数据分片

    Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.

    Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

    • 节点 A 包含 0 到 5500号哈希槽.
    • 节点 B 包含5501 到 11000 号哈希槽.
    • 节点 C 包含11001 到 16384号哈希槽.
    这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
    

    下面对redis cluster原理进行深入讲解。

    展开全文
  • Redis cluster最佳实践

    2018-07-29 20:32:52
    我在做redis cluster的时候发现,两节点的cluster在处理断网或单节点故障时,会出现脑裂情况,为此,我做了实验去测试redis cluster配置的最佳方式,本文包含了测试的全过程。
  • SpringBoot 集成Redis Cluster方案

    千次阅读 2020-03-12 09:58:18
    1. RedisCluster集群结构 Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。 2.RedisCluster集群特点 ① 所有的redis节点彼此互联(PING-PONG机制),内部使用二...

    1. RedisCluster集群结构

     

    Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

    2. RedisCluster集群特点

    所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽

    ② 每个主节点都有一个从节点,当主节点故障,Cluster会按照规则实现主备的高可用性;

    ③ 可以相对平滑扩/缩容节点;

    ④ Redis Cluster采用虚拟槽分区,所有的key根据哈希函数映射到0~16383槽内,key是数据分区的最小粒度,因为不能讲一个大的键值对象,如hash,list等映射到不同的节点上;

    从RedisCluster结构及其主要特点分析,当共享平台用户量增加时,如果业务访问的key分布在不通的槽分区,不同的节点上,此时即可大大增加Redis的并发访问数,较单节点模式在性能方面会有较大的提升。

    3. maven依赖整改

    使用RedisCluster模式,需要使用2.9.0以上版本才能支持Redis密码认证。由于产品共享平台是典型的Spring项目,所以在spring-data-redis的基础上配置spring实现操作Redis Cluster。

    <--2.9.0 以下版本不支持cluster密码认证-->
    <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
       <version>2.9.0</version>
    </dependency>
     <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>2.0.8.RELEASE</version>
    </dependency>

    4. 项目配置文件配置项整改

    RedisCluster集群至少需要6个节点(3主3从,每个主节点分别拥有一个从节点)

    #redis cluster config
    #RedisCluster集群节点及端口信息
    share.redis.cluster.nodes=127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381,127.0.0.1:6382,127.0.0.1:6383,127.0.0.1:6384
    #Redis密码
    share.redis.password=
    #在群集中执行命令时要遵循的最大重定向数目
    share.redis.cluster.max-redirects=5
    #Redis连接池在给定时间可以分配的最大连接数。使用负值无限制
    share.redis.jedis.pool.max-active=1000
    #以毫秒为单位的连接超时时间
    share.redis.timeout=2000
    #池中“空闲”连接的最大数量。使用负值表示无限数量的空闲连接
    share.redis.jedis.pool.max-idle=8
    #目标为保持在池中的最小空闲连接数。这个设置只有在设置max-idle的情况下才有效果
    share.redis.jedis.pool.min-idle=5
    #连接分配在池被耗尽时抛出异常之前应该阻塞的最长时间量(以毫秒为单位)。使用负值可以无限期地阻止
    share.redis.jedis.pool.max-wait=1000
    #redis cluster只使用db0
    share.redis.index=0

    5. 新增RedisCluster配置项类

    新增RedisCluster配置项类用户收集配置文件中的配置项

    @Component
    public class ShareClusterRedisProperties {
    @Value("${spring.share.redis.timeout}")
        private Integer redisTimeout;
    @Value("${spring.share.redis.jedis.pool.max-active}")
        private Integer poolMaxActive;
        @Value("${spring.share.redis.jedis.pool.max-idle}")
        private Integer poolMaxIdle;
        @Value("${spring.share.redis.jedis.pool.min-idle}")
        private Integer poolMinIdle;
        @Value("${spring.share.redis.jedis.pool.max-wait}")
        private Integer poolMaxWait;
        @Value("${spring.share.redis.cluster.nodes}")
        private List<String> clusterNodes;
        @Value("${spring.share.redis.cluster.max-redirects}")
        private Integer clusterMaxRedirects;
        @Value("${spring.share.redis.password}")
        private String password;
        -- getter/setter方法省略 --
    }

    6. 新增RedisCluster集群配置类

    @Configuration
    public class ShareJedisClusterConfig {
    	@Autowired
    	ShareClusterRedisProperties redisProperties;
    /**
         * 注意:
         * 这里返回的JedisCluster是单例的,并且可以直接注入到其他类中去使用
         * @return
         */
        @Bean("shareJedisCluster")
        public JedisCluster getJedisCluster() {
            Set<HostAndPort> nodes = new HashSet<>();
            for (String ipPort : redisProperties.getClusterNodes()) {
                String[] ipPortPair = ipPort.split(":");
                nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.valueOf(ipPortPair[1].trim())));
            }
            //需要密码连接的创建对象方式
            if (StringUtils.isBlank(redisProperties.getPassword())) {
            	return new JedisCluster(nodes,redisProperties.getRedisTimeout(),1000,1,new GenericObjectPoolConfig());
            } else {
            	return new JedisCluster(nodes,redisProperties.getRedisTimeout(),1000,1,redisProperties.getPassword() ,new GenericObjectPoolConfig());
            }
        }
        @Bean
        public RedisConnectionFactory redisConnectionFactory() {
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxTotal(redisProperties.getPoolMaxActive());
            poolConfig.setMaxIdle(redisProperties.getPoolMaxIdle());
            poolConfig.setMinIdle(redisProperties.getPoolMinIdle());
            poolConfig.setMaxWaitMillis(redisProperties.getPoolMaxWait());
            JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
                    .usePooling()
                    .poolConfig(poolConfig)
                    .and()
                    .readTimeout(Duration.ofMillis(redisProperties.getRedisTimeout()))
                    .build();
             // cluster模式
            RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
            redisConfig.setMaxRedirects(redisProperties.getClusterMaxRedirects());
            for (String ipPort :redisProperties.getClusterNodes()){
                String[] ipPortArr = ipPort.split(":");
                redisConfig.clusterNode(ipPortArr[0], Integer.parseInt(ipPortArr[1].trim()));
            }
             return new JedisConnectionFactory(redisConfig, clientConfig);
        }
    }

    7. Redis公共类整改

    在操作Redis Cluster集群的时候,只需自动注入JedisCluster即可,用JedisCluster替换现有的Redis公共方法中使用到redis的地方即可。

    但是 JedisCluster 从性能方面等考虑,并没有提供 Jedis 下提供的 keys 方法, keys 方法,主要用于通配符模式匹配返回满足条件 的 key。keys 方法 还是比较有用的,所以这里需要在Jedis的基础上进行扩展

    public int keys(final String pattern) {
        	try {
    			final Set<String> keySet = new HashSet();
    			final Map<String, JedisPool> nodes = jedisCluster.getClusterNodes();
    			for (String k : nodes.keySet()) {
    				JedisPool pool = nodes.get(k);  
    			    //获取Jedis对象,Jedis对象支持keys模糊查询
    			    Jedis jedis = pool.getResource();  
    			    final Set<String> set = jedis.keys(pattern);
    			    keySet.addAll(set);
    			}
    			
    			return keySet.size();
    		} catch (Exception e) {
    			logger.error("异常信息", e);
                throw e;
    		}
        }
        /**
         * 模糊查询给定的pattern的所有keys列表
         *
         * @param pattern 模糊查询
         * @return 返回当前pattern可匹配的对象keys列表
         */
        public Set<String> keyList(final String pattern) {
    
        	try {
    			final Set<String> keySet = new HashSet<String>();
    			final Map<String, JedisPool> nodes = jedisCluster.getClusterNodes();
    			for (String k : nodes.keySet()) {
    				JedisPool pool = nodes.get(k);  
    			    //获取Jedis对象,Jedis对象支持keys模糊查询
    			    Jedis jedis = pool.getResource();  
    			    final Set<String> set = jedis.keys(pattern);
    			    keySet.addAll(set);
    			}
    			return keySet;
    		} catch (Exception e) {
    			logger.error("异常信息", e);
                throw e;
    		}
        }

     

    展开全文
  • Redis Cluster流程原理

    千次阅读 2018-08-11 19:54:54
    拓扑结构 配置的一致性 1、配置信息数据结构 2、信息交互 3、一致性的达成 sharding 1、数据分片(slot) 2、客户端的路由 ...1、Redis Cluster的读写分离 2、master单点保护 Redis 3.0之...

    Redis 3.0之后,节点之间通过去中心化的方式,提供了完整的shardingreplication(复制机制仍使用原有机制,并且具备感知主备的能力)、failover解决方案,称为Redis Cluster。即:将proxy/sentinel的工作融合到了普通Redis节点里。后面将介绍Redis Cluster这种模式下,水平拆分、故障转移等需求的实现方式。

    拓扑结构

    一个Redis Cluster由多个Redis节点组成。不同的节点组服务的数据无交集,每个节点对应数据sharding的一个分片。节点组内部分为主备2类,对应前面叙述的master和slave。两者数据准实时一致,通过异步化的主备复制机制保证。一个节点组有且仅有一个master,同时有0到多个slave。只有master对外提供写服务,读服务可由master/slave提供。如下所示:

    这里写图片描述

    上图中,key-value全集被分成了5份,5个slot(实际上Redis Cluster有 16384 [0-16383] 个slot,每个节点服务一段区间的slot,这里面仅仅举例)。A和B为master节点,对外提供写服务。分别负责1/2/3和4/5的slot。A/A1和B/B1/B2之间通过主备复制的方式同步数据。

    上述的5个节点,两两通过Redis Cluster Bus交互,相互交换如下的信息:

    • 数据分片(slot)和节点的对应关系;
    • 集群中每个节点可用状态;
    • 集群结构发生变更时,通过一定的协议对配置信息达成一致。数据分片的迁移、主备切换、单点master的发现和其发生主备关系变更等,都会导致集群结构变化。
    • publish/subscribe(发布订阅)功能,在Cluster版内部实现所需要交互的信息。

    Redis Cluster Bus通过单独的端口进行连接,由于Bus是节点间的内部通信机制,交互的是字节序列化信息。相对Client的字符序列化来说,效率较高。

    Redis Cluster是一个去中心化的分布式实现方案,客户端和集群中任一节点连接,然后通过后面的交互流程,逐渐的得到全局的数据分片映射关系。

    配置的一致性

    对于去中心化的实现,集群的拓扑结构并不保存在单独的配置节点上,后者的引入同样会带来新的一致性问题。那么孤立的节点间,如何对集群的拓扑达成一致,是Redis Cluster配置机制要解决的问题。Redis Cluster通过引入2个自增的Epoch变量,来使得集群配置在各个节点间最终达成一致。

    1、配置信息数据结构

    Redis Cluster中的每个节点都保存了集群的配置信息,并且存储在clusterState中,结构如下:

    这里写图片描述

    上图的各个变量语义如下:

    • clusterState 记录了从集群中某个节点视角,来看集群配置状态;
    • currentEpoch 表示整个集群中最大的版本号,集群信息每变更一次,改版本号都会自增。
    • nodes 是一个列表,包含了本节点所感知的,集群所有节点的信息(clusterNode),也包含自身的信息。
    • clusterNode 记录了每个节点的信息,其中包含了节点本身的版本 Epoch;自身的信息描述:节点对应的数据分片范围(slot)、为master时的slave列表、为slave时的master等。

    每个节点包含一个全局唯一的NodeId

    当集群的数据分片信息发生变更(数据在节点间迁移时),Redis Cluster 仍然保持对外服务。

    当集群中某个master出现宕机时,Redis Cluster 会自动发现,并触发故障转移的操作。会将master的某个slave晋升为新的 master。

    由此可见,每个节点都保存着Node视角的集群结构。它描述了数据的分片方式,节点主备关系,并通过Epoch 作为版本号实现集群结构信息的一致性,同时也控制着数据迁移和故障转移的过程。

    2、信息交互

    去中心化的架构不存在统一的配置中心。在Redis Cluster中,这个配置信息交互通过Redis Cluster Bus来完成(独立端口)。Redis Cluster Bus 上交互的信息结构如下:

    这里写图片描述

    clusterMsg 中的type指明了消息的类型,配置信息的一致性主要依靠PING/PONG。每个节点向其他节点频繁的周期性的发送PING/PONG消息。对于消息体中的Gossip部分,包含了sender/receiver 所感知的其他节点信息,接受者根据这些Gossip 跟新对集群的认识。

    对于大规模的集群,如果每次PING/PONG 都携带着所有节点的信息,则网络开销会很大。此时Redis Cluster 在每次PING/PONG,只包含了随机的一部分节点信息。由于交互比较频繁,短时间的几次交互之后,集群的状态也会达成一致。

    3、一致性的达成

    当Cluster 结构不发生变化时,各个节点通过gossip 协议在几轮交互之后,便可以得知Cluster的结构信息,达到一致性的状态。但是当集群结构发生变化时(故障转移/分片迁移等),优先得知变更的节点通过Epoch变量,将自己的最新信息扩散到Cluster,并最终达到一致。

    • clusterNode 的Epoch描述的单个节点的信息版本;
    • clusterState 的currentEpoch 描述的是集群信息的版本,它可以辅助Epoch 的自增生成。因为currentEpoch 是维护在每个节点上的,在集群结构发生变更时,Cluster 在一定的时间窗口控制更新规则,来保证每个节点的currentEpoch都是最新的。

    更新规则如下:

    1. 当某个节点率先知道了变更时,将自身的currentEpoch 自增,并使之成为集群中的最大值。再用自增后的currentEpoch 作为新的Epoch 版本;
    2. 当某个节点收到了比自己大的currentEpoch时,更新自己的currentEpoch;
    3. 当收到的Redis Cluster Bus 消息中的某个节点的Epoch > 自身的时,将更新自身的内容;
    4. 当Redis Cluster Bus 消息中,包含了自己没有的节点时,将其加入到自身的配置中。

    上述的规则保证了信息的更新都是单向的,最终朝着Epoch更大的信息收敛。同时Epoch也随着currentEpoch的增加而增加,最终将各节点信息趋于稳定。

    sharding

    不同节点分组服务于相互无交集的分片(sharding),Redis Cluster 不存在单独的proxy或配置服务器,所以需要将客户端路由到目标的分片。

    1、数据分片(slot)

    Redis Cluster 将所有的数据划分为16384 [0-16383] 个分片,每个分片负责其中一部分。每一条数据(key-value)根据key值通过数据分布算法(一致性哈希)映射到16384 个slot中的一个。数据分布算法为:

    slotId = crc16(key) % 16384

    客户端根据slotId 决定将请求路由到哪个Redis 节点。Cluster 不支持跨节点的单命令,如:sinterstore,如果涉及的2个key对应的slot 在不同的Node,则执行失败。通常Redis的key都是带有业务意义的,如:Product:Trade:20180890310921230001Product:Detail:20180890310921230001。当在集群中存储时,上述同一商品的交易和详情可能会存储在不同的节点上,进而对于这2个key 不能以原子的方式操作。为此,Redis引入了HashTag的概念,使得数据分布算法可以根据key 的某一部分进行计算,让相关的2 条记录落到同一个数据分片。如:

    • 商品交易记录key:Product:Trade:{20180890310921230001}
    • 商品详情记录key:Product:Detail:{20180890310921230001}

    Redis 会根据 {} 之间的字符串作为数据分布式算法的输入。

    2、客户端的路由

    Redis Cluster的客户端相比单机Redis 需要具备路由语义的识别能力,且具备一定的路由缓存能力。当Client 访问的key 不在当前Redis 节点的slots中,Redis 会返回给Client 一个moved命令。并告知其正确的路由信息,如下所示:

    这里写图片描述

    当Client 接收到moved 后,再次请求新的Redis时,此时Cluster 的结构又可能发生了变化。此时有可能再次返回moved 。Client 会根据moved响应,更新其内部的路由缓存信息,以便后续的操作直接找到正确的节点,减少交互次数。

    当Cluster 在数据重新分布过程中时,可以通过ask 命令控制客户端的路由,如下所示:

    这里写图片描述

    上图中,slot 1 需要迁移到新节点上,此时如果客户端已经完成迁移的key,节点将相应ask 告知客户端想目标节点重试。

    ask命令和moved 命令的不同在于,moved 会更新Client数据路由,ask 只是重定向新节点,但是后续的相同slot 仍会路由到旧节点。

    迁移的过程可能会持续一段时间,这段时间某个slot 的数据,同时可能存在于新旧 2 个节点。由于move 操作会使Client 的路由缓存变更,如果新旧节点对于迁移中的slot 所有key 都回应moved,客户端的路由缓存会频繁变更。因此引入ask 类型消息,将重定向和路由缓存分离

    3、分片的迁移

    在一个稳定的Redis Cluster 中,每个slot 对应的节点都是确定的。在某些情况下,节点和分片需要变更:

    • 新的节点作为master加入;
    • 某个节点分组需要下线;
    • 负载不均衡需要调整slot 分布。

    此时需要进行分片的迁移,迁移的触发和过程控制由外部系统完成。Redis Cluster 只提供迁移过程中需要的原语,包含下面 2 种:

    • 节点迁移状态设置:迁移前标记源/目标节点。
    • key迁移的原子化命令:迁移的具体步骤。

    下面的Demo会介绍slot 1 从节点A 迁移到B的过程。

    这里写图片描述

    1. 向节点B发送状态变更命令,将B的对应slot 状态置为importing
    2. 向节点A发送状态变更命令,将A对应的slot 状态置为migrating
    3. 针对A上的slot 的所有key,分别向A 发送migrate 命令,告知A 将对应的key 迁移到B。

    当A节点的状态置为migrating 后,表示对应的slot 正在从A迁出,为保证该slot 数据的一致性。A此时提供的写服务和通常状态下有所区别,对于某个迁移中的slot:

    • 如果Client 访问的key 尚未迁出,则正常的处理该key;
    • 如果key已经迁出或者key不存在,则回复Client ASK 信息让其跳转到B处理;

    当节点B 状态变成importing 后,表示对应的slot 正在向B迁入。即使B 能对外提供该slot 的读写服务,但是和通常情况下有所区别:

    • 当Client的访问不是从ask 跳转的,说明Client 还不知道迁移。有可能操作了尚未迁移完成的,处在A上面的key,如果这个key 在A上被修改了,则后续会产生冲突。
    • 所以对于该slot 上所有非ask 跳转的操作,B不会进行操作,而是通过moved 让Client 跳转至A执行。

    这样的状态控制,保证了同一个key 在迁移之前总是在源节点执行。迁移后总是在目标节点执行,从而杜绝了双写的冲突。迁移过程中,新增加的key 会在目标节点执行,源节点不会新增key。使得迁移有界限,可以在某个确定的时刻结束。

    单个key 的迁移过程可以通过原子化的migrate 命令完成。对于A/B的slave 节点,是通过主备复制,从而达到增删数据。

    当所有key 迁移完成后,Client 通过 cluster setslot 命令设置B的分片信息,从而包含了迁入的slot。设置过程中会让Epoch自增,并且是Cluster 中的最新值。然后通过相互感知,传播到Cluster 中的其他节点。

    failover

    同Sentinel 一样,Redis Cluster 也具备一套完整的故障发现、故障状态一致性保证、主备切换机制。

    1、failover的状态变迁

    1. 故障发现:当某个master 宕机时,宕机时间如何被集群其他节点感知。
    2. 故障确认:多个节点就某个master 是否宕机如何达成一致。
    3. slave选举:集群确认了某个master 宕机后,如何将它的slave 升级成新的master;如果有多个slave,如何选择升级。
    4. 集群结构变更:成功选举成为master后,如何让整个集群知道,以更新Cluster 结构信息。

    2、故障发现

    Redis Cluster 节点间通过Redis Cluster Bus 两两周期性的PING/PONG 交互。当某个节点宕机时,其他Node 发出的PING消息没有收到响应,并且超过一定时间(NODE_TIMEOUT)未收到,则认为该节点故障,将其置为PFAIL状态(Possible Fail)。后续通过Gossip 发出的PING/PONG消息中,这个节点的PFAIL 状态会传播到集群的其他节点。

    Redis Cluster 的节点两两通过TCP 保持Redis Cluster Bus连接,当对PING 无反馈时,可能是节点故障,也可能是TCP 链接断开。如果是TCP 断开导致的误报,虽然误报消息会因为其他节点的正常连接被忽略,但是也可以通过一定的方式减少误报。Redis Cluster 通过 预重试机制 排除此类误报:当 NODE_TIMEOUT/2 过去了,但是还未收到响应,则重新连接重发PING 消息,如果对端正常,则在很短的时间内就会有响应。

    3、故障确认

    对于网络分隔的情况,某个节点(B)并没有故障,但是和A 无法连接,但是和C/D 等其他节点可以正常联通。此时只会有A 将 B 标记为PFAIL 状态,其他节点认为B 正常。此时A 和C/D 等其他节点信息不一致,Redis Cluster 通过故障 确认协议 达成一致。

    集群中每个节点都是Gossip的接收者,A 也会接收到来自其他节点的Gossip 消息,被告知B 是否处于PFAIL 状态。当A收到来气其他master 节点对于 B 的PFAIL 达到一定数量后,会将B的PFAIL 状态升级为 FAIL 状态。表示B 已经确认为故障态,后面会发起slave 选举流程。

    A节点内部的集群信息中,对于B的状态从PFAIL 到 FAIL 的变迁,如下图所示:

    这里写图片描述

    4、slave选举

    上图中,B是A的master,并且B 已经被集群公认是FAIL 状态了,那么A 发起竞选,期望成为新的master。

    如果B 有多个slave (A/E/F)都认知到B 处于FAIL 状态了,A/E/F 可能会同时发起竞选。当B的slave 个数 >= 3 时,很有可能产生多轮竞选失败。为了减少冲突的出现,优先级高的slave 更有可能发起竞选,从而提升成功的可能性。这里的优先级是slave的数据最新的程度,数据越新的(最完整的)优先级越高。

    slave 通过向其他master发送FAILVOER_AUTH_REQUEST 消息发起竞选,master 收到后回复FAILOVER_AUTH_ACK 消息告知是否同意。slave 发送FAILOVER_AUTH_REQUEST 前会将currentEpoch 自增,并将最新的Epoch 带入到FAILOVER_AUTH_REQUEST 消息中,如果自己未投过票,则回复同意,否则回复拒绝。

    5、结构变更通知

    当slave 收到过半的master 同意时,会替代B 成为新的master。此时会以最新的Epoch 通过PONG 消息广播自己成为master,让Cluster 的其他节点尽快的更新拓扑结构。

    当B 恢复可用之后,它手续爱你仍然认为自己是master,但逐渐的通过Gossip 协议得知A 已经替代了自己,然后降级为A的slave。

    可用性和性能

    Redis Cluster 还提供了一些方法可以提升性能和可用性。

    1、Redis Cluster的读写分离

    对于读写分离的场景,应用对于某些读请求允许舍弃一定的数据一致性,以换取更高的吞吐量。此时希望将读请求交给slave处理,以分担master的压力。

    通过分片映射关系,某个slot 一定对应着一个master节点。Client 通过moved 命令,也只会路由到各个master中。即使Client 将请求直接发送到slave上,也会回复moved 到master去处理。

    为此,Redis Cluster 引入了readonly 命令。Client 向slave发送该命令后,不再moved 到master处理,而是自己处理,这成为slave的readonly 模式。通过readwrite命令,可以将slave的readonly模式重置。

    2、master单点保护

    假如Cluster 的初始状态如下所示:

    这里写图片描述

    上图中A、B两个master 分别有自己的slave,假设A1 发生宕机,结构变为如下所示:

    这里写图片描述

    此时A 成为了单点,一旦A 再次宕机,将造成不可用。此时Redis Cluster 会把B 的某个slave (如 B1 )进行副本迁移,变成A的slave。如下所示:

    这里写图片描述

    这样集群中每个master 至少有一个slave,使得Cluster 具有高可用。集群中只需要保持 2*master+1 个节点,就可以保持任一节点宕机时,故障转移后继续高可用。


    参考:《深入分布式缓存》
    链接:http://moguhu.com/article/detail?articleId=108

    展开全文
  • docker安装redis cluster集群

    千次阅读 2020-10-09 12:24:38
    目录docker安装redis cluster集群环境搭建编写redis配置文件创建redis容器创建 Redis Cluster集群SpringBoot配置Redis集群**在pom.xml中引入相关依赖****配置application.yml**Redis 配置基本测试 环境 #查看...

    docker安装redis cluster集群

    环境

    #查看服务器版本信息
    cat /etc/centos-release
    #查看docker版本
    docker -v

    在这里插入图片描述

    搭建

    编写redis配置文件

    #创建目录
    mkdir -p /usr/local/docker-redis/redis-cluster
    #切换至指定目录
    cd /usr/local/docker-redis/redis-cluster/
    #编写 redis-cluster.tmpl 文件
    vi redis-cluster.tmpl

    port ${PORT}
    requirepass 1234
    masterauth 1234
    protected-mode no
    daemonize no
    appendonly yes
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    cluster-announce-ip 39.98.xx.xx
    cluster-announce-port ${PORT}
    cluster-announce-bus-port 1${PORT}
    
    • port:节点端口;
    • requirepass:添加访问认证;
    • masterauth:如果主节点开启了访问认证,从节点访问主节点需要认证;
    • protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
    • daemonize:是否以守护线程的方式启动(后台启动),默认 no;
    • appendonly:是否开启 AOF 持久化模式,默认 no;
    • cluster-enabled:是否开启集群模式,默认 no;
    • cluster-config-file:集群节点信息文件;
    • cluster-node-timeout:集群节点连接超时时间;
    • cluster-announce-ip:集群节点 IP,填写宿主机的 IP;
    • cluster-announce-port:集群节点映射端口;
    • cluster-announce-bus-port:集群节点总线端口。

    每个 Redis 集群节点都需要打开两个 TCP 连接。一个用于为客户端提供服务的正常 Redis TCP 端口,例如 6379。还有一个基于 6379 端口加 10000 的端口,比如 16379。
    第二个端口用于集群总线,这是一个使用二进制协议的节点到节点通信通道。节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端永远不要尝试与集群总线端口通信,与正常的 Redis 命令端口通信即可,但是请确保防火墙中的这两个端口都已经打开,否则 Redis 集群节点将无法通信

    在redis-cluster目录下面执行下面命令,创建7000-7005相关目录和文件

    for port in `seq 7000 7005`; do \
      mkdir -p ${port}/conf \
      && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
      && mkdir -p ${port}/data;\
    done
    
    

    #执行tree命令,查看结果
    tree /usr/local/docker-redis/redis-cluster

    在这里插入图片描述

    #查看节点配置文件
    cat /usr/local/docker-redis/redis-cluster/700{0…5}/conf/redis.conf

    在这里插入图片描述

    创建redis容器

    将宿主机的7000~7005端口与6geredis容器映射,并将宿主机的目录与容器内的目录进行映射(挂载)。使用host网络模式

    for port in $(seq 7000 7005); do \
      docker run -di --restart always --name redis-${port} --net host \
      -v /usr/local/docker-redis/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
      -v /usr/local/docker-redis/redis-cluster/${port}/data:/data \
      redis redis-server /usr/local/etc/redis/redis.conf; \
    done
    
    

    备注:命令译为 循环7010 - 7015 运行redis 容器
    docker run 运行
    -di 守护进程
    –restart always 保持容器启动
    –name edis- p o r t 容 器 名 称 − − n e t h o s t 使 用 h o s t 网 卡 − v / u s r / l o c a l / d o c k e r − r e d i s / r e d i s − c l u s t e r / {port} 容器名称 --net host 使用host网卡 -v /usr/local/docker-redis/redis-cluster/ portnethost使hostv/usr/local/dockerredis/rediscluster/{port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
    将宿主机700节点文件挂载到容器/usr/local/etc/redis/redis.conf文件中
    -v /usr/local/docker-redis/redis-cluster/${port}/data:/data
    将宿主机700
    /data目录挂载到容器/data目录中
    redis redis-server /usr/local/etc/redis/redis.conf;
    根据挂载配置启动redis服务端

    在这里插入图片描述

    #使用命令查看是否成功
    docker ps -a

    在这里插入图片描述


    创建 Redis Cluster集群

    #进入容器
    docker exec -it redis-7000 bash
    #进入到指定目录下面
    cd /usr/local/bin/
    #使用redis-cli命令创建集群(需要redis5.0版本以上)
    redis-cli -a xx(密码)–cluster create 39.98.xx.xx:7000 39.98.xx.xx:7001 39.98.xx.xx:7002 39.98.xx.xx:7003 39.98.xx.xx:7004 39.98.xx.xx:7005 --cluster-replicas 1

    出现提示,输入yes

    在这里插入图片描述


    查看集群状态

    #进入容器
    docker exec -it redis-7003 bash
    #切换至指定目录
    cd /usr/local/bin/
    #查看集群状态
    redis-cli -a xx(密码) --cluster check 39.98.xx.xx:7002

    查看集群信息

    #连接至集群某个节点
    redis-cli -c -a xx(密码) -h 39.98.xx. xx -p 7001
    #查看集群信息
    cluster info
    #查看集群结点信息
    cluster nodes
    在这里插入图片描述

    SpringBoot配置Redis集群

    在SpringBoot2.x版本中,redis默认的连接池已经更换为Lettuce,而不再是jedis

    在pom.xml中引入相关依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    

    配置application.yml

    spring:
      redis:
        timeout: 6000
        password: xxx
        cluster:
          max-redirects: 3 # 获取失败 最大重定向次数 
          nodes:
            - 39.98.xx.xx:7001
            - 39.98.xx.xx:7002
            - 39.98.xx.xx:7003
            - 39.98.xx.xx:7004
            - 39.98.xx.xx:7005
            - 39.98.xx.xx:7000
        lettuce:
          pool:
            max-active: 1000 #连接池最大连接数(使用负值表示没有限制)
            max-idle: 10 # 连接池中的最大空闲连接
            min-idle: 5 # 连接池中的最小空闲连接
            max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
    

    Redis 配置

    @Configuration
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    public class RedisConfig {
        @Bean
        public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }
    

    基本测试

    @SpringBootTest
    public class RedisTest {
    
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        @Test
        public void test() {
            redisTemplate.opsForValue().set("name", "admin");
            String name = redisTemplate.opsForValue().get("name");
            System.out.println(name); //输出admin
        }
    }
    
    展开全文
  • Redis Sentinel 与 Redis Cluster

    万次阅读 多人点赞 2018-07-26 14:06:18
    一、前言 互联网高速发展的今天,对应用系统的抗压能力要求越来越高,传统的应用层+数据库已经不能满足当前的需要。所以一大批内存式数据库和...本文主要介绍Redis Sentinel 及 Redis Cluster的区别及用法,Redi...
  • Kubernetes 部署Redis Cluster

    千次阅读 2020-07-27 15:01:03
    Redis Cluster 最少需要3个Master节点,每个Master节点可以有一个或多个Slave节点。 Kubernetes YAML文件 ConfigMap保存redis.conf配置文件 --- # Redis Config apiVersion: v1 kind: ConfigMap metadata: ...
  • 5.8. 集群常用命令 5.8.1. 集群的重启与删除 1.关闭集群的某个节点 关闭集群的某个节点,比如关闭端口号为7001的实例: redis-cli -a cyclone -c -h 192.168....redis-server /etc/redis/redis-cluster-7001/7001.c...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 92,618
精华内容 37,047
关键字:

rediscluster

redis 订阅
友情链接: ChatServer.rar