终于做了一把MySQL调参boy
本文通过笔者经历的一个真实案例来介绍一个MySQL中的重要参数innodb_buffer_pool_size,希望能给大家带来些许收获,当遇到类似性能问题时可以多一种思考方式。
图片拍摄于大唐不夜城
问题背景
有个广西的客户,之前系统一直用的很流畅,最近反馈系统响应极慢,卡顿严重,希望我们尽快解决。
收到反馈以后我立马去查看服务器各项指标,微服务所在机器各项指标正常,但是数据库服务器已不堪重负,看一下top的输出:
数据库服务器的硬件配置为8核16G内存,最繁忙的时候系统负载已经达到了16,cpu利用率700%,可想而知系统当前服务质量有多糟糕。
自我思考
使用量突然上来了吗?
观察了使用人数的趋势图,是多了一些,但还在同一个数量级(toB的客户,一般都在一个可控的量)。
数据量突然上来了吗?
确实是多了一些,有几张表,之前一年多才30多万数据,最近一个月已经长到1百万级别,到底是业务上量了还是程序bug呢,还需要持续排查。
慢查多了吗?
是的,慢查很多,而且最近几天猛涨,怀疑是不是增加了新功能,根据慢SQL去查业务代码,确实增加了七八张报表,我尝试点了一下,确实很慢,高峰期前端几乎全是超时,太慢了。
toB系统业务复杂,OLTP和OLAP都兼备,MySQL应付OLTP很擅长,但是OLAP就有点捉襟见肘了,也许有人会说为什么不用大数据的那一套东西来解决OLAP的问题呢?
成本、成本、成本太高了,toB业务,大多数都部署在客户的自建机房中,最好能少引入或者不引入其他组件,最大限度降低各项成本,包括和客户的沟通成本,客户要付出的财力成本,后期的运维成本等等。
解决过程
铺垫了这么多,具体怎么解决呢?短期来看就是先采用垂直扩容的方式抵御一波,俗称升配置,长期来看的话需要梳理&优化慢查,采用读写分离等手段逐步优化。
话不多说,先联系客户升配置,8核16G变16核32G,希望第二天早高峰能给客户带来丝滑般的用户体验。
第二天我盯着数据库观察负载,确实好了一些,但终归还是凉凉了,只是来的比以往稍晚一些,一时间不知道怎么处理了,客户严重质疑我们的能力。
问题究竟出在哪里了呢?现在这个硬件配置已经很强悍了,感觉完全没有发挥出来,cpu最高才跑到800%。过往的工作中,有专门的DBA负责数据库的运维,遇到过一次升配的场景,升完以后有很明显的性能提升,那感觉刷刷的。
穷途末路的时候我拨通了老板的电话,和他沟通了目前的境遇,希望老同志能指点迷津,快速帮我捅破窗户纸,他有句话提醒了我,“为什么浙江客户的数据库没这个问题呢,配置一样,浙江客户的业务量还要更大一些,区别就是他们用的阿里云RDS,广西客户是自建MySQL,会不会有什么数据库的参数咱没有意识到”。
跟他聊完我立马去对比了阿里云RDS和自建MySQL的相关参数,有一个值非常可疑“innodb_buffer_pool_size“,浙江客户RDS中这个值为12G,而广西客户自建MySQL这个值才为128M,相差接近百倍,好奇心驱使着我快速一探究竟。
看下官方文档对于innodb_buffer_pool的解释:
The buffer pool is a memory area that holds cached data for tables, indexes, and other auxiliary buffers. For efficiency of high-volume read operations, the buffer pool is divided into pages that can potentially hold multiple rows. For efficiency of cache management, the buffer pool is implemented as a linked list of pages; data that is rarely used is aged out of the cache, using a variation of the LRU algorithm. For more information, see Section 15.5.1, “Buffer Pool”. InnoDBInnoDB
The size of the buffer pool is important for system performance:
InnoDB allocates memory for the entire buffer pool at server startup, using operations. The innodb_buffer_pool_size system variable defines the buffer pool size. Typically, a recommended innodb_buffer_pool_size value is 50 to 75 percent of system memory. innodb_buffer_pool_size can be configured dynamically, while the server is running. For more information, see Section 15.8.3.1, “Configuring InnoDB Buffer Pool Size”. malloc()
On systems with a large amount of memory, you can improve concurrency by dividing the buffer pool into multiple buffer pool instances. The innodb_buffer_pool_instances system variable defines the number of buffer pool instances.
A buffer pool that is too small may cause excessive churning as pages are flushed from the buffer pool only to be required again a short time later.
A buffer pool that is too large may cause swapping due to competition for memory.
提取出这么几个重要信息:
1.缓冲池是保存表、索引和其他辅助缓冲区的缓存数据的内存区域;
2.缓冲池的大小对MySQL的性能很重要;
3.推荐的大小是物理内存的50%到75%;
4.inndb_buffer_pool_size可以在MySQL运行时动态调整;
5."Configuring InnoDB Buffer Pool Size"这个配置手册中提到默认值为128兆。
再看看《MySQL技术内幕InnoDB存储引擎》这本书中关于缓冲池的介绍:
缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。在数据库中进行读取页的操作,首先将从磁盘读到的页放在缓冲池中,这个过程称为将页“FIX“到缓冲池中。下一次再读相同的页时,首先判断该页是否在缓冲池中,若在缓冲池中,称该页在缓冲池中被命中,直接读取该页,否则,读取磁盘上的页。
做了一定的了解之后我决定动手去改一下这个值看看效果,之前提到客户已经把数据库服务器的配置扩到了16核32G,那我就把inndb_buffer_pool_size设置为32G*0.75=24G。
--注意:
--1.这里的单位是字节
--2.这是动态调整,长远来看这个配置应该放到配置文件中,防止重启丢失
set global innodb_buffer_pool_size = 25769803776
调完以后效果显著,我拿了几个耗时严重的SQL做了对比,查询时间减少一半以上,慢查数量明显下降,看看此时的数据库负载情况
调整缓冲池大小之前cpu和负载都很高,但是内存占用很低,调整完以后cpu和负载明显下降,内存占用高了,这正是我们所期待的效果。
看看客户给我们的反馈
总结
问题暂时告一段落,虽说没有100%的解决问题,但也解决了70%-80%的问题,那些剩余的20%-30%需要开发人员去优化代码,硬件扩容并不是银弹,庆幸的是,经过这次调整应该能给开发人员争取一些时间来优化代码。
另一方面也折射出自己对数据库的认识只是停留在开发视角的一些知识,比如SQL优化、索引的匹配、慢查优化等等,对于底层原理性的东西欠缺太多,有人会说这类东西应该交给DBA负责,这么说倒也没什么问题,但现实情况是有些团队就是没有配备DBA的,只能开发顶,再者说,作为开发而言,对于这类知识不一定要熟练掌握,但起码应该有一些初步的认识。
推荐阅读
MySQL如何使用内存 (oracle.com)
https://docs.oracle.com/cd/E17952_01/mysql-8.0-en/memory-use.html
调整innodb_buffer_pool_size
Configuring InnoDB Buffer Pool Size (oracle.com)
终于做了一把MySQL调参boy的更多相关文章
- Python中Gradient Boosting Machine(GBM)调参方法详解
原文地址:Complete Guide to Parameter Tuning in Gradient Boosting (GBM) in Python by Aarshay Jain 原文翻译与校对 ...
- hyperopt自动调参
hyperopt自动调参 在传统机器学习和深度学习领域经常需要调参,调参有些是通过通过对数据和算法的理解进行的,这当然是上上策,但还有相当一部分属于"黑盒" hyperopt可以帮 ...
- GBDT调参总结
一.GBDT类库弱学习器参数 二.回归 数据集:已知用户的30个特征,预测用户的信用值 from sklearn.ensemble import GradientBoostingRegressor f ...
- [调参]CV炼丹技巧/经验
转自:https://www.zhihu.com/question/25097993 我和@杨军类似, 也是半路出家. 现在的工作内容主要就是使用CNN做CV任务. 干调参这种活也有两年时间了. 我的 ...
- scikit-learn 梯度提升树(GBDT)调参小结
在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...
- gbdt调参的小结
关键部分转自http://www.cnblogs.com/pinard/p/6143927.html 第一次知道网格搜索这个方法,不知道在工业中是不是用这种方式 1.首先从步长和迭代次数入手,选择一个 ...
- scikit-learn 梯度提升树(GBDT)调参笔记
在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn ...
- scikit-learn随机森林调参小结
在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...
- word2vec参数调整 及lda调参
一.word2vec调参 ./word2vec -train resultbig.txt -output vectors.bin -cbow 0 -size 200 -window 5 -neg ...
随机推荐
- 我的分布式微服务框架:YC-Framework
YC-Framework官方文档:http://framework.youcongtech.com/ YC-Framework源代码:https://github.com/developers-you ...
- .NET Core如何配置TLS Cipher(套件)?
前言 前不久我发表了一篇关于TLS协议配置被我钻了空子,经过第三方合作伙伴验证,针对此TLS协议存在不安全套件,急催速速解决,那么我们本篇开始继续整活!第三方合作伙伴对平台安全严苛要求,我们已连续发版 ...
- 使用 CliWrap 让C#中的命令行交互举重若轻
在代码中进行命令行交互是一个很常见的场景, 特别是在一些CI CD 自动化流程中, 在这之前我们会使用 System.Diagnostics.Process API, 现在有一个更灵活的工具 CliW ...
- 【PS算法理论探讨一】 Photoshop中两个32位图像混合的计算公式(含不透明度和图层混合模式)。
大家可以在网上搜索相关的主题啊,你可以搜索到一堆,不过似乎没有那一个讲的很全面,我这里抽空整理和测试一下数据,分享给大家. 我们假定有2个32位的图层,图层BG和图层FG,其中图层BG是背景层(位于下 ...
- Hadoop 相关知识点(一)
作业提交流程(MR执行过程) Mapreduce2.x Client:用来提交作业 ResourceManager:协调集群上的计算资源的分配 NodeManager:负责启动和监控集群上的计算容器( ...
- angular中路由跳转并传值四种方式
一.路由传值 步骤1 路由传递参数 注意 一定是要传递 索引值 let key = index 这种情况是在浏览器中可以显示对应的参数 这种的是问号 localhost:8080/news?id=2& ...
- 实现new Date(), 获取当前时间戳
JS 获取时间戳: 我相信大家找了很久了吧! 希望我写的这个对您有些帮助哦~ 大家是不是以为时间戳是关于时间的,都去 new Date() 里面找方法了啊,我来告诉你们正确的吧 其实大家用 JS 里的 ...
- jQuery 的两种语法
文档就绪事件(文档加载完成之后才执行jQuer代码): 第一种: $(document).ready(function() { // jQuery 代码.... }); 第二种: $(function ...
- DMA(Data Migration Assistant)迁移SQLServer数据库
DMA适用于 本地SQLServer向Azure SQL Database迁移 两台不同的数据库服务器之间迁移 高版本->低版本 或 低版本->高版本 本文以两台不同服务器的低版本(SQL ...
- Redis增加测试数据
目录 一.简介 二.操作 三.制造测试数据 一.简介 用shell脚本将文本内容挨个写到redis中效率是很慢的.打开一个链接,写入后再关闭,再打开,效率很低. redis支持pipe mode功能, ...