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

在这里插入图片描述

一条更新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链表中一共有多少个缓存页,以及冷数据区域里的缓存页数量。

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值