`

danga.memcached2.0.1存在nio管道句柄泄漏问题[转]

    博客分类:
  • java
阅读更多
服务器出现故障,分析日志:
最先开始的是danga.memcached报"too many open files",句柄数达到上限(ulimit上限已经是加大的),
导致danga.memcached无法创建新的套接字,连接缓存服务器失败,
紧接着压力全部转移到数据库,数据库连接池用完,很快就撑不住,
因为数据库响应慢,线程占用率变高,接收请求的线程池也达到上限,很多请求被拒绝,
页面出现时而可以访问,时而访问不了,重启后恢复正常,
lsof查看Java进程持有的句柄,大部分为pipe和event poll,
初步判断是danga.memcached中使用的nio管道未正确关闭。
为了进一步了解问题,分析源码:
首先来看danga是怎么获取套接字的:
SocketIO.getSocket()
Java代码 复制代码

 

SocketChannel sock = SocketChannel.open();
sock.socket().connect( new InetSocketAddress( host, port ), timeout );
return sock.socket(); // 直接拿到Socket使用,把SocketChannel的引用丢了,并且没有注册Selector

再来看应用调用API发生了什么:
MemCachedClient.get()
Java代码 复制代码

 

// 省略了不相关代码
sock.write( cmd.getBytes() );
String line = sock.readLine();

内部调用关系等价于:
Java代码 复制代码

 

// sock.write( cmd.getBytes() ); 等价于
out = new BufferedOutputStream( sock.getOutputStream() );
out.write( b );
// String line = sock.readLine(); 等价于
in  = new DataInputStream( sock.getInputStream() );
in.read( b );

再看看它是怎么关闭的:
SockIO.trueClose()
Java代码 复制代码

 

// 省略了错误检查代码
in.close();
out.close();
sock.close(); // Soket内部会同时关闭Channel,但不会关闭Selector

这种把非阻塞式管道当作阻塞式套接字用法,我们来看看SunJDK是怎么处理的:
SocketChannelImpl.socket().connect()最终调用的是:
SocketAdaptor.connect()
Java代码 复制代码

 

// 省略了部分代码
sel = Util.getTemporarySelector(sc);
sk = sc.register(sel, SelectionKey.OP_CONNECT);

再看看Util.getTemporarySelector()怎么实现的:
Java代码 复制代码

 

// 省略了部分代码
private static ThreadLocal localSelector = new ThreadLocal();
SoftReference ref = (SoftReference)localSelector.get();
sel = sc.provider().openSelector();
localSelector.set(new SoftReference(new SelectorWrapper(sel)));
return sel;

通过上面的代码,基本结论是:
danga.memcached2.0.1使用nio非阻塞式管道,
但却把非阻塞式管道当作阻塞式套接字用,没有注册Selector,
JDK会注册一个临时的Selector,使用Soft引用,并使用ThreadLocal做缓存,
当线程池剧烈收缩和扩张时,就会出现很多垃圾Soft引用的Selector,
如果内存够用,这些Soft引用都不会释放,句柄数就有可能达到上限。
而danga.memcached1.6.0使用的是常规阻塞式套接字,性能稍慢,但资源管理都比较正确,
降级使用1.6.0版本后,服务器恢复正常,
但1.6.0版本存在memcached服务器重启后,客户端无法自动恢复连接的问题,需将连接超时设置足够短(50ms以内)。
另外,将接收请求的线程池最大值和最小值设为一样,固定大小,避免收缩。
      能力不够,别人找到了这个帖子,而自己找不到,不过当时已经怀疑是mmcached的问题的了,呵呵。
分享到:
评论

相关推荐

    danga memcached使用

    **标题:“danga memcached使用”** memcached是一款高性能、分布式内存对象缓存系统,它广泛应用于Web应用中,用于减轻数据库的负载,通过在内存中缓存数据和对象来减少读取数据库的次数。Danga是memcached的原始...

    memcached_net.spy_com.danga JAR

    Memcache java jar 包 java_memcached-release_2.5.1.jar import com.danga.MemCached.MemCachedClient; import net.spy.memcached.MemcachedClient;

    java_memcached-release_2.5.1.jar Memcache java jar 包

    2. **缓存操作**:通过简单的API,开发者可以设置、获取、删除或检查缓存在Memcached中的键值对。这些操作通常都是原子性的,确保了数据的一致性。 3. **序列化与反序列化**:Java Memcached客户端库通常会处理对象...

    memcached在JAVA中调用的DEMO

    memcached在JAVA中调用的DEMO,直接导入项目,无需新建工程。前提是必须按安装memcached,并启动memcached server服务

    memcached-2.4.2.jar memcached-2.4.2.jar

    使用memcached 方法 package com.war.common.util; import com.danga.MemCached.*; import java.util.Date; public class MemCached { protected static MemCachedClient mcc; protected static Logger log; ...

    memcached使用说明.doc

    【Memcached 使用说明】 Memcached 是一套由 danga.com(LiveJournal 技术团队)开发的分布式内存对象缓存系统,旨在减少数据库负载并提升应用性能。它通过将数据存储在内存中,使得高并发环境下的数据访问更为快速...

    java-memcached-2.6.6.jar

    java-memcached-2.6.6.jar

    计算机后端-PHP视频教程. Memcachedmemcached(day1).pdf

    Memcached由Danga Interactive公司开发,最初服务于LiveJournal,现在已经成为一种开源、高性能、分布式的内存对象缓存系统。它的工作原理是将数据存储在内存中,避免了频繁读取硬盘带来的I/O延迟,从而提高了数据...

    java使用memcached的实例

    在IT领域,尤其是在JavaWeb开发中,Memcached作为一种高性能、分布式的内存对象缓存系统,被广泛用于加速动态网络应用的加载速度。本文将详细解析如何在Java项目中使用Memcached,包括其配置方法以及一个具体的示例...

    memcached学习笔记

    此外,由于 Memcached 是无状态的,所以它不负责数据的同步,如果多个服务器共享数据,需要在应用层面处理一致性问题。 总结一下,Memcached 是一个轻量级、高性能的分布式缓存系统,适用于高并发的 Web 应用场景。...

    memcached操作及说明

    ### Memcached操作及说明 #### 一、Memcached概述 Memcached是一款高性能、分布式内存对象缓存系统,旨在减轻数据库的负担,加速动态网站的访问速度。它最初由Danga Interactive为提升LiveJournal.com的访问速度而...

    memcached安装和使用详细说明

    当检测到特定的查询操作时,可以先尝试从Memcached中获取数据,如果不存在则从数据库查询并存入缓存。这种方式可以显著提高查询速度,尤其是在高并发场景下。 **总结** Memcached作为一个高效的分布式缓存系统,...

    memcached.jar

    com.danga package 下的 memcached.jar

    Memcached.pdf Memcached.pdf

    ### Memcached概述与关键技术知识点 #### 一、简介 **Memcached** 是一款高性能的分布式内存缓存系统,主要用于在动态应用中减少数据库负载并提高访问速度。它通过在内存中存储经常使用的数据来实现这一目标,从而...

    Memcached学习笔记

    ### Memcached学习笔记 #### 一、Memcached简介 Memcached是一种高性能的分布式内存对象缓存系统,主要用于在动态应用程序中减少数据库负载,提高访问速度。最初由Danga Interactive为优化LiveJournal.com网站的...

    memcached客户端(三种客户端)

    在Java开发中,有三种主流的Memcached客户端库供开发者选择:官方的基于传统阻塞IO的客户端、Dustin Sallings实现的基于Java NIO的Spymemcached以及XMemcached。 1. **官方客户端** 官方提供的客户端是由Greg ...

    memcached1

    最近一直在做一个项目的前期设计工作,考虑到后期系统的扩展和性能问题也找了很多解决方法,有一个就是用到了数据库的缓存工具memcached(当然该工具并不仅仅局限于数据库的缓存)。先简单的介绍下什么是memcached。...

    memcached-library, 一个与Memcached缓存系统接口的CodeIgniter库.zip

    library, 一个与Memcached缓存系统接口的CodeIgniter库 用于CodeIgniter的#Memcached 库##Description这个库是为了帮助一个基于CodeIgniter的项目与 1或者更多的Memcached服务器( http://www.danga.com/memcached

    memcached代码分析详解.docx

    memcached是由Danga Interactive开发的一个开源项目,旨在提高动态Web应用的性能。它是一个基于内存的键值存储系统,用于临时存储(非持久化)中小规模的数据,如网页内容、数据库查询结果等。memcached通过在服务器...

Global site tag (gtag.js) - Google Analytics