V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
langzizx39
V2EX  ›  程序员

关于 mongodb 频繁写操作的性能问题

  •  
  •   langzizx39 · 2017-01-12 18:03:22 +08:00 · 4496 次点击
    这是一个创建于 2880 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有个系统每小时有差不多两百万的数据进来,这些数据几乎所有最终都要写库,但不是所有数据都是插入,而是大部分为更新操作。库中个别表量越堆越多,最多的已经接近 6 千万,少的也有千万以上,而且还在缓慢增长。于是我发现写入时间越来越慢,目前写库的平均时间需要 50 到 70ms ,那么我想请教一下大家:

    1. 我的 mongodb 这个写入时间是不是正常?
    2. 我 mongodb 的版本为 2.6.4 ,是库锁。如果升级 3.0 以上支持表锁之后性能会不会提升非常明显?(比如平均写入时间缩短为 20ms 以下甚至更小)
    3. 关于拆表:目前有定时任务在跑,定时移动旧数据到历史表,但是这个扫描全表并移动的过程也很漫长(今天凌晨 2 点跑到现在都没跑完)。所以还有没有更好的拆表方案?
    4. mongodb 是不是本身更偏重于读操作,所以我的场景不适用 mongodb ?
    5. 其它哪些库更适用于我的应用场景?

    希望大家指导一下我这个资历尚浅新手,谢谢大家!

    24 条回复    2017-01-13 21:35:06 +08:00
    Had
        1
    Had  
       2017-01-12 19:39:11 +08:00   ❤️ 1
    不说别的,先升级先升级先升级
    3.2 的 Document 锁给写性能带来的提升是非常非常巨大的
    gouchaoer
        2
    gouchaoer  
       2017-01-12 19:52:13 +08:00 via Android   ❤️ 1
    先说结论, mongo 是垃圾

    mongo 锁粒度最高版本只到了表级别吧,放弃了事务之类的 insert 性能只是 mysql 的 3 倍,连 join 都不支持

    你扫表用 skip 的话等于自杀, skip 等于 mysql 的 offset ,通常优化手段肯定就是区间查找了,但是 mongo 不支持自增的 int 主键。。。一个折中就是每次 insert 的时候用 collection 的数量做自增 int 加索引,当然了这个是不准的,但是可以用来区间遍历

    update 本质上是根据索引找到记录然后更新记录和索引,性能肯定没有专门为 insert 优化的快。。。。每小时 200w 数据 qps 就是 555 吧,既然木已成舟就这能上 mongo 的 sharding 了吧,多部署几台。。。谁把 mongo 这种玩具拿到生产环境支持大并发
    gouchaoer
        3
    gouchaoer  
       2017-01-12 19:55:01 +08:00 via Android
    mysql/postgres 现有的成熟方案不用,自讨苦吃
    janxin
        4
    janxin  
       2017-01-12 20:40:18 +08:00   ❤️ 1
    1-2. 3.x 效率会高一点,不多,不是神器。我们现在在亿级别插入大概是 200ms+....嗯,不过我们抖动太大,不是很有参考价值,而且 IO 瓶颈...
    3. 大量日志类型数据分拆我现在做法是按月分,自动写入当前月。但是看你的情况大概要分到日了。但是这方案缺点很明显。
    4-5. 大部分场景 SQL 数据库都可以处理。
    janxin
        5
    janxin  
       2017-01-12 20:47:28 +08:00
    换了一个性能好点的机器,大概是 20ms 以下插入
    Had
        6
    Had  
       2017-01-12 20:47:53 +08:00
    @gouchaoer 锁粒度在 3.0 提供的 WiredTiger 就是 Document 级别啊,没记错的话,从 3.2 开始有了基本的 join 了
    gouchaoer
        7
    gouchaoer  
       2017-01-12 21:20:14 +08:00 via Android
    @Had
    http://m.blog.csdn.net/article/details?id=51240798

    如果 lz 老实用 mysql/postgresql 的话, 2*12 核=24 线程的机器在 1 亿数据量上 update 的 qps 至少都 2000 以上,他这个 qps 绰绰有余。。。上了 3 亿了 mysql 分库表区方案还很成熟,直接分就完了。。。。我不信一个新的 feature 就能本质上提高多少 qps ,如果真的本质上提高了 qps 那只能说明原来很烂
    bash99
        8
    bash99  
       2017-01-12 21:24:06 +08:00
    这类数据情况不分表(区),肯定最后索引不在内存里面,然后 btree 模式的索引写性能剧降。
    换个其它模式的引擎试试,比如 rocksdb 或者 toku 之类的。
    spice630
        9
    spice630  
       2017-01-12 21:37:22 +08:00
    不如用云服务。
    billlee
        10
    billlee  
       2017-01-12 21:38:49 +08:00
    @gouchaoer update 操作的主要瓶颈是 log flush 时的磁盘操作吧?那个测试报告没给出磁盘配置
    peneazy
        11
    peneazy  
       2017-01-12 22:03:31 +08:00
    正好打算这周末学 mongodb ,难道不用学了,接着用 mysql ?
    rrfeng
        12
    rrfeng  
       2017-01-12 22:26:33 +08:00 via Android   ❤️ 1
    这里这么黑 mongo 吗?

    我们好几个表几亿都没拆还不是在跑...

    不管是什么数据库都要按需求来吧优化吧。
    SlipStupig
        13
    SlipStupig  
       2017-01-12 22:46:48 +08:00   ❤️ 1
    mongo 3.2 每天几百万数据 update ,没有 sharding , 也没分表,感觉性能没有那么糟糕啊。
    @gouchaoer
    shiny
        14
    shiny  
       2017-01-12 22:47:45 +08:00   ❤️ 1
    已经实践过的技巧:注意 update 时候的条件,有没有索引。 另外如果数据安全性要求低,可以不确认安全写入磁盘,直接返回。

    另外,不管用什么数据库,还是要想办法能不能把多次 update 给合并成单次。

    MongoDB ,太多人把它当万能药了,结果发现传统 SQL 数据库遇到的问题它也会遇到。
    billlee
        15
    billlee  
       2017-01-12 23:38:30 +08:00   ❤️ 1
    才发现是 mongodb 2.6, 这还是 MMAPv1 吧,建议测试一下 3.x 的 WiredTiger. WiredTiger 是行锁,不是表锁。基本上就相当与 MySQL 的 MyISAM 和 InnoDB 的区别。
    sujin190
        16
    sujin190  
       2017-01-12 23:44:43 +08:00   ❤️ 1
    看内存使用,看 io ,看 cpu 使用量,你这样说没意义啊,总的来说 3 比 2 很大差别就是有数据压缩,写性能也有所提升,不过 mongo 和 MySQL 相比内存不太足够的情况下性能非常低,我们现在也在用 mongo,每日写入也几百万,不过不是同一个表,延迟基本低于 10ms,毫无压力
    langzizx39
        17
    langzizx39  
    OP
       2017-01-13 10:09:09 +08:00
    @gouchaoer 感谢解答!在我接手之前用的就是 mysql ,后来因为我们数据的字段经常会增减改变,于是就把 mysql 换掉了,我会去了解一下 postgresql 的,看看它是不是适用于我们的业务场景,非常感谢指路!
    langzizx39
        18
    langzizx39  
    OP
       2017-01-13 10:16:23 +08:00
    @Had 感谢解答!目前改动量最少的方案就是升级了,我会去了解尝试一下的。
    langzizx39
        19
    langzizx39  
    OP
       2017-01-13 10:18:59 +08:00
    @janxin 感谢回复!“换了一个性能好点的机器,大概是 20ms 以下插入”,是指亿级的数据量也能在 20ms 以下吗?另外这个“性能好点”是什么配置的机器呢?
    langzizx39
        20
    langzizx39  
    OP
       2017-01-13 10:29:59 +08:00
    @rrfeng
    @SlipStupig
    感谢回复!请问你们写入的平均时间大概是多少?另外,除了分表还可以怎么按需求优化呢?
    langzizx39
        21
    langzizx39  
    OP
       2017-01-13 10:33:39 +08:00
    @shiny 感谢回复!目前我 update 的条件都是有索引的,而且也是批量的,就还不知道是不是不确认就返回,我会去试试看的。
    janxin
        22
    janxin  
       2017-01-13 10:50:12 +08:00
    @langzizx39 是的,最开始测试的机器 IO 比较差
    smallpath
        23
    smallpath  
       2017-01-13 10:51:29 +08:00
    mongo 最高到表锁???? 黑人问号???
    SlipStupig
        24
    SlipStupig  
       2017-01-13 21:35:06 +08:00
    @langzizx39 我机器比较差双核 4G 内存,机械盘,写入速度大概 1000/s
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2593 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:52 · PVG 18:52 · LAX 02:52 · JFK 05:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.