【大白话系统】MySQL 学习总结 之 缓冲池(Buffer Pool) 如何支撑高并发和动态调整
如果大家对我的 【大白话系列】MySQL 学习总结系列 感兴趣的话,可以点击关注一波。
一、上节回顾
在上节《 缓冲池(Buffer Pool) 的设计原理和管理机制》中,介绍了缓冲池整体的设计原理。包括几个比较重要的概念:free 链表、flush 链表和 lru 链表。正式因为这一套机制,使得 InnoDB 存储引擎可以基于内存操作,避免了磁盘随机读写的低性能。
二、Buffer Pool 如何应对高并发场景
1、单个 Buffer Pool 的问题
直到现在,估计大家都以为缓冲池只是一个大的内存区域,在 InnoDB 存储引擎中只有一个,这是对的吗?
我们可以想象,如果 InnoDB 存储引擎只有一个 Buffer Pool,当高并发时,多个请求进来,那么为了保证数据的一致性(缓存页、free 链表、flush 链表、lru 链表等多种操作),必须得给缓冲池加锁了,每一时刻只能有一个请求获得锁去操作 Buffer Pool,其他请求只能排队等待锁释放。那么此时 MySQL 的性能是多么的低!
2、多个 Buffer Pool
既然一个 Buffer Pool 不够用,那么整多几个呗。
在生产环境中,其实我们是可以给 MySQL 设置多个 Buffer Pool 来提升 MySQL 的并发能力的~
如何设置?
我们先看看 MySQL 的默认规则:如果你给 Buffer Pool 分配的内存小于1GB,那么最多就只会给你一个 Buffer。
但是呢,如果你给 MySQL 设置的内存很大,此时你可以利用下面两个参数来设置 Buffer Pool 的总大小和总实例数,这样,MySQL 就能有多个 Buffer Pool 来支撑高并发了。
[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4
解释一下:上面利用参数 innodb_buffer_pool_size 来设置 Buffer Pool 的总大小为 8G,利用参数 innodb_buffer_pool_instances 来设置一共有 4个 Buffer Pool 实例。那么就是说,MySQL 一共有 4个 Buffer Pool ,每个的大小为 2G。
当然了,每个 Buffer Pool 负责管理着自己的描述数据块和缓存页,有自己独立一套 free 链表、flush 链表和 lru 链表。
到这,我们就晓得,只要你能分配足够大的内存给 Buffer Pool ,你就能创建尽量多的 Buffer Pool 来应对高并发场景~
正所谓,并发性能不高,机器配置来凑,这还是有道理的。
但是正经点来说,最基本最主要的还是咱们写的 SQL。当然了,能写出一手好 SQL,前提我们还是得理解 MySQL 各个组件的原理,熟悉索引的原理、事务原理和锁原理等。当然了,之后我也会分别对这些做出一个学习总结分享出来。
三、生产环境中,如何动态调整 Buffer Pool 的大小
相信基本每个公司,项目上线后,用户和流量会不断地增长,这对于 MySQL 来说,会有什么变化?
首先,访问增多,不断地从磁盘文件中的数据页读取数据到 Buffer Pool,也不断地将 Buffer Pool 的脏缓存页刷回磁盘文件中。很明显的,Buffer Pool 越小,这两个操作就会越频繁,但是磁盘IO操作又是比较耗时的,本来 SQL 执行只要 20 ms,如果碰巧碰到遇到缓存页用完,就要经历一系列的操作,SQL 最后执行完可能就要 200 ms,甚至更多了。
所以我们此时需要及时调整 Buffer Pool 的大小。
1、如何动态调整 Buffer Pool 的大小?
但是生产环境,肯定不能让我们直接修改 MySQL 配置然后再重启吧,这估计要骂死。
在 MySQL 5.7 后,MySQL 允许我们动态调整参数 innodb_buffer_pool_size 的值来调整 Buffer Pool 的大小了。
假如就这样直接调大会存在啥问题?
假设调整前的配置:Buffer Pool 的总大小为8G,一共4个 Buffer Pool,每个大小为 2G。
[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4
假设给 Buffer Pool 调整到 16 G,就是说参数 innodb_buffer_pool_size 改为 17179869184。
此时,MySQL 会为 Buffer Pool 申请一块大小为16G 的连续内存,然后分成 4块,接着将每一个 Buffer Pool 的数据都复制到对应的内存块里,最后再清空之前的内存区域。
我们可以发现,全部数据要从一块地方复制到另外一块地方,那这是相当耗费时间的操作,整整8个G的数据要进行复制粘贴呢!而且,如果本来 Buffer Pool 是更大的话,那就更恐怖了。
2、Buffer Pool 的 chunk 机制
为了解决上面的问题,Buffer Pool 引入一个机制:chunk 机制。
- 每个
Buffer Pool其实是由多个 chunk 组成的。每个 chunk 的大小由参数innodb_buffer_pool_chunk_size控制,默认值是 128M。 - 每个 chunk 就是一系列的描述数据块和对应的缓存页。
- 每个
Buffer Pool里的所有 chunk 共享一套 free、flush、lru 链表。
得益于 chunk 机制,就能避免了上面说到的问题。当扩大 Buffer Pool 内存时,不再需要全部数据进行复制和粘贴,而是在原本的基础上进行增减内存。
下面继续用上面的例子,介绍一下 chunk 机制下,Buffer Pool 是如何动态调整大小的。
调整前 Buffer Pool 的总大小为 8G,调整后的 Buffer Pool 大小为 16 G。
由于 Buffer Pool 的实例数是不可以变的,所以是每个 Buffer Pool 增加 2G 的大小,此时只要给每个 Buffer Pool 申请 (2000M/128M)个chunk就行了,但是要注意的是,新增的每个 chunk 都是连续的128M内存。
四、生产环境中,应该给 Buffer Pool 设置多大的内存
1、如何设置 Buffer Pool 的总内存大小
我们都知道,给 Buffer Pool 分配越大的内存,MySQL 的并发性能就越好。那是不是都应该将百分之九十九的机器的内存都分配给 Buffe Pool 呢?
那当然不是了!
先不说操作系统内核也需要几个G内存,MySQL 除了 Buffer Pool 还有很多别的内存数据结构呢,这些都是需要内存的,所以说,上面的想法是绝对不行的!
比较合理的比例,应该是 Buffer Pool 的内存大小占机器总内存的 50% ~ 60%,例如机器的总内存有32G,那么你给 Buffer Pool 分配个20G左右就挺合理的了。
2、如何设置 Buffer Pool 的实例数
Buffer Pool 的总大小搞定了,那应该设置多少个实例数呢?
这里有一个公式:Buffer Pool 总大小 = (chunk 大小 * Buffer Pool数量)* n倍。
上个例子解释一下。
假设此时 Buffer Pool 的总大小为 8G,即 8192M,那么 Buffer Pool 的数量应该是多少个呢?
8192 = ( 128 * Buffer Pool 数量)* n
64 个:也是可以的,但是每个 Buffer Pool 就只要一个 chunk。
16 个:也是可以的,每个 Buffer Pool 拥有四个 chunk。
8 个:也是可以的,每个 Buffer Pool 拥有八个 chunk。
所以说,只要你的 Buffer Pool 数量符合上面的公式,其实都是可以的,看你们根据业务后怎么选择了。
【大白话系统】MySQL 学习总结 之 缓冲池(Buffer Pool) 如何支撑高并发和动态调整的更多相关文章
- 【大白话系统】MySQL 学习总结 之 缓冲池(Buffer Pool) 的设计原理和管理机制
一.缓冲池(Buffer Pool)的地位 在<MySQL 学习总结 之 InnoDB 存储引擎的架构设计>中,我们就讲到,缓冲池是 InnoDB 存储引擎中最重要的组件.因为为了提高 M ...
- MySQL学习笔记-cache 与 buffer
Cache和Buffer是两个不同的概念,简单的说,Cache是加速"读",而 buffer是缓冲"写",前者解决读的问题,保存从磁盘上读出的数据,后者是解决写 ...
- MySql 缓冲池(buffer pool) 和 写缓存(change buffer) 转
应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. M ...
- MySQL缓存之Qcache与buffer pool对比
Q:innodb buffer pool和Qcache的缓存区别? A: 1.Qcacche缓存的是SQL语句及对应的结果集,缓存在内存,最简单的情况是SQL一直不重复,那Qcache的命令率肯定是0 ...
- InnoDB 中的缓冲池(Buffer Pool)
本文主要说明 InnoDB Buffer Pool 的内部执行原理,其生效的前提是使用到了索引,如果没有用到索引会进行全表扫描. 结构 在 InnoDB 存储引擎层维护着一个缓冲池,通过其可以避免对磁 ...
- MySQL中读页缓冲区buffer pool
Buffer pool 我们都知道我们读取页面是需要将其从磁盘中读到内存中,然后等待CPU对数据进行处理.我们直到从磁盘中读取数据到内存的过程是十分慢的,所以我们读取的页面需要将其缓存起来,所以MyS ...
- MySQL面试必考知识点:揭秘亿级高并发数据库调优与最佳实践法则
做业务,要懂基本的SQL语句: 做性能优化,要懂索引,懂引擎: 做分库分表,要懂主从,懂读写分离... 数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 今天我们用10分钟 ...
- mysql内核源代码深度解析 缓冲池 buffer pool 整体概述
http://blog.csdn.net/cjcl99/article/details/51063078
- 【大白话系列】MySQL 学习总结 之 COMPACT 行格式的设计原理
如果大家对我的 [大白话系列]MySQL 学习总结系列 感兴趣的话,可以点击关注一波. 一.回顾 MySQL 学习总结系列至此已经第七节了. 从大方向:我们已经学习了 MySQL 的架构设计.Inno ...
随机推荐
- 机器学习——提升方法AdaBoost算法,推导过程
0提升的基本方法 对于分类的问题,给定一个训练样本集,求比较粗糙的分类规则(弱分类器)要比求精确的分类的分类规则(强分类器)容易的多.提升的方法就是从弱分类器算法出发,反复学习,得到一系列弱分类器(又 ...
- cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA
186. [USACO Oct08] 牧场旅行 ★★☆ 输入文件:pwalk.in 输出文件:pwalk.out 逐字节对比时间限制:1 s 内存限制:128 MB n个被自然地编号为 ...
- 点分治 (等级排) codeforces 321C
Now Fox Ciel becomes a commander of Tree Land. Tree Land, like its name said, has n cities connected ...
- DOCKER学习_017:Docker-Compose介绍
dockers三驾马车 Docker Machine Docker Swarm Docker Compose 一 Docker Compose介绍 Docker Compose是一个定义和运行多容器应 ...
- background-position和position
1.background-position:表示背景定位的属性.描述属性值时,有两种方式:一是像素描述:而是单位描述. (1)像素描述: 格式如下: background-position:向右偏移量 ...
- Qt Installer Framework翻译(3-4)
更新组件 下图说明了用于更新已安装组件的默认工作流程: 本节使用在macOS上运行的Qt 5维护工具为例,来演示用户如何更新已安装组件. 启动更新程序 用户启动维护工具时,将打开"简介&qu ...
- mysql输出到页面MVC模式
上一篇文章我提到过在jsp页面不好 这篇文章讲的就是界面和代码分离,可以初步实现两个或三个人合作完成一个项目 好,废话不多说,进正题 这次又四个步骤 第一步,新建项目,新建实体类 第二步,新建数据库, ...
- 两张导图带你走进Spring设计模式与编程思想
两张思维导图带你了解Spring Spring常用设计模式 Spring设计思想
- 在Anaconda3下安装(CPU版)TensorFlow(清华镜像源)
1.打开Anaconda Prompt 2.搭建TensorFlow的环境: conda config --add channels https://mirrors.tuna.tsinghua.edu ...
- Hexo+coding实现自动化部署
前言 昨天写了一篇利于云环境写博客,但是让群里大佬们看了下.评论道:"写的不错,但还是觉得这个云环境太繁琐了,没有CI/CD自动化部署方便".于是我便百度查了下,网上文章大部分是通 ...