最近在做迁移工作,从hdfs迁移到我司的分布式文件系统,但是我也是非常无语,我司文件系统竟然没有做预读。。对于大量顺序读的场景,这个是非常吃亏的。对于跨机房场景,原Hdfs可达到100M+/s的读速度,但是现在却仅有几十M/s。对于这个问题,等待底层文件系统添加预读确实是最根本的解决方法,但是面对发布时间周期长,排期封板等问题,我们就打算在自己的插件上先简单实现预读功能。
其实看上去功能比较简单,但是实际做上去还是踩了不少坑的。设计思路是:
发异步小IO size同时进行异步顺序预读,在回调中设置是否接着预读,并notify主线程,写好需要填充的Buffer,当主线程完成需要填好的buffer,结束本次预读。
在设计中需要注意:
1. 因为是写完了就继续下发下一次的预读,当主线程完成所需要填好的buffer之后,可能还有flying的请求,要等待所有的预读请求都返回。
2.基本知识,condition variable在 wait的时候会挂起,释放锁,所以一把锁,既保证condition variable又保证一些变量就足够了,简化设计。
3.锁的释放:一定要注意锁的释放时机。实际中,我们一个异步item一直卡在notify_one,原因就是为了防止死锁,锁过早的释放,导致item被上层析构,notify失败。