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

mongodb 导入数据怎么破

  •  
  •   dtgxx · 55 天前 · 1849 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数据量太大 几百亿,但是只有一台机器,存储够用。


    数据需要以三个字段建联合唯一索引。


    如果不建索引,导入差不多一周就完事了。 但是联合唯一索引在导入数据之后有重复数据就无法创建了,去掉重复数据也非常的难。 建索引之后再导数据,非常非常非常的慢,可能是索引影响了插入速度。。


    大佬们有啥高招吗

    34 条回复    2020-08-08 15:16:43 +08:00
    wupher
        1
    wupher   55 天前
    那就不要用唯一性索引
    dtgxx
        2
    dtgxx   55 天前
    @wupher #1 尴尬。。。这个是刚需。。
    abcbuzhiming
        3
    abcbuzhiming   55 天前
    不能自己写程序读取数据,然后在去重的基础上导入吗?无非就是慢一点呗
    dtgxx
        4
    dtgxx   55 天前
    @abcbuzhiming #3 写了很多程序,也做了非常多的优化,慢的不行。。数据量太大,程序无法支持去重的。
    jiangzhuo
        5
    jiangzhuo   55 天前   ❤️ 1
    去阿里云 AWS 之类的开一套高性能的机器,导入,然后关闭数据库,把导入好的文件传回你那台机器,用导好的文件启动数据库。
    dtgxx
        6
    dtgxx   55 天前
    @jiangzhuo #5 你这个建议蛮不错的,以后遇到需求感觉可以这么试试,挺好。只是目前这部分数据价格比较高买的,不太想放到别人服务器。
    594duck
        7
    594duck   55 天前 via iPhone
    就不能先倒入关系数据库,再处理好所有的逻辑。死磕那个干嘛
    billlee
        8
    billlee   55 天前
    你导进去要干嘛?这样即使能导完用起来还是会很慢啊
    dtgxx
        9
    dtgxx   55 天前
    @billlee #8 查询用,之前不加联合索引是查询是很快的,两百亿数据查询,差不多 50ms 就能返回。
    dtgxx
        10
    dtgxx   55 天前
    @594duck #7 主要是目前只有一个机器,用关系型数据库会比 mongo 慢更多。mongo 不用联合索引每秒我这可以处理到大约 50 万条数据,关系型数据库单点的肯定做不到。
    zxlzy
        11
    zxlzy   55 天前 via Android
    @dtgxx 他这个建议是最靠谱的了,至于数据价格贵…… 多少大中小互联网公司生死存亡的数据都放在阿里云和 aws 上了。
    entertainyou
        12
    entertainyou   55 天前 via Android
    分表?
    594duck
        13
    594duck   55 天前 via iPhone
    @dtgxx 200 亿 50ms 返回?纯文本文件 200 亿行,grep 一下中间的文件,50ms 都回不了。

    要么你这技术已经很到家了,要么我淘汰了
    showhand
        14
    showhand   55 天前 via iPhone
    是不是先读取索引数据,把重复的记下来,然后导入的时候判断下数据是否在重复的索引里面
    wupher
        15
    wupher   55 天前
    索引无非是为了方便查询,你可以在查询函数上做文章,查询多条记录后,再返回你想要的唯一记录,或者通过逻辑字段来标识删除,都是可以的。

    唯一性索引本来就很影响性能,数据,建议谨慎使用。几百亿数据,正常都应该 sharding 了,更不建议使用唯一性索引。

    5 楼的建议也相当棒,买机器来处理也是条思路。
    dtgxx
        16
    dtgxx   55 天前
    @zxlzy #11 放阿里云 aws 基本都是民口的。
    JCZ2MkKb5S8ZX9pq
        17
    JCZ2MkKb5S8ZX9pq   55 天前
    需求没看很懂,唯一索引是建一个单独的字段,还是 createIndex ?
    如果碰到重复,处理逻辑是什么样的?

    另外有个比较基本的差别,insert_many 比逐条插入要快很多。可以考虑先 createIndex 然后批量导入,最后再说处理重复,不知道能不能行。
    dtgxx
        18
    dtgxx   55 天前
    @wupher #15 确实是,感觉之前的不使用索引的方式也可以,只是下游取的时候得自己做去重了,而且增量订阅的时候,每次更新的数据量也越来越大了。
    dtgxx
        19
    dtgxx   55 天前
    @JCZ2MkKb5S8ZX9pq #17 三个字段的联合索引,目前使用 mongoinsert 导入数据,insert_one 和 insert_many 都比较慢,都放弃了。重复数据保留任何一条就可以了。
    zhuifeng1017
        20
    zhuifeng1017   55 天前 via Android
    用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的
    dtgxx
        21
    dtgxx   55 天前
    @zhuifeng1017 #20 啊 大佬,这个哪里有说明吗,真是这样就太好啦
    JCZ2MkKb5S8ZX9pq
        22
    JCZ2MkKb5S8ZX9pq   55 天前
    @dtgxx 20 楼说的看了眼,学到了。但感觉不管哪种去重,查找的花销总归是难免的,不如先全部丢进去再说了。可以以后慢慢处理。

    > 但是联合唯一索引在导入数据之后有重复数据就无法创建了
    这个没有看懂,如果是 mongo 自带的 index 不是可以重复的吗?
    windyland
        23
    windyland   55 天前 via Android
    所以为什么不试试阿里云开内存盘呢。。。。。。?
    dtgxx
        24
    dtgxx   55 天前
    @JCZ2MkKb5S8ZX9pq #22 先导入数据,然后添加唯一索引,被索引的字段如果有重复,这个索引就会建失败。
    JCZ2MkKb5S8ZX9pq
        25
    JCZ2MkKb5S8ZX9pq   55 天前
    @dtgxx 是用

    createIndex({name:1,gender:1,age:1})
    如果是这种是可以重复的吧?

    加了{unique: true}的话倒不清楚,没用过这个,查询会更快吗?
    我去试试看这个。

    也可以考虑初期先导入,用起来再说,日后慢慢去重做 unique 吧。
    dtgxx
        26
    dtgxx   55 天前
    @JCZ2MkKb5S8ZX9pq #25 联合唯一索引,唯一指的就是 unique 。
    JCZ2MkKb5S8ZX9pq
        27
    JCZ2MkKb5S8ZX9pq   55 天前   ❤️ 1
    @dtgxx 嗯,看了下的确没有先 compound 然后再转换的方法。那就等于全部数据要预处理,那是怎么都快不起来了。
    去重的话感觉也是先建非 unique 的 index,然后排序去重能快一点。不过你这个量是满夸张的。
    wupher
        28
    wupher   55 天前   ❤️ 1
    只有单条重复性不多的情况可以用这种方法。

    如果单条数据重复数量级很大,那就不适合了。

    几百亿也可以考虑放 ES 或者 Cassandra
    dtgxx
        29
    dtgxx   55 天前
    @zhuifeng1017 #20
    引用:用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的
    这个你自己试过吗?我刚测试了,并不可以。

    @wupher 是 之前考虑用分布式大数据存储之类的,最终机器限制,就没搞。
    v2exblog
        30
    v2exblog   55 天前
    假设数据有 500 亿。
    首先对数据对三个联合主键做一个取余,假设是模 10000,这样数据被分成了 10000 份,平均每份 500w 数据,所以只需要对这 500w 数据去重就行了,做好后直接插入数据库,不用建立唯一索引
    smallgoogle
        31
    smallgoogle   54 天前
    哎。别说了。才弄完。5 亿数据。
    dtgxx
        32
    dtgxx   54 天前
    @v2exblog #30 没太明白,把数据分成 1 万份,不也需要每一份都去重吗。
    @smallgoogle 共勉老铁。
    kuafou
        33
    kuafou   46 天前
    @dtgxx 问题解决了吗?
    dtgxx
        34
    dtgxx   46 天前
    @kuafou #33 只能导入之后,去重,再建索引,去重也非常慢,不过目前没有别的好办法。去重虽然慢,但是要远远快于提前建好索引的情况。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3380 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:35 · PVG 18:35 · LAX 03:35 · JFK 06:35
    ♥ Do have faith in what you're doing.