读高性能MySQL(第4版)笔记04_操作系统和硬件优化

1. 从软件本身和它运行的典型工作负载来看,MySQL通常也更适合运行在廉价硬件上

2. 基本资源

2.1. CPU

2.2. 内存

2.3. 磁盘

2.4. 瓶颈

2.5. 网络资源

3. CPU

3.1. 最常见的瓶颈是CPU耗尽

3.2. 检查CPU使用率来确定工作负载是否受CPU限制

3.3. 低延迟(快速响应时间)

3.3.1. 需要更快的CPU,因为每个查询将只使用一个CPU

3.4. 高吞吐量

3.4.1. 如果可以同时运行多个查询,那么可以使用多个CPU为查询提供服务

4. 内存

4.1. 内存耗尽的情况也会发生,但通常只在你试图将太多内存分配给MySQL时才会发生

4.2. 配置大内存的主要原因并不是为了在内存中保存大量数据,而是为了避免磁盘I/O

4.3. 磁盘I/O比访问内存中的数据要慢几个数量级

4.4. 如果有足够的内存,可以完全避开磁盘读取操作

4.5. 如果所有数据都能装入内存,那么一旦服务器的缓存预热完成,每次读取都将是一次缓存命中

4.6. 写入可以像读取一样在内存中执行,但迟早必须被写入磁盘,才能持久保留数据

4.7. 缓存可以延迟写操作,但缓存不能像消除读操作那样消除写操作

4.8. 多次写操作,一次刷新

4.8.1. 一个数据片段可以在内存中被多次更改,而无须每一次都将新值写入磁盘

4.8.2. 当数据被最终刷新到磁盘时,自上次物理写入以来发生的所有修改都将被持久化

4.9. I/O合并

4.9.1. 许多不同的数据片段可以在内存中被修改,这些修改可以被收集在一起,因此物理写可以作为单个磁盘操作执行

4.9.2. 提前写日志(write-ahead logging)策略

4.9.2.1. 允许在内存中更改页面,而不用将更改刷新到磁盘,这通常涉及随机I/O,速度非常慢

4.9.2.2. 将更改的记录写入顺序日志文件,这样要快得多

4.9.2.3. 后台线程可以稍后将修改过的页面刷新到磁盘,这样做可以优化写操作的性能

4.10. 写操作从缓冲中获益,因为可以将随机I/O转换为顺序I/O

4.11. 异步(缓冲)写操作通常由操作系统处理,并且是被成批处理的,因此可以更优地被刷新到磁盘

4.12. 同步(无缓冲)写入必须等待数据落盘

5. 固态(闪存)存储

5.1. I/O饱和也会发生,但比CPU耗尽的频率低得多

5.2. 用HDD硬盘时,最好尝试找到一个有效的内存/磁盘比率

5.2.1. HDD延迟较高、IOPS较低

5.3. 使用SSD时,内存对磁盘的比率就变得不那么重要了

5.4. 固态设备对于提高服务器整体性能非常有用,现在通常应该成为数据库的标准配置,尤其对于OLTP工作负载

5.4.1. SSD通常比HDD快10到20倍

5.4.2. 只有在预算极为有限的系统中,或者在需要惊人的高达数PB的磁盘空间的数据仓库场景下,才考虑继续使用HDD

5.5. 比硬盘驱动器明显更好的随机读写性能

5.6. 闪存设备读的能力通常略好于写的能力

5.7. 比硬盘驱动器更好的顺序读写性能

5.8. 比硬盘驱动器更好的并发支持

5.8.1. 只有在拥有大量并发性的情况下,闪存设备才能真正实现最高吞吐量

5.9. 固态存储设备使用非易失性闪存芯片组成的单元

5.9.1. 非易失随机访问内存(NVRAM)

5.10. 固态存储建立在闪存之上

5.11. 闪存的特点

5.11.1. 可以被快速地多次读取,而且以很小的单元读取数据

5.11.2. 写入则要困难得多

5.11.2.1. 只有进行特殊的擦除操作之后,存储单元才能被重新写入数据,并且每次擦除的块大小较大

5.12. 写操作的限制是固态存储复杂性的原因

5.12.1. 为了使写操作能够很好地执行,并避免过早地耗尽闪存块写寿命,设备必须能够重新定位页面,并执行垃圾收集和所谓的损耗均衡

5.13. 为了使某些块保持新鲜并为新的写入做好准备,设备会回收块

5.14. 100GB文件在160GB的SSD上的性能与在320GB的SSD上的性能是不同的

5.14.1. 当没有空闲块时,必须等待擦除操作完成,从而导致速度减慢

5.14.2. 写入空闲块需要几百微秒,但擦除速度要慢得多,通常需要几毫秒

6. RAID

6.1. 存储引擎通常将数据/索引保存在单个大文件中,这意味着RAID通常是存储大量数据的最佳选项

6.2. 不要认为RAID是数据安全方面的强有力的保证

6.2.1. RAID并不能消除,甚至不能减少备份的需要

6.3. 保存在损坏的物理媒介中的数据很少被访问,可能几个月都不会被发现,直到尝试读取数据,或者当另一个驱动器出现故障,RAID控制器尝试使用损坏的数据重建阵列时才发现问题

6.3.1. 硬盘空间越大,出现这种情况的可能性就越大

6.4. 大多数控制器都提供了一些软件来报告阵列的状态,你需要对此进行跟踪,否则可能完全不知道驱动器已出现故障

6.4.1. 到第二个驱动器出现故障时就太晚了

6.5. 通过定期主动检查阵列的一致性,可以降低潜在的损坏风险

6.6. 很多RAID控制器不能很好地处理大数据块

6.7. RAID缓存是物理安装在硬件RAID控制器上的(相对)少量内存

6.7.1. 在RAID缓存中缓存读取都是浪费内存

6.8. RAID控制器的内存是一种稀缺资源,应该明智地使用它

6.9. 对事务日志发出fsync()调用,并在启用sync_binlog的情况下创建二进制日志,但除非控制器有备用电池单元(BBU)或其他非易失性存储,否则不应启用写缓存

6.9.1. 硬盘也可能会撒谎。应该确保在fsync()时刷新缓存,或者干脆在没有备用电池时禁用它们

6.9.2. 当安装新硬件时,最好进行真正的暴力碰撞测试(例如把电源插头拔出来)。这通常是发现细微的错误配置或偷偷摸摸的硬盘行为的唯一方法

6.10. 要测试RAID控制器的BBU是否真的可靠,请确保将电源线拔下一段时间

6.10.1. 有些BBU设备在没电的情况下无法维持足够的时间(将RAID缓存的数据刷新到磁盘

6.10.2. 一个环节出问题可能会导致整个存储系统链变得无用

6.11. RAID 0

6.11.1. 最便宜和性能最好的RAID配置

6.11.2. 永远不适合用于生产数据库

6.11.3. 在开发环境中,当服务器完全失效也不会变成突发事件时,可以选择RAID 0

6.11.4. 不提供任何冗余

6.11.5. RAID 0阵列的故障概率高于任何单磁盘的故障概率,而不是更低

6.12. RAID 1

6.12.1. 良好的读性能,并且可以跨磁盘复制数据

6.12.2. 良好的冗余

6.12.3. 读取速度略高于RAID 0

6.12.4. 顺序写入不需要许多底层磁盘就能执行得很好

6.12.5. 需要冗余但只有两个硬盘驱动器的低端服务器的典型选择

6.12.6. 大多数操作系统都允许你轻松地创建软件RAID 0和RAID 1卷

6.13. RAID 5

6.13.1. 将数据分布在具有分布式奇偶校验块的多块磁盘上,以便在任何一块磁盘出现故障时,可以从奇偶校验块重建数据

6.13.2. 如果两块磁盘同时出现故障,整个卷将无法恢复

6.13.2.1. 丢失两块磁盘时会产生灾难性的后果

6.13.3. RAID 5的可伸缩性不能超过10块磁盘

6.13.4. 良好的RAID 5的性能在很大程度上依赖于RAID控制器的缓存,这可能与数据库服务器的需求相冲突

6.14. RAID 6

6.14.1. 允许你在承受两次磁盘故障的情况下仍然能重建阵列

6.14.2. 计算额外的奇偶校验会使写操作比RAID 5慢

6.15. RAID 10

6.15.1. 一个非常好的数据存储选择

6.15.2. 条带化的镜像对组成,因此在读写方面都能很好地被扩展

6.15.2.1. 最佳的条带块大小取决于工作负载和硬件

6.15.2.2. 对于随机I/O来说,拥有较大的块大小是很好的,因为这意味着可以从单个驱动器中满足更多的读取需求

6.15.3. 与RAID 5相比,它的重建速度快且容易

6.15.4. 以很好地在软件中被实现

6.16. RAID 50

6.16.1. 由条带化的RAID 5阵列组成,如果有很多磁盘,它可以很好地兼顾RAID 5的经济性和RAID 10的性能

6.16.2. 主要用于非常大的数据集,如数据仓库或非常大的OLTP系统

7. 网络

7.1. 延迟和带宽是网络连接的限制因素

7.2. 网络运行不正常是主要的性能瓶颈

7.3. 数据包丢失是一个常见的问题

7.3.1. 即使是1%的丢失也足以导致性能显著下降,因为协议栈中的各个层都会尝试通过等待一段时间然后重新发送数据包等策略来解决问题,这会增加额外的响应时间

7.4. DNS解析异常中断或缓慢成为一个致命弱点

7.4.1. 对于生产服务器来说,启用skip_name_resolve是一个好主意

7.4.2. 当MySQL收到连接请求时,它会同时进行正向和反向DNS查找

7.4.3. 如果启用skip_name_resolve选项,MySQL不会进行任何DNS查找

7.4.3.1. 意味着用户账号在host列中只能有IP地址、“localhost”或IP地址通配符

7.4.3.2. host列中包含主机名的任何用户账号都将无法登录

8. 文件系统

8.1. 文件系统是在数据库中保证数据完整性的最低层

8.2. Windows

8.2.1. 只有一个(NTFS)是真正可行的

8.3. GNU/Linux

8.3.1. 大多数时候,给定的文件系统跟其他文件系统相比不会有明显的差别

8.3.2. 只有在某些情况下,达到文件系统的处理极限时,例如,需要处理高并发性、处理许多文件、碎片,等等,不同文件系统的差异才会体现出来

8.3.3. 最好使用日志型文件系统,如ext4、XFS或ZFS

8.3.4. 建议使用XFS文件系统,并将交换率和磁盘队列调度器设置为适合于服务器的值

8.4. 磁盘队列调度器

8.4.1. 完全公平排队,即CFQ(Complete FairQueuing)

8.4.2. 在MySQL的工作负载类型下,CFQ会导致非常糟糕的响应时间,因为会不必要地阻塞队列中的一些请求

8.4.3. 不要使用CFQ,它可能会导致严重的性能问题

8.5. 内存和交换

8.5.1. 给MySQL分配大量内存后,它的表现最好

8.5.2. InnoDB使用内存作为缓存来避免磁盘访问

8.5.2.1. 意味着内存系统的性能会直接影响查询的速度

8.5.3. 当使用SSD时,性能损失不像使用HDD时那样明显

8.5.3.1. 仍然应该积极地避免交换,即使只是为了避免不必要的写操作,因为写操作可能会缩短磁盘整体寿命

8.5.4. 更改存储引擎读写数据的方式

8.5.4.1. 设置innodb_flush_method=O_DIRECT可以减轻I/O压力

8.5.4.2. 该参数仅对InnoDB有效

8.6. 很多技巧都是特定于内核版本的,所以要小心,特别是在升级时

8.7. Linux剖析器perf是一个非常有用的工具,可以用它来检查操作在系统级别发生的事情

热门相关:倾心之恋:总裁的妻子   网游三国之城市攻略   重生成偏执霍少的小仙女   宠物小精灵之庭树   网游三国之城市攻略