linux结构
基本结构
VFS层
就是看你对哪个目录中的文件执行的磁盘io操作,把io请求交给具体的文件系统
Page Cache
在这个page cache 基于内存的缓存里找你要的数据在不在里面,如果有就基于内存缓存来执行读写,如果没有就继续往下一层走,此时这个请求会交给通用的block层,在这一层会把你对文件的io请求转换为Block IO请求
IO调度层
这一层里默认的是用CFQ公平调度算法,也就是说,可能有两个sql请求同时过来,一个比较简单,只是更新磁盘的一个block的数据就可以了,另外一个是读取一个表中的所有数据,如果基于这个默认的CFQ算法,就会让读全表的这个sql先执行,更新一个条数据的sql等到读全表的sql全部执行结束之后才能执行。这样会导致明明应该先执行简单地操作,结果复杂的反而先执行了,不符合我们的预期
于是,在mysql的生产环境,建议采用deadline iO调用算法。它的一个核心思想就是,任何一个IO操作都能不能一直不停的等待,在指定范围内,都必须让他去执行
Block 设备驱动层
Io调度层决定了哪个io请求先执行,哪个io请求后执行,此时可以执行的io请求就会交给Block设备驱动层,经过驱动把iO请求发送给真正的存储硬件,也就是Block设备层
RAID
第一种、项目的数据读写十分频繁,然后对可靠性要求很高,那这时候毫无疑问肯定选择RAID10了,但是付出的代价也就高了,不过一般这么选择的用户眼都不会眨一下,类似银行,你懂的。
第二种、项目的数据读十分频繁,写则较少一些,然后可靠性有一定要求但不是很高,那么可以选择RAID5,这应该是一种存储性能、数据安全和存储成本兼顾的存储解决方案了,也可以理解为是RAID 0和RAID 1的折中方案。
第三种、项目的读写都十分频繁,但是可靠性要求不高,主要用于内部这种,可以选择RAID0。
充放电
服务器使用功能多快磁盘组成的RAID阵列的时候,一般会有一个RAID卡,这个RAID卡是带有一个缓存,这个缓存不是直接用我们的服务器的那种模式,他是一种跟内存类似的SDRAM,当然,你大致就认为它也是基于内存来存储的吧
然后我们可以把RAID的缓存模式设置为write back,这样 的话,所有写入到磁盘阵列的数据,都先会缓存在RAID卡的缓存里,后续慢慢再写入到磁盘阵列里去,这种写缓冲机制,可以大幅度提升我们的数据库磁盘写的性能
有了缓存我们很容易就会想到一个问题,就是比如数据写到了RAID卡的缓存中,机器突然宕机了,那么数据不就丢失了吗?其实正是因为如此,RAID卡一般都有配置自己独立的锂电池或者电容,如果服务器突然掉电了,无法接通电源了,RAID卡自己是基于锂电池供电运行的,然后它会赶紧把缓存里面的数据写入到阵列的磁盘上去
但是锂电池是存在性能衰减的问题的,所以一般来说锂电池都是要配置定时充放电的,也就是说每隔30天-90天(不同的锂电池厂商是不一样的),就会自动对锂电池进行放电一次,这样可以延长锂电池的寿命和校验电池容量。
如果不这样做,可能锂电池中存储的电量不够,在机器突然掉电的情况,锂电池中的电量不足以支撑将缓存中的数据全部刷新到磁盘上,就还是会造成数据丢失的现象
所以在锂电池充放电的过程中,RAID的缓存界别会从wirte back变成 write through,我们通过RAID写数据的时候,IO就直接写磁盘了,如果写内存和写磁盘相比的话,写内存的效率会比写磁盘的效率高上数十倍
生产建议:开启RAID卡的缓存,需要对锂电池的自动充放电的问题进行思考,防止由于锂电池定时的充放电造成系统的数据库每隔一段时间就会造成性能几十倍的抖动