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

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

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

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

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

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

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

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

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

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