oceanbase的updateserver服务使用了SAS+SSD的混合存储方式,其中SAS盘用于存储实时记录的操作日志,SSD用于存储定期转储的内存数据。updateserver写操作日志的特点是大量的小块数据追加写,总带宽不大,但是要求1毫秒以下的写延迟,直接使用SAS或SSD都无法满足需求,因此我们为updateserver配备了一块带电池的raid卡,数据写入raid卡的缓存后即向系统返回,再由raid聚集后再写入SAS盘。在线上的配置中,SAS盘和SSD盘都接到同一块raid卡上。

问题说明:

oceanbase在sns feed index机群调高写入压力后,偶尔出现写操作日志用时超长的情况,由于updateserver机器配置了带电池的raid卡,正常情况下数据写入raid卡的buffer即可返回,用时约100us,但是在sns feed index的应用中却出现主备写操作日志用时达到几百毫秒的情况,由于updateserver使用单线程批处理写请求的技术,所以一次写操作日志的超时就会造成后续排队中的写任务延迟都相应增加,短时间内阻塞应用端很多数据的写入。

经过排查发现线上两次出现的这种写超时情况,都伴随同时在执行的updateserver转储任务,通过与内核组高阳同学的多次交流,怀疑转储写SSD的IO影响了写操作日志,造成其延迟增大,在线下部署与线上相同的压力测试环境,sas盘做raid1,2块ssd不做raid,全接到raid卡上,写入模式都为write back,在7500TPS,写操作日志速度约25MB/s,转储写SSD速度约100MB/s的情况下,稳定复现这一问题。

统计测试结果发现,出现超时的概率与ssd的碎片情况有关,在ssd没有经过全盘dd碎片比较多的情况下,写操作日志用时超过50ms的概率为万分之3.2,而对ssd进行一次全盘dd置零之后,仍然会出现写操作日志用时超过50ms的情况,但是概率降低到百万分之1.7。使用megacli将ssd设备的写入模式修改为write through之后,再进行测试连续写入500G数据的情况下,超过50ms的情况出现次数为0。

因此实验数据验证了之前的怀疑,由于写操作日志和转储数据都是write back模式,先放在raid的卡的缓存中,然后异步写到设备中去,由于转储短时间内写数据量比较大,在写满raid卡缓存的情况下,只能阻塞写入,等缓存的数据写到设备中去才能返回,这样缓存就退化成了一个fifo队列,阻塞了写操作日志的IO,特别是在SSD碎片比较多的情况,写SSD变造成raid卡缓存清理耗时变长,写操作日志用时也相应变长。

结论:

1、updateserver使用的机器,上线前需要对raid进行配置,除操作日志盘的写入模式为write back,其他盘需要改为write through

2、ssd盘上线前做一次全盘清理,使用dd即可(dd if=/dev/zero of=[ssd设备文件] bs=4194304)