spark 落盘doris 落盘数是什么意思_linux

背景

最近在遇到了一个非常奇怪的现象:
程序修改了配置文件中的参数,程序退出之后。cat 配置文件,发现文件内容修改成功。但是断电重启之后,概率性出现配置文件为空或者是配置未修改(概率较大)。
通过简单的思考,判断方向大致如下:

1. 和之前mount 顺序有关,可参考之前的一篇博客mount顺序导致读写不一致问题。通过简单的排查,确定不是这个问题,如果是mount顺序的问题,应该是必现才对。

2. 重启前或重启过程中一些进程对该配置文件进行了修改。因为我是断电重启的,所以应该不是重启前的问题。那么就极有可能是重启过程中,部分进程对该配置文件进行了修改。通过代码的查找,的确发现了一个进程可能会导致这个现象。在systemd中将该进程设置为不启动。尝试了几次,问题依旧存在。

3. 巧合之下,我用vi去修改这个配置文件,重启之后,发现一样会存在这个问题。在修改之后,执行sync,就是ok的了。让我想到了数据同步机制,以前了解,数据不是直接写到磁盘,而是先写到buff中,再到磁盘。但是由于接触到这类问题较少,未成完整的知识的体系。于是搜索了相关资料,进行总结。

数据落盘

在很多的场景中,我们经常要确保数据已经安全的写到磁盘,以便在系统宕机或重启之后还能读到这些数据。但是我们知道,linux系统的IO路径很复杂,并且分为很多层,每一层可能都会有buffer来加速IO读写。因此,想要将数据安全的写到磁盘,并不是简单调一个write/fwrite就可以搞定的。

先对该类问题进行一个直观感受:

spark 落盘doris 落盘数是什么意思_linux_02


对于上面的代码,我相信有经验的人,已经知道结果。但是没吃过亏的,可能就会发出灵魂拷问:每隔1秒打印一次?

spark 落盘doris 落盘数是什么意思_linux_03


实际上是它会卡在这里,不输出。但是过了一会(大约93秒)就会全部输出,至于为什么,可以研究下,原因也是很简单的。

分析:
我们首先要知道标准输入和标准输出是行缓冲。行缓冲的特点就是:先将数据保存到缓冲区,遇到换行符才会将数据进程写磁盘或者是缓冲区满了。我们上面demo,过了一会全部输出,就是后者。

拓展:
有了行缓冲,我们再介绍一下无缓冲全缓冲
无缓冲:代表的就是标准错误输出,fd=2。它会直接写入,不会保存到缓冲区中
全缓冲:对普通文件进行fputs,fprintf操作时,数据并没有直接写道磁盘。只有当缓冲区满了,或者手动调用fflush或fclose时。缓冲区的数据才会写到磁盘。我遇到的问题就是属于该类。

盗一个经典的图:

spark 落盘doris 落盘数是什么意思_重启_04


由上图可知应用层和内核都有缓冲区,经过层层关卡,最终才能写入磁盘或存储介质中。

总结

我们知道想要将数据安全的写到磁盘,并不是一件容易的事情。他可能停留在用户层的缓冲区,也有可能停留在内核的缓冲区。因此,我们在编程中要有主动同步数据的良好习惯。

安全的编程方式:
fopen() -> fflush() -> fsync() -> fclose()

若我的内容对您有所帮助,还请关注我的公众号。不定期分享干活,剖析案例,也可以一起讨论分享。

我的宗旨:

踩完您工作中的所有坑并分享给您,让你的工作无bug,人生尽是坦途