V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
leebs
V2EX  ›  MongoDB

mongodb 数据全量加载到 redis,怎样提升速度?

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

    假设 50w 数据,db 全量查询,再往 redis 里面塞,内存可能会爆。 db 分页查询,需要先 count ,是个耗时的操作,而且分批次插入,最终结果和数据库不一定一致(中间可能有其他删除修改的操作)。

    比如布隆过滤器,一般是怎么导入亿级数据的?

    22 条回复    2022-03-09 12:06:51 +08:00
    hidemyself
        1
    hidemyself  
       207 天前
    cursor ? MySQL 和 PG 是可以的
    wqhui
        2
    wqhui  
       207 天前
    分批弄数据进去,导数据过程中发生修改的数据记录一下,这部分数据再刷一下
    git00ll
        3
    git00ll  
       206 天前
    你只能做到 redis 与 db 中的某个瞬间的数据是一致的,不可能保证恰好与导入完成时数据一致。考虑看业务上能否改。
    另外 redis 写时,开 20-30 线程一起写会快很多。
    wellsc
        4
    wellsc  
       206 天前
    为什么要全量导入啊,增量不行吗?你确定所有数据是热数据?
    wellsc
        5
    wellsc  
       206 天前
    @git00ll 你是哪个版本的 redis 哦
    hopingtop
        6
    hopingtop  
       206 天前
    不严谨回答:如果是 mongodb 全量数据,可以考虑采用 mongodb 的内存引擎 你可以了解一下
    git00ll
        7
    git00ll  
       206 天前
    @wellsc 与哪个版本的 redis 没有关系,因为应用与 redis 网络交互 RTT 的存在,单线程写很难达到 1000 次 /s 。
    wellsc
        8
    wellsc  
       206 天前
    @git00ll pipeline 用了吗
    q1angch0u
        9
    q1angch0u  
       206 天前
    不一直问题可以用线上双写解决吧~
    visitant
        10
    visitant  
       206 天前
    可以试试接 mongoDB 的 binlog ,然后写入 redis ,看你的业务能不能接受最终一致了
    Mithril
        11
    Mithril  
       206 天前
    确定一个时间点,比如当前时间,然后把所有 update time 在这之前的数据全拉出来塞到 redis 里。可以想办法跳过序列化和反序列化,直接塞进去。
    然后你去查在这时间点以后的 change stream ,按顺序拉到 redis 里。MongoDB 已经给你这功能了,就不要再用 binlog 了。
    从此以后用 change stream 同步修改,就可以保证大部分时候都是一致的。
    bthulu
        12
    bthulu  
       206 天前
    去掉 mongo, 全部采用 redis 就行了
    leebs
        13
    leebs  
    OP
       206 天前
    @bthulu 以前的数据怎么导入呢。
    leebs
        14
    leebs  
    OP
       206 天前
    @wqhui 按一千条分批查询,MongoDB 查询后面十几万数据很慢,每次读都需要三四秒的时间。
    leebs
        15
    leebs  
    OP
       206 天前
    @hidemyself 用 cursor 感觉很慢啊。
    leebs
        16
    leebs  
    OP
       206 天前
    @git00ll redis 不是单线程处理事件的嘛,开多少线程也是一个一个处理的吧。
    leebs
        17
    leebs  
    OP
       206 天前
    @wellsc 比如要校验数据是否存在,得先把数据全量导入 redis 。
    wellsc
        18
    wellsc  
       206 天前
    @leebs 布隆?
    zmzeng12
        19
    zmzeng12  
       205 天前
    @leebs
    redis bulk 写入有两个重要的优化,应该先试试:
    1. redis pipeline
    2. 多线程 /进程并发写入 redis ,redis server 端采用 IO 多路复用设计,加上纯内存操作,因此性能很高,因此 client 端要上多线程才能榨出 QPS 上限,规格不是很小的话,写入数万 QPS 都是很正常的,可以参考华为云给的性能白皮书 https://support.huaweicloud.com/pwp-dcs/dcs-pwp-0606002.html

    如果只是做数据存在 /重复校验,不需要导入全量数据到 redis ,可以参考:
    1. 按 @wellsc 的回答用布隆过滤器解决,看 https://redis.com/redis-best-practices/bloom-filter-pattern/
    2. 如果数据 primary key 能比较好地一一映射成数字,也可以通过 bitmap 解决
    leebs
        20
    leebs  
    OP
       205 天前
    @zmzeng12
    1. 用布隆过滤器,首先得把数据导进去把。
    2. 数据无规律,都是用户提交的任意数据,有什么好的映射方法嘛。
    leebs
        21
    leebs  
    OP
       205 天前
    @zmzeng12 另外主要性能影响不在 redis 写入这一边,在 db 数据读取这一边。
    fov6363
        22
    fov6363  
       205 天前
    update_time 建索引,用 update_time 来导数据,只导 update_time > last_sync_time 的数据
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2206 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 12:06 · PVG 20:06 · LAX 05:06 · JFK 08:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.