你的系统是如何与MySQL打交道

本文详细介绍了MySQL中BufferPool的工作原理及其对性能的影响。包括BufferPool的初始化过程、内存结构配置、预读机制对LRU算法的影响以及如何通过合理配置提高并发能力等内容。

在这里插入图片描述

一条更新SQL的执行全过程

在这里插入图片描述

为什么不将修改落盘,而是使用BufferPool?

因为数据库的update操作是随机IO,随机IO效率很低,如果直接落盘,那么MySQL支持的并发数量可能就会很少,而redo日志这些事顺序IO,比随机IO性能高。

undo日志做什么用?各种日志如何控制大小,何时会去删除?

普通的Java应用系统部署在机器上能抗多少并发?

以大量的高并发线上系统的生产经验观察而言,一般Java应用系统部署在4核8G的机器上,每秒钟抗下500左右的并发访问量,差不多是比较合适的。但是如果你每个请求花费1s,那么一台机器也许只可以处理100个请求,但是你每个请求只要花费100ms,可以处理完,那么你一台机器每秒也许可以处理几百个请求。

高并发场景下,数据库应该用什么样的机器?

通常推荐的数据库至少是8核16G,甚至是16核32G的机器。因为大部分Java系统压力大,都是集中在你依赖的那个MySQL数据库上的!对于8核16G的机器,每秒抗个一两千并发请求是没问题的,但是如果并发量再高一些,假设每秒有几千个并发请求,那么数据库有点危险,可能会宕机。对于16核32G的机器部署MySQL数据库而言,每秒扛个两三千,甚至三四千请求也可以,但是上万请求就不行了。

MySQL常用的性能监控指标:

QPS:每秒查询数

TPS:每秒事务数

IOPS:随机IO的并发能力

吞吐量:机器的磁盘存储每秒可以读写多少个字节的数据量

latency:往磁盘写入一条数据的延迟

CPU负载

网络负载

内存负载

构造MySQL压测工具及监控系统

sysbench,…

Buffer Pool这个数据内存结构

配置buffer_pool的大小,缓冲页是16KB

innodb_buffer_pool_size=2147483648

在这里插入图片描述

配置的参数只是buffer_pool的缓冲页大小,实际上Buffer_Pool还会包含一部分描述数据,大概相当于缓冲页的百分之五。

Buffer_Pool的初始化过程

数据库一启动,就会按照设置的Buffer_Pool的大小去申请一块内存区域,申请完毕之后,数据库就会按照默认的缓存页的16KB大小,以及对应的800个字节左右的描述数据的大小,在Buffer Pool划分出一个一个的缓存页和一个一个他们对应的描述数据。当数据库运行起来后,我们对数据进行增删改查的时候,才会把数据对应的页从磁盘文件里读取出来,放入Buffer Pool中的缓存页中。

Free和flush链表

free链表存储的是空闲缓冲,flush存的是脏页链表。

表、列和行、表空间、数据页的关系

表、列、行都是逻辑概念,实际上数据在磁盘空间是以表空间及一个一个的数据页组织起来的。

MySQL预读机制或全面扫描给LRU带来的问题

innodb_read_ahead_threshold,意思是如果顺序访问了一个区里的多个数据页,访问的数据页的数量如果超过了这个阈值,就会触发预读机制,把下一个相邻区中所有数据页都加载到缓存里去。

如果Buffer Pool里缓存一个区里的连续13个页,而且这些数据页都比较频繁地访问,此时就会触发预读机制,把这个区里的其他的数据页都加载到缓存里去,innodb_random_read_ahead来控制的。

全表扫描,select * from users,一下子把表里所有数据页都加载到Buffer Pool中去。

预读机制导致了LRU缓存淘汰机制不好用。

基于冷热数据分离的LRU算法

innodb_old_blocks_pct参数控制的冷热数据比例,数据从磁盘加载到Buffer Pool时,会进入后半部分的冷数据区域中,如果1s(由innodb_old_bolcks_time参数控制)之后,有访问,才会将它提前到热数据区域。

为什么Redis要做热数据加载?

如果说你把访问到的数据都放在Redis,那么导致大量不怎么访问的数据都会被放在Redis缓存里,浪费内存,所以会考虑数据的缓存预加载。所以,白天的统计出哪些商品被访问得最多,到了晚上,启动定时,把热门数据加载到Redis。

LRU链表的热数据区域是如何进行优化的?

LRU热数据区域的1/4区域,即使访问了,也不会移动到链表头,因为头部非常大概率会被访问的,频率移动浪费性能,后3/4被访问了,才会移动到链表头。

将Buffer Pool的数据刷到磁盘

1.后台的定时线程将冷数据区域尾部的一些缓存刷入磁盘中

2.后台线程会在MySQL不怎么繁忙的时候,找个时间把flush链表中的缓存页刷入磁盘,只要flush链表中的缓存页刷入磁盘,那么这些缓存页也会从flush链表和lru链表中移除,加入free链表中。

3.当实在没有空闲缓存页了,从LRU链表的冷数据区域的尾部找到一个缓存页,把它刷入磁盘和清空。

多个Buffer Pool优化并发能力

如果你给Buffer Pool分 配的内存小于1GB,那么最多只会分配一个Buffer Pool。如果你的机器内存很大,那么你必然会给Buffer Pool分配较大的内存,比如给他个8G内存,那么可以设置多个Buffer Pool的优化并发能力。类似于ConcurrentHashMap的分段锁机制。

innodb_buffer_pool_size=8589934592 // 设置Buffer Pool 
innodb_buufer_pool_instances=4  // Buffer Pool的实例个数

通过chunk来支持数据库运行期间的Buffer Pool动态调整

在这里插入图片描述

如果从8G调整到16G的时候,不需要额外申请16GB的连续内存空间及拷贝了。只需要申请一系列的chunk,然后将chunk分配给Buffer Pool就可以了。

生产环境中,基于机器配置合理的Buffer Pool

通常,如果一台专门做数据库的服务器,内存设置为机器内存的百分之60。

buffer pool总大小=(chunk大小 * buffer pool数量)*倍数

查看INNODB的运行状况

show engine innodb status

total memory allocated,指的是buffer pool最终的总大小是多少

Buffer pool size,指的是buffer pool一共能容纳多少个缓存页

Free buffers,指的是free链表一共有多少个空闲的缓存页是可用的

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

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值