Kinbase ES 优化之IO优化

IO 资源作为目前服务器中最昂贵的资源之一,是目前绝大部分业务系统主要的瓶颈资源,原因就在于服务器相关的硬件资源中IO资源的性能提升是难度最大的。存储的发展步伐远低于内存和CPU的发展。

在数据库管理系统中,IO是十分宝贵的,所以在数据库管理系统中我们希望操作尽可能在内存中完成,如果在一次事务中发生过多的IO就意味着性能的下降。

所以如何保证IO资源的性能最大化也是数据库管理系统优化的重中之重。目前数据库IO调优的主要思路是1、延迟IO,降低频繁IO到来的资源 ,包括使用缓冲池资源等 一次IO中代价最高的部分是寻址所以通过延迟IO可以减少寻址的次数从而提升性能。2、并发,提高一次IO写入的数据量,减少了IO次数,但是总的需要写入的数据量没有减少,这就要求在一次IO中尽可能对的写入数据保证该落盘的落盘。

Kinbase ES 提供了多种IO 资源的优化手段包括:

• 优化数据库内存参数

• 调整 IO 调度策略

• 利用多 IO 设备分担压力

• 优化文件系统挂载方式

• 配置预读 IO 请求队列

优化数据库 I/O 相关参数

fsync

原理:用来设置日志缓冲区刷盘时, 需要确认已经将其写入了磁盘。

如果关闭该功能,那么由操作系统调度 磁盘写的操作, 能更好利用缓存机制, 提高 IO 性能。该性能的提高伴随了数据丢失的风险, 当操作系统或主机 崩溃时, 不保证刷出的日志是否真正写入了磁盘。 应用范围:应依据操作系统和主机的稳定性来配置,一般在追求极限性能是修改。

full_page_writes

原理:full_page_writes (boolean),打开这个选项的时候, 数据库服务器在检查点 (checkpoint) 之后对页面的第 一次写入时将整个页面写到 WAL 里面。这么做是因为在操作系统崩溃过程中可能只有部分页面写入磁盘,

从而导致在同一个页面中包含新旧数据的混合。在崩溃后的恢复期间, 由于在 WAL 里面存储的信息不够完 整, 无法完全恢复该页。把完整的页面影像保存下来就可以保证正确存储页面, 代价是增加了写入 WAL 的数 据量。因为 WAL 重放总是从一个检查点开始的, 所以在检查点后每个页面第一次改变的时候做 WAL 备份就 足够了。因此, 一个减小全页面写开销的方法是增加检查点的间隔参数值。把这个选项关闭会加快正常操作 的速度, 但是可能导致系统崩溃或者掉电之后的数据库损坏, 它的危害类似关闭 fsync , 只是比较小而已。 应用范围:关闭可以改善性能,但是需要一定条件,如果有减小部分页面写入风险的硬件支持 (比如电池供 电的磁盘控制器) 或者文件系统支持 (比如 ReiserFS 4), 并且他们可以把风险降低到一个可以接受的低范畴, 那 么可以关闭这个选项。如果为了极限性能,并且是 IO 的问题,可以考虑使用。

commit_delay

原理:事务提交和日志刷盘的时间间隔,

应用范围:如果并发的非只读事务数目较多, 可以适当增加该值, 使日志缓冲区一次刷盘可以刷出较多的事 务, 减少 IO 次数, 提高性能。需要和 commit_sibling 配合使用。

commit_siblings

原理:触发 commit_delay 的并发事务数, 只有系统的并发活跃事务数达到了该值, 才会等待 commit_delay 的时 间将日志刷盘, 如果系统中并发活跃事务达不到该值,commit_delay 将不起作用, 防止在系统并发压力较小的 情况下, 事务提交后空等其他事务造成时间的浪费。 应用范围:应根据系统写的负载配置,并发越大就配置越大,和 commit_delay 一起使用。

checkpoint_timeout

原理:两个相邻检查点之间的时间间隔,用于刷数据到磁盘。 应用范围:根据系统写的负载设置, 一般不要太频繁。可以和后台写线程配置相关参数配合使用,一般 pk 测 试过程中会设置的很长(如果内存够的话),可以不用频繁刷。

bgwriter_delay

原理:后台写线程的自动执行时间, 后台写线程的作用是将 shared_buffer 里的脏页面写回到磁盘, 减少

checkpoint 的压力。默认是 200ms。 应用范围:如果系统数据修改的压力一直很大, 建议将该时间间隔设置小一些, 以免积累的大量的脏页面到

checkpoint, 使 checkpoint 时间过长 (checkpoint 期间系统响应速度较慢)。tpcc 一般设置 10ms 可以减少压力;

bgwriter_lru_maxpages

原理:后台写线程一次写出的脏页面数,默认 100 个页面。 应用范围:依据系统写的负载修改,比如 tpcc,因为时间间隔短,一次写入的少页面少,比如设置 75。

bgwriter_lru_multiplier

原理:后台写线程根据最近服务线程需要的 buffer 数量乘上这个比率估算出下次服务线程需要的 buffer 数量,

再使用后台写进程写回脏页面, 使缓冲区能使用的干净页面达到这个估计值。默认是 2.0

应用范围:应根据系统写负载来配置。

调整 IO 调度策略

采用合适的磁盘调度算法,IO 调度策略一般包括:CFQ,Deadline,NOOP 和 Anticipatory 。 对于机械磁盘来说,deadline 是数据库的最佳选择,比如 tpcc 一般采用 deadline。固态硬盘一般可以不做调整。

调度算法包括

1. CFQ

原理:公平算法原则,对于通用服务器来说通常是最好的选择。它试图均匀地分布对 I/O 带 宽的访问。在多媒体应用, 总能保证 audio、video 及时从磁盘读取数据。同时对于其他各类应 用表现也很好。每个进程一个 queue,每个 queue 按照上述规则进行 merge 和 sort。进程之间

round robin 调度,每次执行一个进程的 4 个请求。 应用范围:默认算法,适用于大部份系统应用,适用于 io 大小非常均匀的场景

2. Deadline

原理:这个算法试图把每次请求的延迟降至最低。该算法重排了请求的顺序来提高性能。使 用轮询的调度器, 简洁小巧, 提供了最小的读取延迟和高的吞吐量。 应用范围:适合小文件读写,跳跃式读写,零散读写,特别适合于读取较多的环境,稍微复 杂点的 OLTP 最好更换为 Deadline

3. NOOP

原理:这个算法实现了一个简单 FIFO 队列。他假定 I/O 请求由驱动程序或者设备做了优化 或者重排了顺序 (就像一个智能控制器完成的工作那样)。 应用范围:在有些 SAN 环境下,这个选择可能是最好选择。适用于随机存取设备, no seek cost,非机械可随机寻址的磁盘。I/O 性能不是瓶颈的时候使用 NOOP,也适用于带有 TCQ

的磁盘。

4. Anticipatory

原理:这个算法推迟 I/O 请求,希望能对它们进行排序,获得最高的效率。同 deadline 不同 之处在于每次处理完读请求之后, 不是立即返回, 而是等待几个微秒,在这段时间内, 任何来 自临近区域的请求都被立即执行. 超时以后, 继续原来的处理. 基于下面的假设: 几个微妙内,

程序有很大机会提交另一次请求. 调度器跟踪每个进程的 io 读写统计信息, 以获得最佳预期.

应用范围:适合大文件读写,整块式,重复读写 (web server),适用于文件服务器 ftp/samba 等, 不适用数据库场景。

磁盘调度算法的设置:

echo deadline >/sys/block/sda/queue/scheduler

将 sda 的调度策略设置为 deadline。 我们也可以直接在/etc/grub.conf 的 kernel 行最后添 elevator=deadline 来永久生效。

总结下来, 机械盘的调度算法建议配置为deadline, 固态盘的调度算法建议配置为NOOP

多 IO 设备分担压力

把数据、日志、索引放到不同的 I/O 设备上,或者使用 RAID 设备,以此来利用多个设备的 IO 能力来分担IO 压力。

优化文件系统挂载

优化挂载文件系统的参数,推荐使用 xfs 和 ext4 文件系统。 挂载 XFS 参数:

(rw, noatime,nodiratime,nobarrier)

挂载 ext4 参数:

ext4 (rw,noatime,nodiratime,nobarrier,data=ordered)

比如:noatime 和 nodiratime ,去掉更新访问的时间。

nobarrier:现在的很多文件系统会在数据提交时强制底层设备刷新 cache,避免数据丢失,称之为 write barriers。 但是,其实我们数据库服务器底层存储设备要么采用 RAID 卡,RAID 卡本身的电池可以掉电保护;要么采 用 Flash 卡,它也有自我保护机制,保证数据不会丢失。所以我们可以安全的使用 nobarrier 挂载文件系统。

• data=ordered:(默认) 文件系统日志区仅存放元数据

• data=journal:把数据与元数据都先写入日志区(安全,慢)

• data=writeback:不按日志区元数据顺序来写数据(不安全,快)

配置预读和 IO 请求队列

主要是指操作系统的预读和排队的大小的调整,主要包括:

1. readahead 预读扇区数调整,预读是提高磁盘性能的有效手段,目前对顺序读比较有效,主要利用数据 的局部性特点。比如在笔者的系统上,通过实验设置通读 256 块扇区性能较优。 调整命令:

echo 256 /sys/block/sdb/queue/read_ahead_kb

2. I/O 请求队列长度(调大能增加硬盘吞吐量,但要占用更多内存):

/sys/block/sdb/queue/nr_requests

调整情况: 比如:随机读取修改 减少预读:/sys/block/sdb/queue/read_ahead_kb,默认 128,调整为 16

增大队列:/sys/block/sdb/queue/nr_requests,默认 128,调整为 512

比如:顺序读取修改 增大预读:/sys/block/sdb/queue/read_ahead_kb,默认 128,调整为 256/512

减少队列:/sys/block/sdb/queue/nr_requests,默认 128,调整为 64/32

优化数据库内存参数

KingbaseES 的内存主要包括共享内存和私有内存两大类,不合理的内存使用可能会带来 IO 问题:如

shared_buffers 过小导致数据换进换出,work_mem 过小导致排序使用临时文件。合理的使用内存参数可以较 好的发挥硬件的能力。 在做内存调整时也需要考虑 KingbaseES 使用的内存不要过大导致 swap。

KingbaseES 使用内存总大小为:

shared_buffers(数据) + wal_buffers(日志)+ maintenance_work_mem(创建索引排序时使用)+ n*work_mem(n 为并发做排序的连接数) + 服务进程上下文使用的内存 (无法精确估计大小) + m*thread_stack_size (thread_stack_size 为进程栈的大小, KingbaseES 默认为 1MB; m 为当前连接数);

在进行内存调整时首先要清楚是哪个部分的内存出现了问题,有针对性的进行参数调整。

共享内存参数

shared_buffers

原理:数据库服务器使用的共享内存缓冲区的数量,主要用于缓存数据,根据需求一般不能设置超过 80% 的 内存,但至少是 20%。 应用范围:数据库本身, 查询的数据量比较大,比较频繁使用到。

wal_buffers

原理:日志缓冲区大小, 共享内存里用于 WAL 数据(日志)的磁盘页面缓冲区的数目。 应用范围:如果单位时间事务的数据修改数据量较大,也就是事务的写比较多的情况,如果 IO 是瓶颈,可 以调整这个值到很大,有很多的缓存后,就不会频繁的写磁盘,降低 IO。缺省值为 8 ,8 个页面是 64k。当 然也可以很小,这个设置只需要大到能保存下一次事务生成的 WAL 数据即可, 因为这些数据在每次事务提 交时都会写入磁盘。

私有内存区参数

work_mem

原理:内部排序和哈希操作可使用的工作内存大小。该内存是在开始使用临时磁盘文件之前使用的内存数目。 应用范围:数据比较多大的情况,主要排序的数据有关系,排序数据越大,设置的就越大,比如 16g 内存,

tpch 测试,单用户 10g 规模数据,设置 2g 的 work_mem。数值以 kB 为单位的, 缺省是 1024(1MB),比如 tpcc 1000warehouse,并发 50 个,设置 20mb 即可。

Note: 对于复杂的查询, 可能会同时并发运行好几个排序或者哈希操作, 每个都会使用这个参数声明的这么多 内存, 然后才会开始求助于临时文件。同样, 好几个正在运行的会话可能会同时进行排序操作。因此使用的总 内存可能是 work_mem 的好几倍。ORDER BY, DISTINCT 和 mergejoin 都要用到排序操作, 而哈希操作在哈希 连接、哈希聚集和以哈希为基础的 IN 子查询处理中都会用到。

maintenance_work_mem

原理:在维护性操作 (比如 VACUUM, CREATE INDEX, ALTER TABLE ADD FOREIGN KEY 等) 中使用的最 大的内存数。 应用范围:在维护性操作 (比如 VACUUM, CREATE INDEX, ALTER TABLE ADD FOREIGN KEY 等)调整 大小,默认是 16MB,比如创建索引的索引数据很大,比如 10g,如果内存允许就可以调整这个参数,一般在 需要创建索引的时候调大,创建完之后再调小。

Note: 因为在一个数据库会话里, 任意时刻只有一个这样的操作可以执行, 并且一个数据库安装通常不会有太 多这样的工作并发执行, 把这个数值设置得比 work_mem 更大是安全的,更大的设置可以改进清理和恢复数 据的速度,但是要避免内存用尽的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值