Redis文件连接数不够导致listen sock总是可读CPU跑满

前几天碰到碰到一个线上redis CPU跑满的情况,基本无法处理正常请求了,刚开始以为是其他地方的问题,后来grep "Max open files" /proc/`pidof redis-server`/ -r  排查原来是启动redis的时候。ulimit -n 只有1024,从而无法接受新连接。

晚高峰时间段突发的大量请求导致redis连接数超过1024,从而listen sock 持续可读并且accept失败,从而CPU跑满,导致严重的雪崩。比如简单复现的话,ulimit -n 20 修改当前会话的打开文件数,然后启动某个服务器程序,然后给其发送超过限制的TCP连接,这时候监听套接字一定会每次select / epoll的时候,都返回句柄可读。从而不断的accept调用,然后accept立即出现如下错误,也就是EMFILE:

accept failed. errno:24, errmsg:Too many open files.

但是,accept的实现里面遇到句柄数不够的处理方法为:留在下次处理,而不是断开TCP连接,也是有道理的,因为下回说不定就关闭了一些呢。

但这一就会导致监听套接字不断有可读消息,但却accept无法接受,从而listen的backlog被塞满;从而导致后面的连接被RST了。

这里多啰嗦一下,memcached对于这种情况的处理有点特殊,或者说周到,如果memcache accept 的时候返回EMFILE,那么它会立即调用listen(sfd, 0) , 也就是将监听套接字的等待accept队列的backlog设置为0,从而拒绝掉这部分请求,减轻系统负载,保全自我。还是挺不错的。

时间: 2024-10-05 13:08:49

Redis文件连接数不够导致listen sock总是可读CPU跑满的相关文章

"Redis客户端连接数一直降不下来"的有关问题解决

[线上问题] "Redis客户端连接数一直降不下来"的问题解决 前段时间,上线了新的 Redis缓存(Cache)服务,准备替换掉 Memcached. 为什么要将 Memcached 替换掉? 原因是 业务数据是压缩后的列表型数据,缓存中保存最新的3000条数据.对于新数据追加操作,需要拆解成[get + unzip + append + zip + set]这5步操作.若列表长度在O(1k)级别的,其耗时至少在50ms+.而在并发环境下,这样会存在“数据更新覆盖问题”,因为追加操作

server version for the right syntax to use near 'USING BTREE 数据库文件版本不合导致的错误

MySQL 返回:#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE,  KEY `lang` (`language_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8' at line 5 解决办法是打开要导入

MongoDB索引文件破坏后导致查询错误的问题

问题描述: MongoDB在非正常情况下关闭时,可能会导致索引文件破坏,造成数据在更新时没有反映到索引上. 解决方案: 使用脚本,重建MongoDB所有表的索引. var names  = db.getCollectionNames(); for( var i in names ){     var name = names[i];     print(name);          var coll = db.getCollection(name);     coll.reIndex(); }

net 编译报错:编辑器或项目正在尝试签出在内存中修改的文件,这将导致保存该文件

1,报错提示: 编辑器或项目正在尝试签出在内存中修改的文件,这将导致保存该文件. 在生成过程中保存文件是危险的,这可能会在将来导致不正确的生成输出. 是否仍然继续签出? 2,原因:licenses.licx属性设为了只读. 3,解决: a,搜索''licenses.licx',去掉只读属性; b,LicensesClear.exe放到项目根目录下,双击执行. 递归取消licenses.licx只读属性,源码 原文地址:https://www.cnblogs.com/qqhfeng/p/92947

Java IO把一个文件中的内容以字符串的形式读出来

代码记录(备查): /** * 把一个文件中的内容以字符串的形式读出来 * * @author zhipengs * */ public class FileToString { public static void main(String[] args) { System.out.println(readFileToString()); } private static String readFileToString() { // new 一个空文件,用于获取路径 File dirs = ne

Json数据如果作为配置文件比较难读懂,XML文件作为配置文件有先天的优势,容易读懂和配置,因此不考虑效率时,在页面中宁可用XML文件作为配置文件再用JS做一次转化把XML转成JSON使用

比如如下相对比较复杂的XML <myobjects> <!--object 1--> <myobject> <id>yourID_1</id> <name>your name</name> <description> <![CDATA[Merck Biologics Pilot Plant ]]> </description> <locations> <location

redis占用高内存导致的socket连接失败

最近在搞ELK日志平台,部署filebeat收集日志时(输出到redis),出现了经典的[连接被目标机器积极拒绝]异常, 1)环境配置: 开发机,开发服务机(开发机上的virtualbox虚拟机,启动了ELK服务).测试机.测试服务机(ELK) 2)本机(开发机)使用可输出日志到开发服务机 + 测试服务机 3)测试机可输出日志到开发服务机,配置为测试服务机则提示 [2017-04-07T13:39:52+08:00 ERR Connecting error publishing events (

解决docker数据文件过大导致根磁盘满的问题

背景: 最近在线上使用的docker主机发现根目录容量快满了,一番查找,发现是docker的data文件过大了.     我们知道docker数据默认是存放在/var/lib/docker下的,我们可以在启动时用-g --graph=""参数,把数据目录更改到其他容量大的地方去.但是对于在使用中的docker来说,直接修改这个目录路径,会导致镜像和容器都丢失了,所以修改参数这个方法适用于初始化docker的时候使用. 对于又想解决根分区容量满,又不想更改数据存储路径的我来说,我不想更改

连接数过多导致程序连接报错的原因

涉及到的参数:    max_connections 1024 max_user_connections 1000 wait_timeout 100 连接数是直接反应数据库性能好坏的关键指标.可能的原因包括: (1)sql查询堵死,造成后面的DML操作等待: (2)增删改查操作频繁,磁盘IO遇到瓶颈,导致无法处理繁忙请求等. 如果出现too manyconnections,直接增大max_connections值得同时,一般设置为500-1000,在大多数情况下就可以了,但是如果继续增加,比如增