六、基于 Buffer Pool 优化

  MySQL 高并发场景下会使用多线程来处理请求,然后访问存储在 Buffer Pool 中的共享缓存页,多个线程访问同一个 Buffer Pool 资源必然是要加锁来进行的。虽然对数据的查询、更新等操作都是在内存中进行的,即使加锁性能也是可以的。但如果大量请求需要通过磁盘加载数据到缓存,就需要进行磁盘 IO 操作,这时性能就会受到影响。

多个 Buffer Pool 优化并发能力

  MySQL 默认的规则是,如果给 Buffer Pool 分配的内存小于 1G ,就会只分配一个 Buffer Pool,但是如果内存很大就可以分配多个 Buffer Pool。

[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4

  通过以上参数,给 Buffer pool 总内存大小设置为 8G,分为 4个,每个 Buffer pool 就是 2G 内存。这时多个线程并发访问,就会把请求压力分散到 4个 Buffer Pool,每个 Buffer Pool 都有单独的缓存页和链表。

基于 chunk 机制动态调整 Buffer pool 大小

  Buffer Pool 一旦创建是不允许运行期间动态调整的,如果允许动态调整,比如 8G 内存扩展到 16G 内存,那么首先需要向系统申请一块 16G 的内存,然后把原来 8G 内存中的数据拷贝到 16G 内存空间,这个操作性能是及其低下的。

  但是 MySQL 对此做了优化,设计了一个 chunk 机制,也就是说 Buffer pool 实际上是由 chunk 块组成的,chunk 块的大小由参数 innodb_buffer_pool_chunk_size 控制,默认为 128 M 。如果一个 Buffer pool 总内存有 8G,拥有 4个Buffer Pool,每个 Buffer Pool 大小为 2G,那么实际上每个 Buffer Pool 是由 16个 128M 的 chunk 组成的。

  每个 chunk 块中就是一系列的元数据和缓存页,Buffer Pool 中的所有 chunk 共享一套链表。然后扩容时只需要把申请到的一系列 128M 的 chunk 分配给 Buffer Pool 就完成扩容了。

合理设置 Buffer Pool

  Buffer Pool 的总内存不是越大越好,一般在机器内存的50% ~ 60% 左右,因为操作系统也需要一定的内存。设定规则为 Buffer Pool 总大小 = 128M * chunk * buffer。比如说给 Buffer Pool 分配 20G 内存,chunk 大小为 128M。

  现在需要分配 16个 Buffer Pool,那么 (1024 * 20)M = 128M * chunk * 16   也就是每个 buffer pool 拥有 10 个 chunk,大小为 1024M(1G);

  如果许需要分配 32个 Buffer Pool,那么 (1024 * 20)M = 128M * chunk *  32   也就是每个 buffer pool 拥有 5 个 chunk,大小为 640M;

查看 innodb 信息

  执行命令 SHOW ENGINE INNODB STATUS 查看 innodb 信息。

复制代码
Total memory allocated xxxx;
Dictionary memory allocated xxx
Buffer pool size xxxx
Free buffers xxx
Database pages xxx
Old database pages xxxx
Modified db pages xx
Pending reads 0
Pending writes: LRU O, flush list 0, single page 0
Pages made young xxxx, not young xxx
xx youngs/s, xx non-youngs/s
Pages read xxox, created xxx, written xxx
xx reads/s, xx creates/s,1xx writes/s
Buffer pool hit rate xoxx / 1000, young-making rate xxx / 1000 not xx / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: xoxxx,unzip_LRU len: xxx
I/o sum[xxox]:cur[xx], unzip sum[16xx:cur[O]
复制代码

参数解释

(1)Total memory allocated,这就是说buffer pool最终的总大小是多少

(2) Buffer pool size,这就是说buffer pool—共能容纳多少个缓存页

(3) Free buffers,这就是说free链表中一共有多少个空闲的缓存页是可用的

(4) Database pages和old database pages,就是说lru链表中一共有多少个缓存页,以及冷数据区域里的缓存页数量

(5)Modified db pages,这就是flush链表中的缓存页数量

(6)Pending reads和Pending writes,等待从磁盘上加载进缓存页的数量,还有就是即将从lru链表中刷入磁盘的数量、即将从flush链表中刷入磁盘的数量

(7) Pages made young和not young,这就是说已经在lru冷数据区域里访问之后转移到热数据区域的缓存页的数量,以及在lru冷数据区域里1s内被访问了没进入热数据区域的缓存页的数量

(8) youngs/s和not youngs/s,这就是说每秒从冷数据区域进入热数据区域的缓存页的数量,以及每秒在冷数据区域里被访问了但是不能进入热数据区域的缓存页的数量

(9) Pages read xoxx, created xx,written xoxx,xx reads/s, xx creates/s, 1xx writes/s,这里就是说已经读取、创建和写入了多少个缓存页,以及每秒钟读取、创建和写入的缓存页数量

(10) Buffer pool hit rate xx / 1000,这就是说每1000次访问,有多少次是直接命中了buffer pool里的缓存的

(11) young-making rate xx / 1000 not xx / 1000,每1000次访问,有多少次访问让缓存页从冷数据区域移动到了热数据区域,以及没移动的缓存页数量

(12)LRU len:这就是lru链表里的缓存页的数量

(13)I/o sum:最近50s读取磁盘页的总数

(14) Io cur:现在正在读取磁盘页的数量

posted @   维维尼~  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示