共计 3797 个字符,预计需要花费 10 分钟才能阅读完成。
导读 | Buffer 为了让不同速度的设备能够同步,建立的一个缓冲区域,写进 Buffer 的数据是为了从中拿出写入其他设备。 |
Bbuffer 与 Cache 非常类似,因为它们都用于存储数据数据,被应用层读取字节数据。在很多场合它们有着相同的概念:
首先从翻译上,Buffer 应该翻译为“缓冲”,Cache 应该翻译为“缓存”,两个完全不是一个东西。
在硬件这一层看,Buffer 应该为内存,Cache 为 CPU 集成的告诉缓存。
Buffer 为了让不同速度的设备能够同步,建立的一个缓冲区域,写进 Buffer 的数据是为了从中拿出写入其他设备。
Cache 是为了提高读取速度,将经常或马上需要的数据预读到缓存中,写进 Cache 的数据是为了其他设备从中去读取。
从软件这一层来说,Buffer 是块设备的缓冲,Cache 是文件系统的缓存。以 Linux 为例,
Buffer(Buffer Cache)以块形式缓冲了块设备的操作,定时或手动的同步到硬盘,它是为了缓冲写操作然后一次性将很多改动写入硬盘,避免频繁写硬盘,提高写入效率。
Cache(Page Cache)以页面形式缓存了文件系统的文件,给需要使用的程序读取,它是为了给读操作提供缓冲,避免频繁读硬盘,提高读取效率。
总而言之,Buffer 里面的东西是为了写到别处去,Cache 里面的东西是为了给别处读。
Buffer 与 Cache 的用途有所不一定:
关于零拷贝深入理解:
MySQL 的缓冲区设计如下图所示:
如上图所示,MySQL 在不同层次使用了与缓存机制不同的配套技术。其中有:
磁盘也可以提供磁盘缓存,通常在 MySQL 中会关闭磁盘缓存,我们仅仅需要了解有 Disk Buffer 这一概念即可。
Write Through 与 Write Back 指的是在使用内存空间作为缓存的应用在处理写操作时是否直接落盘:
Write Through:写操作 ” 穿过 ” 缓存区直接落盘,这种策略能够确保数据不会因为宕机而丢失内存缓冲区的数据;
Write Back:一次写操作仅仅更新了内存缓存区中的数据,数据落盘通常通过间隔一个时间进行落盘一次;MySQL 为此提供了一些参数来控制 Page Cache 数据落盘的具体行为,例如:
innodb_flush_log_at_trx_commit 参数用于控制基于 Page Cache 的 Redo Log Buffer 的数据落盘机制[2]。此参数用于控制以下两个特性之间的平衡:
innodb_flush_log_at_trx_commit 有三个可选配置值:
刷新频率默认为 1 s,由参数 innodb_flush_log_at_timeout 进行配置。
innodb_flush_method 参数同时控制 redo log buffer 和 innodb buffer pool 缓冲区刷新策略,其中:
nosync 这里只讨论 Unix-like 操作系统,而不讨论 Windows 系统。
其中,littlesync 与 nosync 仅仅用于内部性能测试,并不建议使用。
补充说明:以 O_SYNC 方式打开文件意味着文件的每一次写操作都直接导致将数据本身以及元数据刷新到磁盘上。
为什么有 O_DIRECT 与 O_DIRECT_NO_FSYNC 配置的区别?
首先,我们需要理解更新操作落盘分为两个具体的子步骤:①文件数据更新落盘②文件元数据更新落盘。O_DIRECT 的在部分操作系统中会导致文件元数据不落盘,除非主动调用 fsync,为此,MySQL 提供了 O_DIRECT 以及 O_DIRECT_NO_FSYNC 这两个配置[5]。
如果你确定在自己的操作系统上,即使不进行 fsync 调用,也能够确保文件元数据落盘,那么请使用 O_DIRECT_NO_FSYNC 配置,这对 MySQL 性能略有帮助。否则,请使用 O_DIRECT,不然文件元数据的丢失可能会导致 MySQL 运行错误。
MySQL 日志刷新策略通过 sync_binlog 参数进行配置,其有 3 个可选配置:
注意事项:使用 Page Cache 机制的数据刷盘机制,即使基于同步策略,即每次写操作都要求数据直接落盘,但在数据落盘之前,数据总是先要写于 Page Cache 中,再将 Page Cache 中的具体 Page 刷新到磁盘上。
写一条 redo log 涉及到的步骤有:
修改表的一行记录涉及到的步骤有:
