内存的80%?应该如何调整你的innodb_buffer_pool_size
现在看来,如果有人知道如何调优InnoDB,那就是你必须将innodb_buffer_pool_size调整到物理内存的80%。多数都是这样建议,它似乎深深植根于DBA的脑海中。MySQL手册引用了这个规则,那么谁能责怪DBA呢?问题是:这有意义吗?
什么使用服务器上的内存?
在我们质疑这样的建议之前,让我们考虑一下在典型的MySQL服务器中可以占用RAM的广泛类别。这个列表不一定完整,但我认为它概述了MySQL服务器消耗内存的大面积。
操作系统:内核,正在运行的进程,文件系统缓存等。
MySQL固定使用:查询缓存,InnoDB缓冲池大小,mysqld rss等。
基于MySQL工作负载的使用:连接,每个查询缓冲区(连接缓冲区,排序缓冲区等)
MySQL复制: 二进制日志缓存,复制连接,Galera gcache和证书索引等。
同一服务器上的任何其他服务: Web服务器,缓存服务器,cronjobs等。
毫无疑问,对于调优InnoDB,innodb_buffer_pool_size是最重要的变量。预计它将占用专用MySQL / Innodb服务器上的大部分RAM,但当然其他本地服务可能会影响它的调整方式。如果它(以及服务器上的其他内存消耗)太大,交换可能会启动并迅速降低性能。
此外,MySQL服务器本身的工作量可能会导致很多变化。服务器是否有大量的开放连接和活动查询工作负载消耗内存?由此引起的内存消耗可能与服务器有很大不同。
最后,像Galera这样的复制机制有自己的内存使用模式,可能需要对缓冲池进行一些调整。
我们可以清楚地看到,80%的规则并不像现实那样微妙。
经验法则
但是,为了论证,让我们说80%的规则是一个起点。根据经验,帮助我们获得快速调整数字以使服务器运行。假设我们对系统的工作负载还不知道,但我们知道该系统专用于InnoDB,我们的80%规则怎么能发挥作用呢?
服务器总RAM | 具有80%规则的缓冲池 | 剩余的RAM |
---|---|---|
1G | 800MB | 200MB |
16G | 13G | 3G |
32G | 26G | 6G |
64G | 51G | 13G |
128G | 102G | 26G |
256G | 205G | 51G |
512G | 409G | 103G |
1024G | 819G | 205G |
数字较低,我们的80%规则看起来很合理。然而,当我们进入大型服务器时,它似乎开始变得不那么理智了。要使规则成立,它必须意味着工作负载内存消耗与缓冲池所需大小成比例增加,但通常情况并非如此。我们的服务器具有1TB的RAM可能不需要205G来处理连接和查询之类的东西(可能MySQL无法处理那么多活动连接和查询)。
那么,如果你真的把所有的钱花在了一台强大的服务器上,你是否真的想因为这个经验法则对该资源征收20%的税?
规则的起源
在我的第一次MySQL会议上,可能是在2006-2007我在雅虎工作时,我参加了由Heikki Tuuri(InnoDB的原作者)和Peter Zaitsev主持的InnoDB调优讲座。我清楚地记得询问80%的规则,因为当时雅虎有一些强大的64G服务器而且规则并不适合我。
Heikki的答案让我印象深刻。他说了一些(不是直接引用)的结果:“好吧,我测试的服务器有1GB内存,80%似乎是正确的”。然后,如果记忆服务,他澄清了它并说它不会适用于更大的服务器。
你应该如何调整?
80%可能是一个很好的开始和经验法则。您确实希望确保服务器有足够的可用RAM用于操作系统和通常未知的工作负载。但是,正如我们上面所看到的,服务器越大,规则就越有可能浪费RAM。我认为对于大多数人来说,它以经验法则开始和结束,主要是因为更改InnoDB缓冲池需要在当前版本中重新启动。
那么什么是更好的经验法则?我的规则是,当系统运行生产工作负载时,您可以在不使用swap的情况下调整innodb_buffer_pool_size尽可能大。原则上听起来不错,但同样需要一堆重启,说起来容易做起来难。
幸运的是, MySQL 5.7及其在线缓冲池调整大小功能应该使这个原则更容易理解。看到大量的空闲RAM(或者文件系统缓存使用)?动态调高缓冲池。看到一些交换活动?只需将其关闭即可,无需重启。在实践中,我怀疑使用此功能会有一些与性能相关的打嗝,但这至少是朝着正确方向迈出的一大步。