V2EX 首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐书目
黑客与画家
REWORK 简体中文版
REWORK 精装原版
深入浅出设计模式 Head First Design Patterns
代码之美 Beautiful Code
数据之美 Beautiful Data
信息论、编码与密码学
Free as in Freedom
设计原本
精通正则表达式
V2EX  ›  程序员

我这个服务端 有必要使用内存映射文件吗?

  •  
  •   bccber · 4 天前 · 982 次点击

    我有服务端 A 每天半夜需要从 mysql 加载大量数据到内存 数据格式大约为 map<int64, set<int32>> 加载完数据大概要 5,6 分钟

    如果程序挂逼 也需要花费 5,6 分钟加载数据 相当于会停止服务 5,6 分钟

    为了解决这个问题,另外搞了一个小服务 B 作用就是每天半夜把 mysql 的数据生成到内存映射文件(5 个 GB 左右)

    服务 A 需要加载数据时就直接加载内存映射文件 速度快 然后服务 A 直接操作内存映射文件

    一直运行 也没出过什么错误 但想想 好像没必要使用内存映射文件:

    1. 映射文件只读不修改
    2. 数据只有 5G 左右,完全可以放到物理内存

    我现在的想法是:服务B生成内存映射文件, 服务A从内存映射文件加载数据物理内存,然后关闭文件

    19 回复  |  直到 2017-04-24 16:43:12 +08:00
        1
    trys1   4 天前 via Android
    楼主的技术栈有点窄,完全有其它不同的方案可以满足你怪异的需求,不信你问楼下
        2
    ihuotui   4 天前 via iPhone
    就 nio mmap 就可以了, rocketmq 都是这样做的,看看 mq 的 store 代码
        3
    ihuotui   4 天前 via iPhone
    就是你现在的内存映射文件
        4
    billlee   4 天前
    把这个文件放到 tmpfs, 或者用共享内存 shm_open(3)
        5
    liuqhang   4 天前
    用 redis 应该可以,如果只是想把数据放入内存的话。不是很明白你需求。
        6
    mx1700   4 天前 via Android
    整个加载内存映射文件到内存估计也得几分钟,还是会停止服务
        7
    yidinghe   4 天前 via Android
    内存映射文件也那么大,读取也要耗时间吧。瓶颈在 IO 的话,最好想办法避免 IO 本身
        8
    enenaaa   4 天前
    可以考虑将数据从 mysql 迁移到 redis 上, 或用 redis 代替 B 。
    另外保证服务不挂逼更重要
        9
    erobot   4 天前
    感觉你需要的只是要避免 A 对外停止服务,如果内存够,那 A 多开一个线程读数据,读完了后切用新数据,把旧数据释放掉就好了
        10
    erobot   4 天前
    怕 A 读数据影响稳定的话, billlee 提到的共享内存也类似, B 把数据处理好后放内存,通知 A 切换使用新数据
        11
    ryd994   4 天前
    “映射文件只读不修改” 那为什么不做个抽象层直接从数据库取数据?最多套个缓存
        12
    willakira   4 天前
    巧了,我们公司正好就是你这个 case ,但是 producer 有好几百台机器, consumer 在一万台以上,每天 deliver 的数据在 TB 级吧
    我们这么做的,以一个 producer 为例
    - producer 读取数据库,生成一个压缩的 snapshot
    - producer 分发种子给 consumer ,然后 consumer 通过 bittorrent 协议(私有云)下载 snapshot
    - consumer 定期直接加载到内存,只读,不 mmap 。

    周而复始
        13
    bccber   4 天前
    @ryd994 服务 A 从数据库取数据需要 6 分钟 通过服务 B 先生成文件 服务 A 再读取这个文件 只要三秒

    @erobot 如果服务 A 不挂逼 多开一个线程加载数据 是可以的 如果挂了 需要花 6 分钟加载数据

    @enenaaa redis 不合适 或者说没必要再用 redis 多加一层网络的消耗

    @willakira 是的 和你的做法是一样的 最后只是纠结于 直接把文件的内存加载到物理内存还是直接读取 mmap
        14
    willakira   3 天前
    加到内存就可以了

    mmap 主要用于进程间通信的文件共享
        15
    mengzhuo   3 天前 via iPhone
    我就想问为什么要全部加载?
        16
    julyclyde   3 天前
    哈,和我们公司的做法一样
    不过我提示一点:加载文件过程期间还是不能服务的
        17
    bccber   2 天前
    @mengzhuo 因为内存够大

    @julyclyde 我是这样想的 加载文件 也使用 mmap 的方法加载 速度比 IO 快吧 全部加载到物理内存后 就抛弃 mmap
        18
    julyclyde   2 天前
    @bccber 总读入量并没节省啊
        19
    mengzhuo   23 小时 55 分钟前
    @bccber 内存够大的话, Linux 会把磁盘上的数据 cache 的,两者性能应该差别不大的。
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1987 人在线   最高记录 2466   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.7.5 · 48ms · UTC 08:38 · PVG 16:38 · LAX 01:38 · JFK 04:38
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1