近期Redis集群服务出现不稳定的情况,请求的总体RT波动性很大,出现请求失败的情况。
表现症状
- p99的请求RT耗时问题时段大幅变长
- 个别Redis实例的total_net_output_bytes飚高【100+Mbytes】
- 个别Redis实例的cmdstats_cluster命令执行的次数飙高
- 个别Redis实例CPU使用率飚高
total_net_output_bytes飚高
Cluster命令次数飙高
事故现场
首先要搞明白到底谁在发送cluster指令,tcpflow官方版本抓包数据不带时间戳,这点非常不爽,问题很难被追溯,很庆幸在github上找到一个支持时间戳的tcpflow,https://github.com/mukhin/tcpflow。
抓包数据
2016-10-08 17:08:50 $7
2016-10-08 17:08:50 CLUSTER
2016-10-08 17:08:50 $5
2016-10-08 17:08:50 slots
发送的来源
87 010.192.192.181
78 010.192.192.108
68 010.192.192.121
65 010.192.192.024
64 010.192.192.063
62 010.192.192.089
61 010.192.192.124
60 010.192.192.192
57 010.192.192.164
56 010.192.192.064
52 010.192.192.161
50 010.192.192.127
48 010.192.192.123
46 010.192.192.118
45 010.192.192.065
43 010.192.192.122
42 010.192.192.125
39 010.192.192.120
39 010.192.192.192
36 010.192.192.119
35 010.192.192.126
33 010.192.192.109
17 010.192.192.163
15 010.192.192.162
1 010.192.192.066
发送的频率
204 17:08:53
193 17:08:52
120 17:08:54
98 17:08:50
93 17:08:56
92 17:08:55
82 17:08:59
80 17:08:57
70 17:08:58
根据ip很容易判断出这些命令是Jedis客户端发送,1秒执行了266次,行成了cluster slots风暴,由于频繁执行cluster slots,而且输出的内容体积很大,这就可以解释Redis实例输出内容变多的原因。
分析jedis客户端
目前使用的是jedis比较老的一个版本2.7.0,jedis运行过程中当出现网络波动会导致请求随机节点,然后随机节点会返回Moved指令,这时会导致大量客户端更新slot【JedisClusterConnectionHandler.renewSlotCache()】的请求,由于选择Redis Server时没有做Shuffled会导致所有的cluster slots请求发给同一个Redis Server,Cluster slots会让这个Redis会出现严重的热点问题,进而影响到集群的吞吐以及稳定。
private T runWithRetries(String key, int redirections, boolean tryRandomNode, boolean asking) { if (redirections <= 0) { throw new JedisClusterMaxRedirectionsException("Too many Cluster redirections?"); } Jedis connection = null; try { if (asking) { // TODO: Pipeline asking with the original command to make it // faster.... connection = askConnection.get(); connection.asking(); // if asking success, reset asking flag asking = false; } else { if (tryRandomNode) { connection = connectionHandler.getConnection(); } else { connection = connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(key)); } } return execute(connection); } catch (JedisConnectionException jce) { if (tryRandomNode) { // maybe all connection is down throw jce; } releaseConnection(connection, true); connection = null; // retry with random connection return runWithRetries(key, redirections - 1, true, asking); } catch (JedisRedirectionException jre) { if (jre instanceof JedisAskDataException) { asking = true; askConnection.set(this.connectionHandler.getConnectionFromNode(jre.getTargetNode())); } else if (jre instanceof JedisMovedDataException) { // it rebuilds cluster's slot cache // recommended by Redis cluster specification this.connectionHandler.renewSlotCache(); } else { throw new JedisClusterException(jre); } releaseConnection(connection, false); connection = null; return runWithRetries(key, redirections - 1, false, asking); } finally { releaseConnection(connection, false); } }
public void renewSlotCache() { for (JedisPool jp : cache.getNodes().values()) { Jedis jedis = null; try { jedis = jp.getResource(); cache.discoverClusterSlots(jedis); break; } finally { if (jedis != null) { jedis.close(); } } } }
处理方案
Jedis 2.8.0版本renewSlotCache时增加了Shuffled,使得cluster slots请求尽可能打散至更多Redis Server上。
https://github.com/xetorthio/jedis/pull/1090
相关推荐
客户端通常通过`CLUSTER SLOTS`命令获取槽分配信息。 4. **故障检测与恢复**:每个节点都会监控其他节点的状态,如果发现某节点失效,会触发故障转移过程。一个新的主节点会被选举出来接管失效节点的槽和数据。 **...
**RedisCluster集群与Spring访问Redis详解** Redis是一个高性能的键值数据库,广泛应用于缓存、消息中间件等场景。在大型分布式系统中,为了提供高可用性和数据冗余,我们通常会采用Redis Cluster来构建集群。本文...
在`redisCluster-demo`这个项目中,你可以期待找到一个使用Java实现的示例,展示如何配置和使用`JedisCluster`或者`Lettuce`来连接Redis Cluster,以及如何进行基本的数据操作。这个示例可以帮助初学者理解如何在...
这个压缩包文件"rediscluster配置文件.zip"包含了一系列配置文件,用于搭建一个三主三从的Redis Cluster架构。在这个架构中,每个主节点都有一个对应的从节点,确保在主节点失效时可以从其从节点接管服务,从而保持...
Redis高可用集群Redis Cluster搭建 Redis高可用集群Redis Cluster搭建是 Redis 官方推荐的高可用性解决方案,于 3.0 版本推出。Redis Cluster 的主要用途是实现数据分片(Data Sharding),同时也可以实现高可用...
Redis Cluster通过将数据分割成多个槽(slots)并分布在多个节点之间来实现数据的分布式存储,每个节点负责一部分槽,从而达到水平扩展的目的。 **Spring与Redis的整合** Spring框架提供了一套完善的集成Redis的...
使用JFinal Redis Cluster插件时,首先需要将其引入到项目中,这里我们看到有一个名为 "jfinal-rediscluster-plugin-by-shixiaotian-0.0.1.jar" 的文件,这应该是该插件的可执行版本。通常,开发者会将这个JAR文件...
Redis Cluster是Redis官方提供的分布式集群解决方案,它允许用户在多台服务器上部署Redis实例,形成一个高可用、可扩展的数据存储集群。Redis Cluster通过数据分片(Sharding)和槽分区(Slot Partitioning)策略来...
Redis Cluster是Redis官方提供的分布式解决方案,它通过将数据分片(sharding)到多个节点来实现高可用性和可扩展性。在本实战栗子中,我们将深入探讨如何搭建Redis Cluster,学习其基本概念、操作指令以及如何处理...
### Redis Cluster 的实现机制与原理 #### 集群的核心目标与特性 Redis Cluster 是 Redis 数据库的一个分布式版本,旨在解决单个 Redis 实例在处理大量数据和高并发请求时的局限性。其核心目标包括: 1. **高性能...
实验结果表明,在高并发访问数(例如10000以上)的场景下,RedisCluster的响应时间明显优于Codis系统,验证了RedisCluster分布式缓存系统在处理高并发访问时的高效率和优越性能。 关键词“分布式缓存”指的是分布式...
RedisCluster是Redis的一种分布式集群解决方案,它允许将数据分散存储在多个节点上,以实现高可用性和可扩展性。在RedisCluster中,每个节点都存储一部分数据,并且负责处理一部分客户端请求,这样可以分摊服务器...
【标题】:“Tomcat 8+ Redis Cluster Session” 在现代Web应用开发中,session管理是不可或缺的一部分,尤其是在分布式系统中。传统的session管理方式在多台服务器之间存在数据同步问题,导致用户状态无法共享,...
Codis到Redis Cluster的迁移工具支持将已经在Codis集群中的数据平滑迁移到Redis Cluster,无需停机,保证业务的连续性。同样,它也支持从Redis迁移到Codis,以及在Redis实例之间进行迁移,这些功能使得数据管理更具...
Redis Cluster 集群模式部署 本文将详细介绍 Redis Cluster 集群模式部署的步骤和配置过程。Redis Cluster 是 Redis 的一个高可用解决方案,通过将多个 Redis 节点组合成集群,提高 Redis 的可用性和性能。 环境...
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....
本示例“rediscluster集群demo”旨在展示如何设置和操作一个简单的Redis Cluster实例,确保在本地环境中的正确运行。 首先,Redis Cluster采用无中心架构,每个节点都是对等的,并且负责一部分数据。它通过槽(slot...
**Redis Cluster 搭建全攻略** Redis 是一个高性能的键值存储系统,而 Redis Cluster 是它的分布式解决方案,提供数据的自动分片、故障转移和高可用性。本指南将详细讲解如何完整地搭建一个 Redis Cluster,同时...
1. **自动分片(Sharding)**:Redis Cluster会自动将键空间分成多个槽(Slots),并分配到各个节点,确保数据分散均匀。 2. **容错机制**:如果一个节点宕机,其上的槽和数据可以被其他节点接管,保证服务连续性。 ...