V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
iamtuzi3333
V2EX  ›  MongoDB

大佬们,大问题请教,内存占满

  •  
  •   iamtuzi3333 · 2 天前 · 2280 次点击
    小弟用 MongoDB 存储实时数据,都是传感器数据,十几个传感器,每秒都有数据发过来,需要实时存储,目前用了一个队列去一遍存一遍入库,集合都是分散开的,但是发现一个很严重的问题就是会把服务器的备用内存持续压榨,导致可用内存越来越小,用的 Window Server 服务器,192GB 只剩下十几 M ,可用内存,这个太夸张了,而且看进程 mongod.exe 这个进程占了 5 万多 MB ,很夸张,目前小弟也没有方法能立马排查出来,有大佬有过这个经验吗,请大佬指教一下。
    44 条回复    2024-09-21 11:40:57 +08:00
    liprais
        1
    liprais  
       2 天前
    你不让 mongodb 用内存他咋干活?
    pxllong
        2
    pxllong  
       2 天前
    WiredTiger 这几个参数贴下
    iamtuzi3333
        3
    iamtuzi3333  
    OP
       2 天前
    @pxllong 之前修改是 50GB ,但是还是吃的太厉害了,影响其他项目运行了,还有其他办法吗
    iamtuzi3333
        4
    iamtuzi3333  
    OP
       2 天前
    @liprais 但是吃的太厉害了,影响其他项目运行了,现在很难受,我不知道怎么改好一点,虽然他确实很好用,在考虑要不要换其他数据库了
    liprais
        5
    liprais  
       2 天前
    @iamtuzi3333
    1.你可以限制下 mongodb 占多少内存的
    2.应用跟数据库跑在一个节点上不是好的做法
    iamtuzi3333
        6
    iamtuzi3333  
    OP
       2 天前
    @liprais 有道理,我申请一下多节点服务器,但是这个估计有点难,1 这个我限制了一半内存,明天看看是啥效果,谢谢大佬解答。
    pxllong
        7
    pxllong  
       2 天前
    @iamtuzi3333 mongostat 贴下参数
    dejavuwind
        8
    dejavuwind  
       2 天前
    你有多少传感器数据需要频繁查询的,可以考虑下冷热分离,冷数据换别的存储方式,定期任务进行冷热数据迁移
    dejavuwind
        9
    dejavuwind  
       2 天前
    @dejavuwind 可以考虑专门的时序数据库 influxdb tdengine 之类的
    iamtuzi3333
        10
    iamtuzi3333  
    OP
       2 天前
    @dejavuwind 不需要频繁查询,但是有时候需要翻查历史某一段时间的数据,我看过时序数据库,但是部分是单个时间单个数据,我的数据是{id:1,data:[1,2,3]}这种,有多个字段,data 是个浮点数数组,有时候会是 200 个数字。而且每个传感器一张表,时序数据库好像不太适合。热数据我都放在了 Redis 的队列中了。
    iamtuzi3333
        11
    iamtuzi3333  
    OP
       2 天前
    @pxllong 没法发图片,我打出来部分信息,每秒输出打印 10 条左右,有个 vsize 数据每条都是 6.49G ,
    iamtuzi3333
        12
    iamtuzi3333  
    OP
       2 天前
    @pxllong 复制了一条,大概就是这样
    insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
    *0 *0 *0 *0 0 0|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 111b 59.8k 6 Sep 19 19:25:06.463
    *0 *0 *0 *0 0 1|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 112b 59.9k 6 Sep 19 19:25:07.463
    *0 *0 *0 *0 0 0|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 111b 59.8k 6 Sep 19 19:25:08.463
    *0 *0 *0 *0 0 0|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 111b 59.8k 6 Sep 19 19:25:09.464
    *0 *0 *0 *0 0 1|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 112b 59.9k 6 Sep 19 19:25:10.463
    *0 *0 *0 *0 0 4|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 514b 60.8k 6 Sep 19 19:25:11.463
    *0 *0 *0 *0 0 0|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 111b 59.8k 6 Sep 19 19:25:12.464
    *0 *0 *0 *0 0 0|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 111b 59.8k 6 Sep 19 19:25:13.464
    *0 *0 *0 *0 0 1|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 112b 59.9k 6 Sep 19 19:25:14.464
    *0 *0 *0 *0 0 2|0 0.0% 0.0% 0 6.49G 255M 0|0 0|0 321b 60.5k 6 Sep 19 19:25:15.464
    iamtuzi3333
        13
    iamtuzi3333  
    OP
       2 天前
    目前项目我停掉了,占用太多了,估计 mongo 就是吃内存,这个似乎是他原本就这么设计的。
    wheat0r
        14
    wheat0r  
       2 天前
    @iamtuzi3333 #13 基本上数据库都倾向于吃内存吧
    iamtuzi3333
        15
    iamtuzi3333  
    OP
       2 天前
    @wheat0r 这个倒不会,同台服务器上面有个 sqlserver ,MySQL ,上面也是存了大量数据,但是未发现有这么吃内存,而且现在发现 mongo 太迟了,他的底层是内存映射( Memory-Mapped Files ) 来处理数据库文件,目的是尽可能将数据库数据加载到内存中以提高读写性能。MongoDB 默认会尽量使用可用的内存来缓存数据文件和索引,因此当数据集较大时,mongod.exe 可能会占用大量内存。
    现在这是个无底洞,而且不会自动清除映射文件,全是占用在备用内存中,导致可用内存越来越少。现在我在想找新的数据库来替换了。
    wheat0r
        16
    wheat0r  
       2 天前
    @iamtuzi3333 #15 会的,sqlserver 默认的最大内存占用参数是 2,147,483,647 megabytes (MB),运行一段时间后就会将内存占满。mysql 也存在类似情况,但是不像 sqlserver 一样饥渴。
    ShuA1
        17
    ShuA1  
       2 天前
    @wheat0r mysql 也存在类似情况,但是不像 sqlserver 一样饥渴。
    可能是你配置的问题, 一样可以吃满
    yinft
        18
    yinft  
       2 天前
    哈哈 我们的项目用容器搭的 docker ,我直接限制容器最大内存占用了,简单粗暴
    yinft
        19
    yinft  
       2 天前
    @yinft 容器搭的 mongo
    iamtuzi3333
        20
    iamtuzi3333  
    OP
       2 天前
    @wheat0r 原来这样子,那看来还是机器的问题了。
    @ShuA1 那看来就是配置的问题了。现在这个问题比较难处理,难顶,现在准备更换存储方式了。
    iamtuzi3333
        21
    iamtuzi3333  
    OP
       2 天前
    @yinft 羡慕,咱们没人去搞 docker ,项目也是能 run 就行
    yinft
        22
    yinft  
       2 天前
    @iamtuzi3333 #21 mongodb 配置文件也是能指定内存进行限制的啊
    AlanBrian
        23
    AlanBrian  
       2 天前
    你说它占用 5 万 M ,这不是和你设置的 50GB 很符合吗? mongodb 就是会尽可能使用多的内存。想要降低只能把 WiredTiger 内存设置往下降。
    lingex
        24
    lingex  
       2 天前
    设置 50G ≈ 50000M ,没有问题吧?

    MongoDB 默认最大占用: (物理内存 - 1) / 2 GB
    jason56
        25
    jason56  
       2 天前
    试试 storageEngine = wiredTiger
    jason56
        26
    jason56  
       2 天前
    少贴一行 wiredTigerCacheSizeGB=2
    SWALLOWW
        27
    SWALLOWW  
       2 天前
    它快不就是用内存吗
    pangdundun996
        28
    pangdundun996  
       2 天前
    把 WiredTiger 内存占用调小点就行了
    bcllemon
        29
    bcllemon  
       1 天前
    这个数据是一定要存 mongodb 吗? 是不是可以考虑换时序数据库
    KingPL
        30
    KingPL  
       1 天前
    业务场景应该选用时序数据库
    maokg
        31
    maokg  
       1 天前
    试试 influxdb 、tdengine
    GodIsJasonBourne
        32
    GodIsJasonBourne  
       1 天前
    工作缘故,我看过一遍 mongodb 文档说的明白,它就是会最大限度利用内存,加速读写。 楼上也说的很明白,从存储引擎设为 wiredTiger+配置 cacheSize 入手去优化。
    975779964
        33
    975779964  
       1 天前
    `而且每个传感器一张表,时序数据库好像不太适合`

    你是有多少传感器? 目前我们做的项目 监听 4 万多个传感器数据上报 ,每个传感器 差不多 每 5 秒 2~3 条数据上报,用的 tdengine 和 influxdb ,已经跑了 1 年多了,目前没啥问题
    ktonline
        34
    ktonline  
       1 天前
    用时序数据库啊 兄弟,哪怕 es 也行
    iamtuzi3333
        35
    iamtuzi3333  
    OP
       1 天前
    @yinft 我限制了,但是还是用的很严重。
    @AlanBrian 但是现在备用内存疯狂涨,把可用压榨到十几 M 了,我看了内存占用里面,备用内存中全是他的 mapper 映射文件,用量太厉害了。
    @jason56 我用的新版本,就是这个引擎,内存设定的是 50 多 G ,
    @pangdundun996 已经改了,但是效果不明显。
    @GodIsJasonBourne 这个新版已经是这个设置,参数设置的 50 多 G 。
    iamtuzi3333
        36
    iamtuzi3333  
    OP
       1 天前
    @bcllemon 时序数据库我还在找,但是数据是 JSON 对象,关键的字段 data 是一个数组,时序数据库大部分是存单个值,不太符合。
    @KingPL 目前是还在找。
    @975779964 目前传感器会有几百个,然后数据格式都是 JSON ,其中设备不同,字段也不同,然后传感器每秒上传数据,其中数据有多个字段,其中一个字段是数组,存的元素比较多,几百个,目前看了 influxdb ,他好像只支持单值存储,还有其他好推荐的吗。每个传感器单表就是不想多传感器数据混合在一起,最多的业务场景就是突然要查询某一段的历史数据。
    @ktonline 这个全称是啥,大佬指点一下。
    iamtuzi3333
        37
    iamtuzi3333  
    OP
       1 天前
    重要的业务场景就是存储不同传感器设备数据,保障完整性,可用性,然后一个需求就是能够方便查询数据,这也是我为什么想单个传感器单表存储,传感器数量多,数据比较高频,字段比较多,有没有大佬指点一下这方面改用啥时候好用一点,后台用 nodejs 或者 Java 写查询功能多一点。目前公司就我一个人顶着,有点难顶,还请各位大佬指教,服务器用的 Window server ,华为云服务器,配置不会太差,此前有个项目有 600 多个传感器,也用的 MongoDB ,一启动内存就慢慢被占用满,导致可用内存越来越少,影响其他项目运行。数据除了存库还有个写入文件保存,目前初步排查是因为写入速度跟不上接入速度,导致数据跟文件全部堆积在内存中。
    AlanBrian
        38
    AlanBrian  
       1 天前
    不确定你这个 mongodb 是怎么部署的,我们的业务场景 mongodb 写入速度拉满,1 小时能写入好几亿的数据。可能跟机器的性能也有关系。
    Moyyyyyyyyyyye
        39
    Moyyyyyyyyyyye  
       1 天前
    数据库单独部署,线上环境哪有数据库和应用程序一个机器的
    xsi640
        40
    xsi640  
       1 天前
    这种场景,时序数据库不是更适合么?
    iamtuzi3333
        41
    iamtuzi3333  
    OP
       1 天前
    @AlanBrian 现在这个 MongoDB 用的社区版本,然后是 Window server 服务器,就是直接启动。
    @Moyyyyyyyyyyye 小公司就一台服务器,没办法。
    @xsi640 时序我看了一番,没发现有很合适的,主要是字段不方便存,很多时序数据库都是支持字段单值存储,我的数据字段重点是一个数组。
    Haku
        42
    Haku  
       1 天前
    MongoDB 好像是这样的,狂吃内存,而且它不是只吃一点,不限制的话是你给多少吃多少那种。
    建议要么和别的服务分开放,要么就用参数摁死了。
    iamtuzi3333
        43
    iamtuzi3333  
    OP
       1 天前
    @Haku 参数都按不死,疯狂吃,吃的只剩下十几 M 可用,内存一看全是映射文件占着茅坑。
    juvenn
        44
    juvenn  
       23 小时 45 分钟前
    [#12]( https://v2ex.com/t/1074136#r_15281543)

    从 12 楼的统计看这个读写吞吐都很低,不应该占用这么高的内存。感觉还是哪里配置有问题。(我们有生产用的多个 mongo 集群,32GB 内存上千的 qps 都没有压力。)

    1. 不要用 MMap ,切到 WiredTiger 。
    1. 传感器的数据模型,最好用时序数据库。比如 GreptimeDB ,支持 binary ,可以存 json 或者数组。
    1. 如果对查询实时性要求不高,也可以用 ClickHouse ,支持 json ,数组等。列式存储,压缩比率和查询效率都很高。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2466 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 03:26 · PVG 11:26 · LAX 20:26 · JFK 23:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.