我这个服务端 有必要使用内存映射文件吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
bccber
V2EX    程序员

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

  bccber 2017-04-20 23:29:46 +08:00 3914 次点击
这是一个创建于 3164 天前的主题,其中的信息可能已经有所发展或是发生改变。

我有服务端 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
trys1
    1
trys1  
   2017-04-20 23:59:45 +08:00 via Android
楼主的技术栈有点窄,完全有其它不同的方案可以满足你怪异的需求,不信你问楼下
ihuotui
    2
ihuotui  
   2017-04-21 00:11:20 +08:00 via iPhone
就 nio mmap 就可以了, rocketmq 都是这样做的,看看 mq 的 store 代码
ihuotui
    3
ihuotui  
   2017-04-21 00:12:11 +08:00 via iPhone
就是你现在的内存映射文件
billlee
    4
billlee  
   2017-04-21 00:50:55 +08:00
把这个文件放到 tmpfs, 或者用共享内存 shm_open(3)
liuqhang
    5
liuqhang  
   2017-04-21 01:03:50 +08:00
用 redis 应该可以,如果只是想把数据放入内存的话。不是很明白你需求。
mx1700
    6
mx1700  
   2017-04-21 01:21:09 +08:00 via Android
整个加载内存映射文件到内存估计也得几分钟,还是会停止服务
yidinghe
    7
yidinghe  
   2017-04-21 08:55:48 +08:00 via Android
内存映射文件也那么大,读取也要耗时间吧。瓶颈在 IO 的话,最好想办法避免 IO 本身
enenaaa
    8
enenaaa  
   2017-04-21 09:17:20 +08:00
可以考虑将数据从 mysql 迁移到 redis 上, 或用 redis 代替 B 。
另外保证服务不挂逼更重要
erobot
    9
erobot  
   2017-04-21 10:02:38 +08:00
感觉你需要的只是要避免 A 对外停止服务,如果内存够,那 A 多开一个线程读数据,读完了后切用新数据,把旧数据释放掉就好了
erobot
    10
erobot  
   2017-04-21 10:05:27 +08:00
怕 A 读数据影响稳定的话, billlee 提到的共享内存也类似, B 把数据处理好后放内存,通知 A 切换使用新数据
ryd994
    11
ryd994  
   2017-04-21 10:32:21 +08:00
“映射文件只读不修改” 那为什么不做个抽象层直接从数据库取数据?最多套个缓存
willakira
    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 。

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

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

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

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

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

@julyclyde 我是这样想的 加载文件 也使用 mmap 的方法加载 速度比 IO 快吧 全部加载到物理内存后 就抛弃 mmap
julyclyde
    18
julyclyde  
   2017-04-22 18:59:52 +08:00
@bccber 总读入量并没节省啊
mengzhuo
    19
mengzhuo  
   2017-04-24 16:43:12 +08:00
@bccber 内存够大的话, Linux 会把磁盘上的数据 cache 的,两者性能应该差别不大的。
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     901 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 28ms TC 20:31 PVG 04:31 LAX 12:31 JFK 15:31
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86