magent+memcache集群--java客户端连续set导致magent占用cpu100%,跪求解释

01Byte空间 2013-08-28 06:11:00

问题描述:
两个memcache,通过magent做成互为主备。客户端通过magent的端口写数据,测试的结果是,有时候成功,有时候整个客户端程序夯住。
准确的说是连接magent夯住了,为什么这么说呢,因为此时去telnet连接magent的端口,连接进去后敲入get查询命令后夯住,没有任何输出。
而此时连接memcached的端口是可以的,而且还可以get。

tcpdump host 192.168.150.116 and port 13000 -i eth0 -vv -s 0 -w sp-memcached13000.cap
通过抓包工具抓到这个包的数据,可以看到客户端在set第二个key的时候,没有收到服务端的相应stored。而此时这个端口对应的magent占用cpu一直是100%。

这是为什么???


配置如下:
[root@db1 ~]# ps -ef|grep mem
root 11846 1 0 16:05 ? 00:00:00 memcached -m 64 -u root -d -l 0.0.0.0 -p 11211 -P /root/memcached_11211.pid
root 11951 1 0 16:05 ? 00:00:00 memcached -m 64 -u root -d -l 0.0.0.0 -p 11212 -P /root/memcached_11212.pid
root 13846 5648 0 16:06 pts/1 00:00:00 grep mem
[root@db1 ~]# ps -ef|grep magent|grep -v oracle
root 12694 1 0 16:05 ? 00:00:00 magent -u root -n 51200 -l 0.0.0.0 -p 12000 -s 127.0.0.1:11211 -b 127.0.0.1:11212
root 13312 1 0 16:05 ? 00:00:00 magent -u root -n 51200 -l 0.0.0.0 -p 13000 -s 127.0.0.1:11212 -b 127.0.0.1:11211
root 14352 5648 0 16:06 pts/1 00:00:00 grep magent
[root@db1 ~]#


...全文
5118 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
01Byte空间 2016-04-20
  • 打赏
  • 举报
回复
memagent - issue #4 有内存泄漏问题 Posted on May 18, 2010 by Quick Rabbit 用了一段时间发现有内存泄漏 ,现象是每一次get都会有20byte的内存泄漏。 查了一下代码,发现了泄漏点 以 r28版为例, 在magent.c文件的 1595行, b = buffer_init_size(len + 3); 分配了一个buffer 但在1733行 ,退出了函数,虽然1732行有conn_close(c); 但因为1595分配的buffer 还没有加入到c->request(这个加入 动作要到1745行完成), 所以1732行的conn_close(c)并没有释放1595行分配的buffer 另外,在使用中发现,因为mamagent没有考虑超过机制,memagent在一台memcached突然死掉的情况下,会造成 memagent长久等待,这样所有的客户端都会卡死,造成整个web前台死掉,这是很难让人接受的,我对代码临时加了 一些超时机制,但无法保证都加对了,我并在附件中了,因为联系不上作者,如果作者有兴趣,请联系我 gnujava[at]gmail.com Attachments magent.c 54.62KB Comment #1 Posted on May 18, 2010 by Quick Rabbit "因为mamagent没有考虑超过机制" 改成 "因为mamagent没有考虑超时机制" Comment #2 Posted on Jul 6, 2010 by Grumpy Monkey 你说的内存泄露问题确实存在,多谢指正 memagent没有考虑超时机制的大概意思我了解,我会看看你提交的代码 Comment #3 Posted on Sep 2, 2011 by Massive Bird 请问现在的版本已经解决了“超时”+“内存泄漏”的问题了吗? Comment #4 Posted on Sep 2, 2011 by Quick Rabbit 内存泄漏在r29版本就已经解决了。 超时问题要大改,所以到目前为止r31没见作者动手 Comment #5 Posted on Nov 24, 2011 by Happy Dog 为何不直接用libmemcached呢?能解决这个工程能解决的问题。 Comment #6 Posted on Jun 5, 2012 by Happy Cat 都好久没有更新了,不知道什么时候修复这个问题呢? Comment #7 Posted on Jun 5, 2012 by Happy Cat 怎么感觉 0.6 版本更不稳定,我现在测试直接 telnet 上 magent 后 set 第二次就死在那了,以后再也无法登陆上。 Comment #8 Posted on Jun 4, 2013 by Quick Monkey 关于 0.6 版本,set key 值第二次失败问题; 这个问题的关键点在于作者写 pool_server_handler 用意; 搭建环境多次启停主数据服务器(memcached)和备份服务器(memcached);该部分源码均未被调用;该事件也未被触发; 同时因为s->sfd对应的事件机制上add了pool_server_handler的read触发条件; 影响了s->sfd接收下次set key 命令; 提供一种解决方法: 注释掉 函数 static void pool_server_handler(const int fd,const short which, void* argv); 注释掉 put_server_into_pool(void s) 中: event_del(&(s->ev)); /注意保留/ / event_set(&(s->ev), s->sfd, EV_READ|EV_PERSIST, pool_server_handler, (void *) s); event_add(&(s->ev), 0); */ 如上方法已经测试过;原因不解释; Comment #9 Posted on Jun 4, 2013 by Quick Monkey 从 pool_server_handler 源码分析可知; pool_server_handler 功能是用来当memcached服务器断链时,清理matrix->pool中对应的server(s->sfd)的; 若不清理,matrix->used对应的可用fd持续增加; pool_server_handler 通过 read memcached服务器发送报文来判断server对应fd是否可用: 这个问题或许可以通过修订源码来解决,非通过事件处理方式来解决; Comment #10 Posted on Mar 3, 2014 by Happy Horse where is the author?can you slove this problem about telnet error? Comment #11 Posted on Oct 8, 2014 by Massive Lion I fellow you step. Comments the pool_server_handler method and the code blok /evernt_set(&(s->ev)...);event_add(&(s->ev),0)/. But when write command "I set key1 0 0 1;1 " not response also. Have you encounter this problem. Could you show me the detail solution about this problem. Thanks very much.
傲雪凌霜 2015-05-28
  • 打赏
  • 举报
回复
楼主我也遇到了这个问题 能告诉我你是怎么解决的吗?
amilier 2014-12-19
  • 打赏
  • 举报
回复
楼主问你个不相关的问题,使用magent做mamcache集群的话,那java memcache客户端的一些方法就不能使用了吧,比如statsItems()等这些与memcache server地址有关的方法
howard5812 2014-07-15
  • 打赏
  • 举报
回复
试试下边链接中 8 楼的回复 https://code.google.com/p/memagent/issues/detail?id=4
buptasia 2014-07-01
  • 打赏
  • 举报
回复
我擦跟我遇到的问题一样,我试了更改libevent 版本不行的,楼上的各位大牛你们都解决了么
01Byte空间 2014-06-19
  • 打赏
  • 举报
回复
引用 7 楼 u012598640 的回复:
楼上说的libevent版本的问题,我尝试了,还是不可以,set第二个值得时候telnet客户端就停住了
你找到解决的方法么 ,分享一下啊。
01Byte空间 2014-06-19
  • 打赏
  • 举报
回复
引用 8 楼 a422100210 的回复:
楼主,问题解决没有
没有解决
幸福的娃 2014-06-13
  • 打赏
  • 举报
回复
楼主,问题解决没有
山野闲人谷 2014-04-17
  • 打赏
  • 举报
回复
楼上说的libevent版本的问题,我尝试了,还是不可以,set第二个值得时候telnet客户端就停住了
zhangxiao1228 2013-11-22
  • 打赏
  • 举报
回复
引用 5 楼 Rookie_CEO 的回复:
[quote=引用 4 楼 zhangxiao1228 的回复:] 我也出现了同样的问题,我是在一台机器上成功通过,在另外一台机器上,set的时候一直不通
估计是代理的问题,我这边是没有找到解决方法。[/quote] 我已经解决,我的那个问题是因为libevent包的问题,libevent的1.4.14的版本就可以,libevent的2.0的版本就不行,建议你换换libevent的版本试试
01Byte空间 2013-11-13
  • 打赏
  • 举报
回复
引用 4 楼 zhangxiao1228 的回复:
我也出现了同样的问题,我是在一台机器上成功通过,在另外一台机器上,set的时候一直不通
估计是代理的问题,我这边是没有找到解决方法。
zhangxiao1228 2013-11-13
  • 打赏
  • 举报
回复
我也出现了同样的问题,我是在一台机器上成功通过,在另外一台机器上,set的时候一直不通
01Byte空间 2013-08-29
  • 打赏
  • 举报
回复


这是myeclipse执行了两条插入后夯住的图片,代码如下:
		for (int i = 11; i < 20; i++) {
Boolean b = memCacheClient.set(key + i, key + i);
System.out.println(key + i+":" + b);
}
01Byte空间 2013-08-29
  • 打赏
  • 举报
回复
xia下面是java的MemCachedClient连接池配置

String[] serverlist     = { "192.168.150.116:12000", "192.168.150.116:13000" };
		Integer[] weights       = { new Integer(5), new Integer(2) };   
		int initialConnections  = 10;
		int minSpareConnections = 5;
		int maxSpareConnections = 50;   
		long maxIdleTime        = 2000;//1000 * 60 * 30;       // 30 minutes
		long maxBusyTime        = 1000;//1000 * 60 * 5;        // 5 minutes
		long maintThreadSleep   = 1000 * 5;                     // 5 seconds
		int     socketTimeOut       = 1000 * 3;                 // 3 seconds to block on reads
		int     socketConnectTO     = 1000 * 3;                 // 3 seconds to block on initial connections.  If 0, then will use blocking connect (default)
		boolean failover        = false;                        // turn off auto-failover in event of server down       
		boolean nagleAlg        = false;                        // turn off Nagle's algorithm on all sockets in pool    
		boolean aliveCheck      = true;                        // disable health check of socket on checkout

		SockIOPool pool = SockIOPool.getInstance();
		pool.setServers( serverlist );
		pool.setWeights( weights );     
		pool.setInitConn( initialConnections );
		pool.setMinConn( minSpareConnections );
		pool.setMaxConn( maxSpareConnections );
		pool.setMaxIdle( maxIdleTime );
		pool.setMaxBusyTime( maxBusyTime );
		pool.setMaintSleep( maintThreadSleep );
		pool.setSocketTO( socketTimeOut );
		pool.setSocketConnectTO(socketConnectTO);
		pool.setNagle( nagleAlg );      
		pool.setFailover(failover);
		pool.setAliveCheck( aliveCheck );
		pool.setHashingAlg( SockIOPool.NEW_COMPAT_HASH );
		pool.initialize();   
01Byte空间 2013-08-29
  • 打赏
  • 举报
回复
同样一个set 第一次执行可以,第二次就夯住

[sms@db bin]$ java com.zxx.test.MyclassTest
This is a test String
foo111:null
foo112:null
foo113:null
foo114:null
foo115:null
foo116:null
foo117:null
foo118:null
foo119:null
foo120:null
foo121:null
foo122:null
foo123:null
foo124:null
foo125:null
foo126:null
foo127:null
foo128:null
foo129:null
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ 
[sms@db bin]$ java com.zxx.test.MyclassTest
[sms@db bin]$ 
[sms@db bin]$ 

8,030

社区成员

发帖
与我相关
我的任务
社区描述
高性能数据库开发
社区管理员
  • 高性能数据库开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧