一般的缓存系统写文件一般通过下面三种方式来进行完成:
1. 通过文件系统的page cache来进行写缓存;然后就是通过刷脏页的方式将数据写入磁盘;?缺点:数据在传输过程中需要在应用程序地址空间和page cache之间进行多次数据拷贝操作,这些数据拷贝操作所带来的CPU以及内存开销是非常大的。
mmap:如果想直接写page cache,而跳过application buffer和page cache之间的copy,则可以使用mmap;mmap把page cache 地址空间映射到用户空间,应用程序像操作应用层内存一样,写文件。省去了系统调用开销。
2. 通过写缓存+direct io的方式进行写缓存;这样可以减少数据拷贝操作;?
direct io就是绕过page cache,直接将用户空间的buffer内容直接写入磁盘;通过open文件带上O_DIRECT参数,这是write该文件。就是直接写到设备上。
不过由于文件系统的逻辑空间连续并不能代表磁盘物理空间的连续,所以可能产生随机写的情况,导致性能下降;?
3. 直接操作物理空间,可以大大提高性能;可以通过aio+pwrite来进行write操作;?通过write buffer和read buffer提高性能;write buffer一般很小,只保存最近未sync的数据,而read buffer一般很大,保存ram中的数据;
缓存系统在裸盘上一般有索引区和数据区两部分;索引区一般通过mmap来进行文件的读写;数据区一般采用pread/pwrite来进行文件的读写,pread和pwrite通过offset来进行文件的准确定位;
裸设备的读写:
裸设备如何读:?可以通过pread pwrite对裸盘设备进行读写;?fd = open(path, O_DIRECT | O_DSYNC|O_CREAT, 0644);?然后tuncate;?每个disk有一个fd;通过open函数建立一个fd,path是storage里面的path;?每个vol共享disk里面的fd;
文件系统和裸盘的区别:
O_DIRECT 和 RAW设备最根本的区别是O_DIRECT是基于文件系统的。也就是在应用层来看,其操作对象是文件句柄。从内核和文件层来看,其操作是基于inode和数据块,这些概念都是和ext2/3的文件系统相关,写到磁盘上最终是ext3文件。
而RAW设备写是没有文件系统概念,操作的是扇区号,操作对象是扇区,写出来的东西不一定是ext3文件;
一般基于O_DIRECT来设计优化自己的文件模块,是不满系统的cache和调度策略,自己在应用层实现这些,来制定自己特有的业务特色文件读写。
而基于RAW设备的设计系统,一般是不满现有ext3的诸多缺陷,设计自己的文件系统。自己设计文件布局和索引方式。
两者都要通过驱动层读写;在系统引导启动,还处于实模式的时候,可以通过bios接口读写raw设备。
先看一下这个图: