我有服务端 A 每天半夜需要从 mysql 加载大量数据到内存 数据格式大约为 map<int64, set<int32>> 加载完数据大概要 5,6 分钟
如果程序挂逼 也需要花费 5,6 分钟加载数据 相当于会停止服务 5,6 分钟
为了解决这个问题,另外搞了一个小服务 B 作用就是每天半夜把 mysql 的数据生成到内存映射文件(5 个 GB 左右)
服务 A 需要加载数据时就直接加载内存映射文件 速度快 然后服务 A 直接操作内存映射文件
一直运行 也没出过什么错误 但想想 好像没必要使用内存映射文件:
我现在的想法是:服务B生成内存映射文件, 服务A从内存映射文件加载数据物理内存,然后关闭文件
1
trys1 2017-04-20 23:59:45 +08:00 via Android
楼主的技术栈有点窄,完全有其它不同的方案可以满足你怪异的需求,不信你问楼下
|
2
ihuotui 2017-04-21 00:11:20 +08:00 via iPhone
就 nio mmap 就可以了, rocketmq 都是这样做的,看看 mq 的 store 代码
|
3
ihuotui 2017-04-21 00:12:11 +08:00 via iPhone
就是你现在的内存映射文件
|
4
billlee 2017-04-21 00:50:55 +08:00
把这个文件放到 tmpfs, 或者用共享内存 shm_open(3)
|
5
liuqhang 2017-04-21 01:03:50 +08:00
用 redis 应该可以,如果只是想把数据放入内存的话。不是很明白你需求。
|
6
mx1700 2017-04-21 01:21:09 +08:00 via Android
整个加载内存映射文件到内存估计也得几分钟,还是会停止服务
|
7
yidinghe 2017-04-21 08:55:48 +08:00 via Android
内存映射文件也那么大,读取也要耗时间吧。瓶颈在 IO 的话,最好想办法避免 IO 本身
|
8
enenaaa 2017-04-21 09:17:20 +08:00
可以考虑将数据从 mysql 迁移到 redis 上, 或用 redis 代替 B 。
另外保证服务不挂逼更重要 |
9
erobot 2017-04-21 10:02:38 +08:00
感觉你需要的只是要避免 A 对外停止服务,如果内存够,那 A 多开一个线程读数据,读完了后切用新数据,把旧数据释放掉就好了
|
10
erobot 2017-04-21 10:05:27 +08:00
怕 A 读数据影响稳定的话, billlee 提到的共享内存也类似, B 把数据处理好后放内存,通知 A 切换使用新数据
|
11
ryd994 2017-04-21 10:32:21 +08:00
“映射文件只读不修改” 那为什么不做个抽象层直接从数据库取数据?最多套个缓存
|
12
willakira 2017-04-21 10:54:27 +08:00
巧了,我们公司正好就是你这个 case ,但是 producer 有好几百台机器, consumer 在一万台以上,每天 deliver 的数据在 TB 级吧
我们这么做的,以一个 producer 为例 - producer 读取数据库,生成一个压缩的 snapshot - producer 分发种子给 consumer ,然后 consumer 通过 bittorrent 协议(私有云)下载 snapshot - consumer 定期直接加载到内存,只读,不 mmap 。 周而复始 |
13
bccber OP |
14
willakira 2017-04-22 01:49:41 +08:00
加到内存就可以了
mmap 主要用于进程间通信的文件共享 |
15
mengzhuo 2017-04-22 08:00:29 +08:00 via iPhone
我就想问为什么要全部加载?
|
16
julyclyde 2017-04-22 09:37:58 +08:00
哈,和我们公司的做法一样
不过我提示一点:加载文件过程期间还是不能服务的 |
17
bccber OP |