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

2017-04-20 23:29:46 +08:00
 bccber

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

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

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

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

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

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

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

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

周而复始
bccber
2017-04-21 14:54:46 +08:00
@ryd994 服务 A 从数据库取数据需要 6 分钟 通过服务 B 先生成文件 服务 A 再读取这个文件 只要三秒

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

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

@willakira 是的 和你的做法是一样的 最后只是纠结于 直接把文件的内存加载到物理内存还是直接读取 mmap
willakira
2017-04-22 01:49:41 +08:00
加到内存就可以了

mmap 主要用于进程间通信的文件共享
mengzhuo
2017-04-22 08:00:29 +08:00
我就想问为什么要全部加载?
julyclyde
2017-04-22 09:37:58 +08:00
哈,和我们公司的做法一样
不过我提示一点:加载文件过程期间还是不能服务的
bccber
2017-04-22 18:58:49 +08:00
@mengzhuo 因为内存够大

@julyclyde 我是这样想的 加载文件 也使用 mmap 的方法加载 速度比 IO 快吧 全部加载到物理内存后 就抛弃 mmap
julyclyde
2017-04-22 18:59:52 +08:00
@bccber 总读入量并没节省啊
mengzhuo
2017-04-24 16:43:12 +08:00
@bccber 内存够大的话, Linux 会把磁盘上的数据 cache 的,两者性能应该差别不大的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/356297

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX