ubuntu二进制安装mongodb副本集大量写入数据提示Too many open file

背景

由于上次k8s事故导致mongodb数据损坏,所以本次重构时将mongodb以二进制方式部署到物理服务器上。使用systemctl管理进程。mongodb副本集搭建完成过后,使用mongorestore导入数据时,mongodb进程不定时非正常退出,mongorestore要么卡着不动,要么直接退出。

版本介绍

mongodb: 5.0.27
OS :ubuntu20.04

部署简述

1、解压mongodb的tar包,并编写启动配置文件,配置文件参考如下:

systemLog:
  destination: file
  logAppend: true
  path: /Raid_disk/mongodb/mongodb_log/mongod.log  
storage:
  dbPath: /Raid_disk/mongodb/mongodb-data 
  journal:
    enabled: true
processManagement:
  fork: true
  pidFilePath: /Raid_disk/mongodb/mongod.pid
net:
  port: 27017
  bindIp: 0.0.0.0
replication:   
  replSetName: rs0
#security:
  #clusterAuthMode: keyFile
  #keyFile: /Raid_disk/mongodb/key/mongo.key
  #authorization: enabled

2、按照启动配置文件创建目录等
3、编写service文件,参考如下:

[Unit]
Description=Mongodb Service
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/Raid_disk/mongodb/mongodb-5.0.14/bin/mongod -f /Raid_disk/mongodb/mongodb.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/Raid_disk/mongodb/mongodb-5.0.14/bin/mongod -f /Raid_disk/mongodb/mongodb.conf --shutdown
PrivateTmp=true

[Install]
WantedBy=multi-user.target

4、使用systemctl启动mongodb服务并初始化集群
systemctl daemon-reload
systemctl start mongod

登录节点初始化副本集。

导入数据,出现故障

操作:

使用mongorestore导入数据

mongorestore --host rs0/x.x.x.x27017,x.x.x.x:27017,x.x.x.x:27017 -u root -p '.....' -d db_name file_path --drop

现象

还原的过程中突然卡着,或者还原的命令直接退出。

排查

1、查看mongodb集群状态

发现更本就无法登录,或者登录进去有一个节点状态不正常。
使用systemctl status mongod查看每个服务器上的Mongod启动状态。发现有一个或者两个或者全部都非正常退出。

2、查看mongodb日志

发现有大量的Too many open file....打印出来,如下:

{"t":{"$date":"2023-01-14T14:45:01.435+08:00"},"s":"F",  "c":"CONTROL",  "id":6384300, "ctx":"AuthorizationManager-1","msg":"Writing fatal message","attr":{"message":"DBException::toString(): TooManyFilesOpen: error in creating eventfd: Too many open files\nActual exception type: mongo::error_details::ExceptionForImpl<(mongo::ErrorCodes::Error)264, mongo::AssertionException>\n\n"}}
{"t":{"$date":"2023-01-14T14:45:01.435+08:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn468","msg":"client metadata","attr":{"remote":"10.10.1.5:45732","client":"conn468","doc":{"driver":{"name":"mongo-java-driver","version":"4.1.2"},"os":{"type":"Linux","name":"Linux","architecture":"amd64","version":"5.4.0-121-generic"},"platform":"Java/IcedTea/1.8.0_212-b04"}}}
{"t":{"$date":"2023-01-14T14:45:01.435+08:00"},"s":"W",  "c":"NETWORK",  "id":23023,   "ctx":"listener","msg":"Error accepting new connection","attr":{"error":{"code":264,"codeName":"TooManyFilesOpen","errmsg":"error in creating eventfd: Too many open files"}}}

从日志可以看出很明显是内核参数中文件打开限制。此处还是开心的(^_ ^)

使用ulimit -n查看服务器上限制是1024。这不是把饭味道最里边了吗?
ulimit -n 204800

ulimit -n检查一下,嗯嗯,确实是我配置的,这么多总该够了吧。
启动mongodb进程,登录检查集群状态,恩恩,不错,没有问题。

那就干正事吧,开始还原数据……
经过漫长的等待,终于,他喵的,集群又坍了,日志还是报这个错,mongodb进程依然是非正常退出。

3、修改内核文件

从第二步中结果看出,使用ulimit -n 204800配置没有生效,那肯定是配置地方没对,所以没生效。

于是,我就在修改配置的漫漫苦难旅途中上下求索,爆炸重组,崩溃大哭在这里插入图片描述。所有人都是说的修改了文件限制需要重启服务器,对于我,这尼玛是线上的环境,我又不是胆子长毛了,我敢随便重启服务器?

然后经过多次查看发现虽然配置了limits.conf但是,这个是对于普通启动进程生效,但是对于systemctl管理的进程却是不生效的。那么针对systemctl管理的进程,应该咋弄?请看下面:

1、查看进程现在启动的进程限制:
cat /proc/${PID}/limits

cat /proc/1754103/limits 
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             2058055              2058055              processes 
Max open files            204800               204800               files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       2058055              2058055              signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us

默认是max open files 1024,在这里我们可以直接修改进程的限制,prlimit --pid 1754103 --nofile=204800:204800这是临时的,进程关闭就失效。

对于单个service永久生效,可以在service文件中添加,如本次的Mongod.service,修改后:

[Unit]
Description=Mongodb Service
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/Raid_disk/mongodb/mongodb-5.0.14/bin/mongod -f /Raid_disk/mongodb/mongodb.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/Raid_disk/mongodb/mongodb-5.0.14/bin/mongod -f /Raid_disk/mongodb/mongodb.conf --shutdown
PrivateTmp=true
#配置文件限制
LimitCORE=infinity
LimitNOFILE=204800
LimitNPROC=204800

[Install]
WantedBy=multi-user.target

也可以对所有systemctl 管理的进程管理配置:

vim /etc/systemd/system.conf 
[Manager]
DefaultLimitCORE=infinity
DefaultLimitNOFILE=204800
DefaultLimitNPROC=65535

vim /etc/systemd/user.conf
[Manager]
DefaultLimitCORE=infinity
DefaultLimitNOFILE=204800
DefaultLimitNPROC=65535

#生产环境一般处于禁用状态
DefaultLimitCORE=infinity
#核心转储文件大小不限制,它是进程运行时突然崩溃的那一刻的内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个文件里,可使用 gdb 工具来分析。core dump 生产环境一般处于禁用状态,对于内存消耗性的进程,core dump 时会占用很多系统资源,磁盘空间也可能被写满。
DefaultLimitNOFILE=1048576
#服务进程可以打开文件的最大数目为1048576
DefaultLimitNPROC=65535
#进程可以打开的最大线程数目为65535

运维的小伙伴们,好运!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值