Bbuffer与Cache非常类似,因为它们都用于存储数据数据,被应用层读取字节数据。在很多场合它们有着相同的概念[1]:
首先从翻译上,Buffer应该翻译为“缓冲”,Cache应该翻译为“缓存”,两个完全不是一个东西。在硬件这一层看,Buffer应该为内存,Cache为CPU集成的告诉缓存。Buffer为了让不同速度的设备能够同步,建立的一个缓冲区域,写进Buffer的数据是为了从中拿出写入其他设备。Cache是为了提高读取速度,将经常或马上需要的数据预读到缓存中,写进Cache的数据是为了其他设备从中去读取。从软件这一层来说,Buffer是块设备的缓冲,Cache是文件系统的缓存。以Linux为例,Buffer(BufferCache)以块形式缓冲了块设备的操作,定时或手动的同步到硬盘,它是为了缓冲写操作然后一次性将很多改动写入硬盘,避免频繁写硬盘,提高写入效率。Cache(PageCache)以页面形式缓存了文件系统的文件,给需要使用的程序读取,它是为了给读操作提供缓冲,避免频繁读硬盘,提高读取效率。总而言之,Buffer里面的东西是为了写到别处去,Cache里面的东西是为了给别处读。
Buffer与Cache的用途有所不一定:
Buffer的主要目的是在不同应用、线程、进程之间共享字节数据,例如为了让不同速度的设备能够进行数据同步,就会使用共享Buffer;
Cache的主要目的是提高字节数据的读取/写入速度,例如根据时间局部性、地址局部性操作系统提供pagecache机制;
当然,在很多场合下Buffer与Cache有着相同的语义,因此我们可以认为缓冲区既用于提高读写速度,又用于数据共享与同步。
关于零拷贝深入理解:
二.MySQL缓冲区设计
MySQL的缓冲区设计如下图所示:
Figure1.MySQL的缓冲区设计如上图所示,MySQL在不同层次使用了与缓存机制不同的配套技术。其中有:
应用层:
RedoLogBuffer:对写操作进行缓存,用于实现MySQLInnoDB的事务性;
InnoDBBufferPool:用于对MySQLtable的数据进行缓存。读内存而不是磁盘,通过减少磁盘读操的方式提高读操作性能;写内存而不是磁盘,通过减少磁盘写操的方式提高写操作性能;
操作系统的VFS(Virtualfilesystem,虚拟文件系统)层:
PageCache:操作系统通过缓存以及预读机制对文件系统中的block基于page进行缓存管理;
DirectBuffer:当使用DirectI/O提供的相关API时,操作系统不再提供基于PageCache机制的缓存,而是直接使用DirectBuffer;
磁盘的DiskBuffer:磁盘也可以提供磁盘缓存,通常在MySQL中会关闭磁盘缓存,我们仅仅需要了解有DiskBuffer这一概念即可。
三.WriteThrough/Back与DirectI/O
WriteThrough与WriteBack指的是在使用内存空间作为缓存的应用在处理写操作时是否直接落盘:
WriteThrough:写操作"穿过"缓存区直接落盘,这种策略能够确保数据不会因为宕机而丢失内存缓冲区的数据;
WriteBack:一次写操作仅仅更新了内存缓存区中的数据,数据落盘通常通过间隔一个时间进行落盘一次;
MySQL为此提供了一些参数来控制PageCache数据落盘的具体行为,例如:
(1)innodb_flush_log_at_trx_