mongo 4.2 操作手册:https://docs.mongodb.com/v4.4/release-notes/4.4/
服务器概况
硬件平台:x86_64
机器硬件名:x86_64
系统处理器的体系结构:x86_64
内核版本:#1 SMP Fri May 8 10:59:10 UTC 2020
操作系统:GNU/Linux
操作系统的发行版号:4.18.0-193.el8.x86_64
Linux系统:CentOS Linux release 8.2.2004 (Core)
物理CPU个数:1
每个物理CPU核数:20
逻辑CPU个数:40
内存:32GB
彼时服务器资源占用情况:
数据概况
大小:316G;
类型:JSON;
行数:约3.8亿,每一行即为一条json数据;
格式:
{
"description": "东莞市星东升实业有限公司,东莞市星东升实业有限公司位于广东省东莞市高埗镇冼沙村二上坊第二工业区,,联系电话13612672983(郑春",
"domain": "zhsho.com",
"keywords": "东莞市星东升实业有限公司,华东、华西、华北、华南",
"lang": "zh",
"level": 4,
"mode": "base",
"page": "",
"path": "/",
"pdate": 1623810162,
"prefix": "ywss276.cn",
"ptype": "home",
"query": "",
"rurl": "http://ywss276.cn.zhsho.com/",
"status": 200,
"suffix": ".com",
"title": "华东、华西、华北、华南_东莞市星东升实业有限公司",
"update": 1623810162,
"url": "http://ywss276.cn.zhsho.com/",
"version": "Version/0.1.2 Website/81.69.254.180",
"website": "ywss276.cn.zhsho.com",
"name": [ ],
"type": "企业",
"score": 0.9913351535797119,
"rank": 10,
"icp_domain": "zhsho.com",
"icp_icp": "冀ICP备18027592号",
"icp_pdate": "2019-08-27",
"icp_name": "河北张铭信息科技有限公司",
"icp_type": "企业",
"_id": "5369ef45a52e949671792387a0e1616d"
}
mongo版本
使用 docker 部署 mongo,单实例。
docker run -it -p 20183:27017 -v /mnt/data/zitian/data/docker/mongo/:/data --name mongo1 -d mongo
mongo 版本
导入
进入创建好的 docker,执行如下命令:
mongoimport -d aiip -c site --file /data/aiip_site.txt --upsert
mongoimport 参数:
Q&A
1、内存占用过多,导致 docker 直接被 kill
从 mongodb 3.4 开始,WiredTiger(默认引擎)内部缓存大小是以下两者中的较大者:
50%(RAM-1 GB),或 256 MB
本文实验的服务器内存是32G,计算可知,默认情况下,mongodb将至多使用约15G的内存,而在实验伊始,服务器已经有60%的内存被占用,因此,数据导入过程中,内存占用的不断累加势必会导致程序的崩溃。
此时已经知道程序崩溃是因为数据导入导致内存占用过多,因此首先尝试的方法是将大文件拆分为小文件。
使用 split 命令将数据文件拆分为若干个小文件。
# 最后一个参数是输出文件前缀,所以“.”别忘了
split -l 10000000 -d /data/aiip_site.txt aiip_site.txt.
split 参数:
然后就是逐一导入小文件(一个文件也有一千万的数据···),为了自动化还得再写个脚本...。
#!/bin/bash
workDir=$1
tgtStr=$2
if [ -d $workDir ];then
cd $workDir
else
exit 1
fi
for i in `ls $workDir`
do
filename=${i##*/}
if [ ${filename:0:13} = $tgtStr ]; then
echo $i
cmd_str=`mongoimport --host 127.0.0.1 --port 20183 -d aiip -c site --file $workDir/$i --upsert`
echo $cmd_str
fi
done
2、mongodb占用的内存不主动释放
在使用问题1中描述的方法后,虽然在前几次导入时不会引起内存占用而导致程序崩溃的问题,但经过多次导入之后,mongodb的内存占用依然很明显,查询之后知道,mongodb在插入,删除,更新时会占用内存,并且不主动释放,从而导致问题1复现。
针对如上的问题,想到两种方法,一种是限制mongodb内存使用,一种是主动释放内存。
限制mongodb内存使用
由于本文使用 docker 部署 mongodb,所以对 docker 的内存限制即是对 mongo 的内存限制。
删掉之前的创建的 mongo docker,使用如下的命令创建新的 mongo docker:
docker run -it -p 20183:27017 -v /mnt/data/zitian/data/docker/mongo/:/data -m 5G --memory-swap -1 --name mongo1 -d mongo
此方法带来的好处是,内存占用问题得以解决,但同时也降低了数据导入的性能。
通过配置文件的方式也试了,但是在容器内重启mongo时直接导致容器退出:
storage:
dbPath: /data/db
journal:
enabled: true
engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 5
另外还有一种方法是从系统层面的,可参考使用cgroups限制MongoDB的内存使用
主动释放内存
网上找到的方法是通过命令:
> use admin
> db.runCommand({closeAllDatabases:1})
但此方法在 mongo 3.4 之后已经废弃,并且主动释放 mongodb 占用的内存虽然能解决内存占用问题,但是也影响了正常的读写操作。
(另一种粗暴的方式就是重启mongodb...)
导入测试
注意:
mongodb已经限制了内存使用上限为 5GB;
导入是不存在时插入,存在则更新;
数据有较多重复;
NO | 数据大小 | 总耗时(单位:秒) | 平均速度(单位:条/秒) |
1 | 10.1GB / 1000万 | 3180 | 3145 |
2 | 9.7GB / 1000万 | 2236 | 4472 |
3 | 7.58GB / 1000万 | 1801 | 5552 |
4 | _/约1.4亿 | 50010 | 2799 |
5 | 7.41GB / 1000万 | 4079 | 2451 |
导出
待用到时补上
mongoexport -h 127.0.0.1:20183 -d aiip -c site -o /mnt/data/zitian/data/docker/mongo/aiip_site.json --type json
22 评论
阿添 2021-07-28 17:36:52
测试
阿添 2021-07-22 18:30:25
111
阿添 2021-07-22 18:25:08
444
阿添 2021-07-22 18:24:32
555
阿添 2021-07-22 18:21:31
444
阿添 2021-07-22 18:21:10
666
阿添 2021-07-22 18:20:50
555
阿添 2021-07-22 18:20:27
2222
阿添 2021-07-22 18:20:03
999
阿添 2021-07-22 18:19:22
888
阿添 2021-07-22 18:18:17
777
阿添 2021-07-22 18:15:52
666
阿添 2021-07-22 18:15:19
666
阿添 2021-07-22 18:13:33
555
阿添 2021-07-22 18:12:03
999
阿添 2021-07-22 18:11:29
555
阿添 2021-07-22 18:10:38
222
阿添 2021-07-22 18:06:32
222
阿添 2021-07-22 18:05:53
111