快讯资讯
手机优化
系统数码
网络通信人工智能
网站游戏
测评专题
智车

  记一次Redis Cluster Pipeli       测试左移及其在服务器研    

记一次Redis Cluster Pipeline导致的死锁问题

时间:2026-10-03 14:03 来源:未知 人气:

一、背景介绍

Redis Pipeline是一种高效的命令批量处理机制,可以在Redis中大幅度降低网络延迟,提高读写能力。Redis Cluster Pipeline是基于Redis Cluster的pipeline,通过将多个操作打包成一组操作,一次性发送到Redis Cluster中的多个节点,减少了通信延迟,提高了整个系统的读写吞吐量和性能,适用于需要高效处理Redis Cluster命令的场景。

本次使用到pipeline的场景是批量从Redis Cluster批量查询预约游戏信息,项目内使用的Redis Cluster Pipeline的流程如下,其中的JedisClusterPipeline是我们内部使用的工具类,提供Redis Cluster模式下的pipeline能力:

JedisClusterPipeline使用

JedisClusterPipline jedisClusterPipline = redisService.clusterPipelined(); ListObject response; try { for (String key : keys) { jedisClusterPipline.hmget(key, VALUE1, VALUE2); } // 获取结果 response = jedisClusterPipline.syncAndReturnAll(); } finally { jedisClusterPipline.close(); }

二、故障现场记录

某天,收到了Dubbo线程池耗尽的告警。查看日志发现只有一台机器有问题,并且一直没恢复,已完成任务数也一直没有增加。

查看请求数监控,发现请求数归零,很明显机器已经挂了。

使用arthas查看Dubbo线程,发现400个线程全部处于waiting状态。

三、故障过程分析

Dubbo线程处于waiting状态这一点没有问题,Dubbo线程等待任务的时候也是waiting状态,但是查看完整调用栈发现有问题,下面两张图里的第一张是问题机器的栈,第二张是正常机器的栈,显然问题机器的这个线程在等待Redis连接池里有可用连接。

使用jstack导出线程快照后发现问题机器所有的Dubbo线程都在等待Redis连接池里有可用连接。

调查到这里,能发现两个问题。

  1. 线程一直等待连接而没有被中断。
  2. 线程获取不到连接。

3.1 线程一直等待连接而没有被中断原因分析

Jedis获取连接的逻辑在

org.apache.commons.pool2.impl.GenericObjectPool#borrowObject(long)方法下。

public T borrowObject(long borrowMaxWaitMillis) throws Exception { ... PooledObjectT p = null; // 获取blockWhenExhausted配置项,该配置默认值为true boolean blockWhenExhausted = getBlockWhenExhausted(); boolean create; long waitTime = System.currentTimeMillis(); while (p == null) { create = false; if (blockWhenExhausted) { // 从队列获取空闲的对象,该方法不会阻塞,没有空闲对象会返回null p = idleObjects.pollFirst(); // 没有空闲对象则创建 if (p == null) { p = create(); if (p != null) { create = true; } } if (p == null) { // borrowMaxWaitMillis默认值为-1 if (borrowMaxWaitMillis 0) { // 线程栈快照里所有的dubbo线程都卡在这里,这是个阻塞方法,如果队列里没有新的连接会一直等待下去 p = idleObjects.takeFirst(); } else { // 等待borrowMaxWaitMillis配置的时间还没有拿到连接的话就返回null p = idleObjects.pollFirst(borrowMaxWaitMillis, TimeUnit.MILLISECONDS); } } if (p == null) { throw new NoSuchElementException( "Timeout waiting for idle object"); } if (!p.allocate()) { p = null; } } ... } updateStatsBorrow(p, System.currentTimeMillis() - waitTime); return p.getObject(); }

更多文章

相关文章

网站导航: | 快讯 | 资讯 | 手机 | 优化 | 系统 | 数码 | 网络通信 | 人工智能

  • 游戏 | 测评 | 专题 | 智车

    合作伙伴:

  • 友情链接(欢迎业界知名网站交换链接)申请友情

    

    声明:本站资源皆来自网络,如有侵权问题,请联系管理员处理!

    Copyright ©2020-2028快知站 版权所有 All rights reserved.

    闽ICP备20010713号-1 闽公网安备 35020602001684号