第5章-1 优化服务器设置
上一篇:《第4章-5 linux 网络管理》,接着服务器设置
本章我们将解释如何为MySQL服务器创建合适的配置文件。这是一个迂回的旅程,有许多兴趣点和可以俯瞰风景的短途旅程。这些短途旅程是必要的。确定合适配置的最短路径并不是从研究配置选项并询问应该设置哪些配置或如何更改它们开始的,也不是从检查服务器行为并询问是否有任何配置选项可以改善它开始的。最好从了解MySQL的内部结构和行为开始。然后,你可以使用这些知识作为如何配置MySQL的指南。最后,你可以将期望的配置与当前配置进行比较,并纠正任何重要和值得修改的差异。
人们经常会问:“我的服务器有32GB的RAM和12个CPU核,最佳配置文件是什么?”不幸的是,事情并没有那么简单。你应该根据工作负载、数据和应用程序需求来配置服务器,而不仅仅是根据硬件来配置。MySQL有许多可以更改但不应该更改的设置。通常更好的做法是正确地配置基本设置(在大多数情况下,只有少数设置是重要的),并将更多的时间花在schema优化、索引和查询设计上。在正确设置MySQL的基本配置选项之后,从进一步的更改中获得的潜在收益通常很小。
另外,修改配置的潜在缺点可能是巨大的。MySQL的默认设置是有充分理由的。在不了解其影响的情况下进行更改可能会导致崩溃、卡顿或性能下降。因此,你永远不应该盲目地相信来自热门帮助网站(如MySQL论坛或Stack overflow)的某些人所报告的最佳配置。(例如,如果关闭数据持久性设置,MySQL可以运行得非常快,但它也会让你的数据在崩溃时很容易丢失)应该始终通过阅读相关的官方手册来检查任何更改并仔细测试。
那该怎么办?首先应该确保InnoDB缓冲池和日志文件大小等基本设置是合适的。然后,如果你想防止不希望的行为出现,应该设置一些安全选项(但请注意,这些通常不会提高性能,只会避免问题),然后保持其他的设置不变。如果遇到问题,首先要仔细诊断。
如果问题是由服务器的某个部分引起的,而该部分的行为可以通过配置选项进行纠正,那么可能需要对其进行更改。
有时还需要设置特定的配置选项,这些选项在特殊情况下可能会对性能产生重大影响。但是,这些不应该是基本服务器配置文件的一部分。应该只在发现它们解决的特定性能问题时,才设置它们。这就是为什么我们不建议通过寻找不好的方面来改进配置选项的原因。
如果需要改进配置,应该会在查询响应时间中体现出来。最好从查询及其响应时间开始分析,而不是从配置选项开始。这可以节省很多时间,避免很多问题。
另一个节省时间和避免麻烦的好方法是使用默认设置,除非你明确知道不应该使用默认设置。很多默认设置都是安全的,很多人都会直接使用。这使默认设置成为测试最彻底的设置。当没必要改变这些设置而改变它们时,可能会引起意想不到的错误。
MySQL的配置是如何工作的
介绍在MySQL中应该配置什么之前,我们将首先解释MySQL的配置机制。MySQL通常对其配置很宽容,但遵循这些建议可以为你节省大量的工作和时间。
首先要知道的是,MySQL从何处获取配置信息:命令行参数和配置文件中的设置项。在类UNIX系统上,配置文件通常位于/etc/my.cnf或/etc/mysql/my.cnf。如果使用操作系统的启动脚本,这通常是配置设置的唯一位置。如果手动启动MySQL(在运行测试安装时可能会这样做),还可以在命令行上指定设置。服务器实际上会读取配置文件中的内容,删除其中的注释行和换行符,然后将其与命令行选项一起处理。
术语说明
因为MySQL的很多命令行选项和服务器变量是对应的,所以我们有时会交替使用选项option)和变量(variable)这两个术语。大多数变量与其对应的命令行选项具有相同的名称,但也有一些例外。例如,--memlock命令行选项可以设置locked_in_memory变量。
注意:
需要永久使用的任何设置都应该写入全局配置文件,而不是在命令行中指定。否则会有风险,可能会在没有指定命令行选项的情况下意外启动服务器。将所有配置文件保存在一个地方也是一个好主意,这样可以方便地检查它们。
一定要知道服务器的配置文件在哪里!我们已经看到有人尝试用一个不能读取的文件来配置服务器,但没有成功,比如,Debian服务器上默认不存在/etc/my.cnf,而是会在/etc/mysql/my.cnf中查找配置。有时文件位于多个位置,这可能是因为以前的系统管理员也搞混了。如果不知道服务器会读取哪些文件,可以通过如下命令查询:
$ which mysqld$ /usr/sbin/mysqld --verbose --help / grep -A 1 'Default options'
配置文件采用标准INI格式,被分为多个部分,每个部分都以一行包含在方括号中的该部分名称开头。MySQL程序通常会读取与该程序同名的部分,很多客户端程序也会读取client部分,这为你提供了放置公共设置的位置。服务器通常读取mysqld部分。确保将设置放在文件的正确部分,否则它们将不起作用。
语法、作用域和动态性
配置设置全部用小写字母书写,单词之间以下画线或短横线分隔。这两种写法是等效的,你可能会在命令行和配置文件中看到下面的写法:
/usr/sbin/mysqld --auto-increment-offset=5 /usr/sbin/mysqld --auto_increment_offset=5
选择一种风格并始终如一地使用它。这使得在文件中搜索设置更容易。
配置设置可以有多个作用域。有些设置是服务器范围的(全局作用域),有些设置对于每个连接都不同(会话作用域),有些设置是基于每个对象的。许多会话作用域的变量都有相应的全局变量,可以将相应的全局变量的值视为会话变量的默认值。如果更改会话作用域的变量,它只会影响更改该变量的连接,在连接关闭时更改将丢失。以下是一些例子,
需要注意各个例子中的不同行为:
● max_connections变量是全局作用域的。
● sort_buffer_size变量有一个全局默认值,但是也可以在每个会话中设置。
● join_buffer_size变量具有全局默认值,可以在每个会话中设置,但是多表联接查询
可以为每个联接操作分配一个连接缓冲区,所以每个查询可能有多个联接缓冲区。除了在配置文件中进行设置外,很多变量(但不是全部)还可以在服务器运行时进行更改。MySQL将这些称为动态配置变量。以下语句显示了动态更改sort_buffer_size的会话和全局值的不同方法:
SET sort_buffer_size = <value>; SET GLOBAL sort_buffer_size = <value>; SET @@sort_buffer_size := <value>;SET @@session. sort_buffer_size := <value>; SET @@global.sort_buffer_size := <value>;
请注意,动态设置的变量在MySQL重启后会失效。如果要保留设置,必须更新配置文件。如果在服务器运行时设置变量的全局值,则当前会话和其他现有会话的值将不受影响。如果客户端依赖数据库长连接,请务必记住这一点。这是因为在创建连接时,会话值是从全局值初始化的。在每次更改后应该检查 SHOW GLOBAL VARIABLES 的输出,以确保其达到预期效果。
还可以使用SET命令为变量指定一个特殊值:关键字DEFAULT。将会话作用域变量设置为DEFAULT会将该变量设置为相应的全局作用域变量的值。如果想将会话作用域的变量重置为创建连接时的值,这么设置非常方便。建议不要将它用于全局变量,因为它可能不会实现想要的效果,也就是说,它不会将值设置为启动服务器时的值,甚至不会设置为配置文件中指定的值,它会将变量设置为默认编译的值。
持久化系统变量
了解所有这些变量作用域和配置方法还不够,你还必须知道,如果重新启动MySQL,即使使用了SET GLOBAL来更改全局变量,它也将恢复到配置文件中的状态。这意味着必须同时管理MySQL的配置文件和运行时配置,并确保它们保持同步。如果要增加服务器的最大连接数max_connections,必须在每个正在运行的实例上执行SET GLOBAL max_connections命令,然后编辑配置文件以反映新配置。
MySQL 8.0引入了一个名为持久化系统变量的新功能(参见链接18 https://oreil.ly/ZDwXZ),这有助于简化这个问题。新的语法SET PERSIST允许在运行时设置一次值,MySQL将把这个设置写入磁盘,以便在下次重启后继续使用该值。
设置变量的副作用
动态设置变量可能会产生意想不到的副作用,例如,引起缓冲区刷新脏块。在线更改设置时要小心,可能会导致服务器执行大量工作。
有时可以从变量的名称推断变量的行为。例如,max_heap_table_size指定了内存中隐式临时表允许增长到的最大大小。然而,命名约定并不完全一致,因此不能总是通过查看变量名来猜测它会做什么。
让我们看一些常用的变量以及动态更改这些变量的效果。
table_open_cache
设置此变量不会立即生效:下一次线程打开表时,MySQL会检查变量的值。如果该值大于缓存中的表的数目,线程可以将新打开的表插入缓存。如果该值小于缓存中的表的数目,MySQL将从缓存中删除未使用的表。
thread_cache_size
设置此变量不会立即生效:下一次关闭连接时,MySQL会检查缓存中是否有空间来存储线程。如果有,则缓存线程以供其他连接将来重用。如果没有,则将线程终止而不是缓存它。在这种情况下,缓存中的线程数量,以及线程缓存使用的内存量不会立即减少;只有当一个新连接从缓存中删除一个线程以使用它时,内存量才会降低。
(MySQL仅在连接关闭时将线程添加到缓存中,并仅在创建新连接时将其从缓存中删除。)
read_buffer_size
只有当查询需要时,MySQL才会为该缓冲区分配内存,而且会立即分配此变量指定的整块内存。
read_rnd_buffer_size
在查询需要之前,MySQL不会为该缓冲区分配任何内存。即时查询需要也只会分配所需要的内存(max_read_rnd_buffer_size这样的名字才能更准确地描述该变量)。
MySQL的官方文档详细解释了这些变量的作用,但并不是一个详尽的列表。我们在这里的目标只是展示更改一些常见变量时会出现什么行为。
除非知道这样做是正确的,否则不应该全局地提高每个连接设置的值。有些缓冲区是一次性分配的,即使它们并不需要,所以一个大的全局设置可能是一个巨大的浪费。相反,可以在查询需要时提高该值。
规划变量的更改
设置变量时要小心。并不总是越多越好,如果将值设置得太高,则很容易导致问题:可能会耗尽内存或导致服务器使用交换区。
回到第2章,监控你的SLO,以确保更改不会影响客户体验。只做基准测试是不够的,因为这不是真实的生产环境。如果你不测量服务器的实际性能,可能会在不知不觉中损害性能。我们看到过很多情况,有人改变了服务器的配置,并认为它提高了性能,而实际上,由于一天或一周中不同时间的不同工作负载,服务器的性能总体上有所下降。
理想情况下,应该使用版本控制系统来跟踪配置文件的更改。这种策略可以非常有效地将性能变化或SLO不达标与特定配置更改关联起来。请注意,在默认情况下,只更改配置文件实际上不会做任何事情,还必须更改运行时设置。
在开始更改配置之前,应该优化查询和schema,至少解决一些显而易见的问题,比如添加索引。如果深入调整了配置,但之后又更改了查询或schema,则可能需要重新评估配置。请记住,除非你的硬件、工作负载和数据完全是静态的,否则需要在变化后重新审视配置。事实上,大多数人的服务器在一天中甚至没有稳定的工作负载,这意味着早上八九点的“完美”配置可能不适合下午三点时的情况!显然,追求神话般的“完美”配置是完全不切实际的。因此,不需要去榨干服务器的每一点性能;事实上,这种时间投资的回报可能很小。我们建议专注于优化峰值工作负载,然后在“足够好”的时候就可以停止优化,除非你有理由相信正在放弃显著的性能改进。
什么不该做
在开始服务器配置之前,我们建议你避免一些常见的做法,这些做法有风险,或者实际上不值得这么做。警告:前方有咆哮声!
你可能会被期望(或相信你会被期望)建立一个基准测试套件,并通过迭代修改配置来“调优”服务器,以寻找最佳设置。我们通常不建议大家去做这样的事情。它需要大量的工作和研究,而且大多时候,潜在的回报非常小,因此是巨大的时间浪费。最好把这些时间花在其他事情上,比如检查备份、监控查询计划的变化等。
你不应该“按比率调优”。经典的“调优比率”是一个经验法则,比如,InnoDB缓冲池命中率应该高于某个百分比,如果命中率过低,应该增加缓存大小。这是非常错误的建议。不管别人怎么说,缓存命中率与缓存是太大还是太小无关。首先,命中率取决于工作负载--不管缓存有多大,有些工作负载根本不能被缓存——其次,缓存命中是没有意义的,原因我们将在后面解释。有时会出现缓存太小,出现命中率很低的情况,增加缓存大小会增加命中率。然而,这是一种偶然的关联,并不表示缓存的性能或大小是适当的。
相关性有时看似正确,但问题在于人们容易相信它们永远是正确的。Oracle DBA在几年前就放弃了基于比率的调优,我们希望MySQL DBA也能跟随他们的脚步。 (如果你不相信“按比率调优”是不好的,请阅读Cary Millsap和Jeff Holt编写的Optimizing OraclePerformance。他们甚至专门为这个主题写了一个附录,里面有一个工具,可以人为地生成你想要的任何缓存命中率,无论你的系统性能有多差!当然,这一切都是为了说明这个比率是多么无用) 我们甚至更强烈地希望人们不要编写“调优脚本”来将这些危险的实践编入法典,并将它们传授给成千上万的人。这就引出了我们“什么不该做”的下一个建议:不要使用调优脚本!可以在网上找到一些非常流行的脚本,但最好还是忽略它们。
我们还建议你避免使用调优这个词,在前几段文字中大量使用了这个词。我们更倾向于用配置或优化(只要这是你实际在做的)。一提到调优,人们就会联想到一名不守纪律的新手,他调整了服务器,然后看看会发生什么。我们在前一节中建议,这个实践最好留给那些研究服务器内部结构的人。“调优”服务器可能是一种惊人的时间浪费。
在互联网上搜索配置建议并不总是一个好主意,你会在博客、论坛等找到很多糟糕的建议。尽管许多专家在网上贡献了他们所知道的,但很难判断谁是真正的专家。当然,对于去哪里找真正的专家,我们无法给出公正的建议。但是我们可以说,可靠的、有信誉的MySQL服务提供商通常比简单的互联网搜索结果更安全,因为那些需要拥有满意的客户的人可能正在做正确的事情。然而,即使是他们的建议,在没有经过测试和理解的情况下进行应用也可能是危险的,因为它可能针对的是一种与你不同的情况,而你却没有理解。
最后,不要相信流行的内存消耗公式——是的,MySQL本身在崩溃时会输出的那个公式。(这里我们就不重复了。)这个公式是很早之前的。这不是一个可靠的,甚至不是一个有用的方法来了解MySQL在最坏的情况下可以使用多少内存。你也可以在网上看到这个公式的一些变体。这些公式都有类似的缺陷,尽管它们添加了更多原公式所没有的因素。事实是,你不能给MySQL的内存消耗设定上限。MySQL并不是一个严格控制内存分配的数据库服务器。
创建MySQL配置文件
正如我们在本章开头提到的,没有一个适合所有人的“最佳配置文件”,比如一个针对4CPU、16 GB内存和12块硬盘驱动器的服务器配置。你确实需要开发自己的配置,因为根据你使用服务器的方式,即使是一个良好的基础配置也会有很大的差异。
最小化配置
创建一个最小化的示例配置文件,你可以将其用作自己服务器的良好起点(请注意,MySQL的不同版本会删除、弃用和更改一些选项,欲了解详细信息请查看相关文档)。 你必须为一些设置选择值,我们将在本章后面对此进行解释。我们的基础文件是围绕MySQL 8.0构建的,如下所示:
[mysql] # 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] skip-name-resolve #设置3306端口 port = 3306 # 设置mysql的安装目录,如果是源码安装则是安装的目录, # 如果是二进制安装则是解压的目录!!! basedir=/opt/mysql8/mysql8 # 设置mysql数据库的数据的存放目录,需要进行自建 datadir=/opt/mysql8/mysql8/mydata # 允许最大连接数 max_connections=200 # 服务端使用的字符集默认为8比特编码的latin1字符集,UTF8Mb4 是别名相当于是utf8 character_set_server=UTF8Mb4 init-connect='set names utf8' # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB max_allowed_packet=16M #配置serverid server-id=1 # 设置默认的 密码校验插件 default_authentication_plugin=mysql_native_password # 不区分大小写 lower_case_table_names=1 # 错误消息使用的语言 lc-messages-dir=/opt/mysql8/mysql8/share [mysqld_safe] # 错误日志,需要进行创建 log-error=/opt/mysql8/mysql8/errlog/mysqld.log # 设置PID 的路径,需要进行创建 pid-file=/opt/mysql8/mysql8/pid/mysqld.pid [client]
与经常看到的配置文件相比,这可能看起来内容太少了,但实际上已经超过了很多人的需要。你可能还会使用一些其他类型的配置选项,例如,二进制日志记录,我们将在本章的后面及其他章节中介绍这些内容。
我们配置的第一个变量是数据存放的位置。我们将其设置为/var/lib/mysql,因为它在许多UNIX变体中都很流行。选择另外的位置也没有问题,这由你决定。我们把.pid文件也放置在相同的位置,但很多操作系统默认将其放在/var/run,这也没有问题。我们只需要为这些设置配置一些东西。顺便说一句,不要让socket和.pid文件使用服务器编译的默认值;在不同的MySQL版本中有一些bug,使用默认值可能会导致问题,所以最好显式设置。(我们不是建议选择不同的地点,只是建议确保my.cnf文件明确地设置了这些位置,这样当升级服务器时它们就不会改变或引起问题。)
我们还指定了在操作系统上以mysql账号运行mysqld。你需要确保这个账号存在,并且确保数据目录和其中的所有文件的属主是这个账号。端口设置为默认的3306,但有时也需要更改。
在MySQL 8.0中引入了一个新的配置选项,innodb_dedicated_server。这个选项检查服务器上可用的内存,并为专用的数据库服务器配置了4个额外的变量(innodb_buffer_pool_size、innodb_log_file_size、innodb_log_files_in_group和innodb_flush_method),从而简化这些值的计算和更改。这在云环境中特别有用,在云环境中,你可以运行一个128G B内存的虚拟机(V M),然后重新启动以扩展到256G B内存。这种情况下MySQL是自配置的,不需要管理配置文件中的值的修改。这通常是管理这4个设置的最佳方式。
在我们的示例文件中,大多数其他设置都是不言自明的,其中许多都是判断问题。我们将在本章的其余部分探讨其中的几个。我们还将在本章的后面讨论一些安全设置,这些设置有助于提高服务器的健壮性,并有助于防止错误数据和其他问题。这里我们先暂且略过。
还要解释的一个设置是open_files_limit选项。在典型的Linux系统中,我们将其设置得尽可能大。在现代操作系统中,打开文件句柄的成本很低。如果这个设置不够大,就会看到经典的24号错误,“too many open files”。
跳到最后,配置文件中的最后一部分是针对mysql和mysqladmin等客户端程序的,让它们知道如何连接到服务器。应该为客户端程序设置与服务器相匹配的值。
检查MySQL服务器的状态变量
有时,你可以使用SHOW GLOBAL STATUS的输出作为配置的输入,以更好地为工作负载定制设置。为了获得最佳结果,请查看绝对值以及值如何随时间变化,最好在峰值和非峰值时间做几次快照。可以使用以下命令查看状态变量每60秒的增量变化:
在解释各种配置设置时,我们会经常提到状态变量随时间的变化。我们通常希望你检查一个命令的输出,比如刚才展示的命令。其他一些有用的工具如Percona Toolkit的pt-mext或pt-mysql-summary可以提供状态计数器变化的紧凑显示。
我们已经向你展示了一些初步内容,接下来将带你查看一些服务器内部组件,并附带一些配置建议。这将为你提供必要的背景知识,以便为配置选项选择适当的值,稍后将返回示例配置文件进行配置。
$ mysqladnin extended-status -ri60
配置内存使用
使用innodb_dedicated_server通常会占用50%~75%的内存。这样,至少有25%的内存可用于每个连接的内存分配、操作系统开销和其他内存设置。我们将在下面逐一介绍这些内容,然后更详细地了解各种MySQL缓存的需求。
每个连接的内存需求
MySQL只需要少量的内存就能保持一个连接(通常是一个相关的专用线程)打开。它还需要基本内存量来执行任何给定的查询。你需要为MySQL留出足够的内存,以便在负载高峰期执行查询,否则查询将因内存不足而无法正常运行或失败。
了解MySQL在峰值使用期间将消耗多少内存是很有用的,但是一些使用模式可能会意外地消耗大量内存,这使得内存消耗很难预测。预处理语句就是一个例子,因为可以同时打开多个预处理语句。另一个例子是InnoDB数据字典(稍后将详细介绍)。
在试图预测内存消耗峰值时,不需要假设最坏的情况。例如,如果将MySQL配置为最多允许100个连接,理论上可以同时在所有100个连接上运行大型查询,但实际上这不太可能会发生。使用许多大型临时表或复杂存储过程的查询最有可能占用大量内存。
为操作系统保留内存
与查询一样,需要为操作系统保留足够的内存以完成其工作。这包括运行任何本地监控软件、配置管理工具、计划作业等。操作系统有足够内存的最佳判断依据是,它没有主动将虚拟内存交换(分页)到磁盘。
InnoDB缓冲池
InnoDB缓冲池需要的内存比其他任何组件都多,就性能而言,InnoDB缓冲池大小通常是最重要的变量。InnoDB缓冲池不仅缓存索引,还缓存行数据、自适应哈希索引、更改缓冲区、锁和其他内部结构等。InnoDB还使用缓冲池来实现延迟写操作,从而可以将多个写操作合并在一起并按顺序执行。简而言之,InnoDB严重依赖缓冲池,应该确保为其分配足够的内存。你可以使用SHOW命令或innotop等工具中的变量来监控InnoDB缓冲池的内存使用情况。
如果数据不多,并且不会快速增长,那么也不需要将内存过度分配给缓冲池。让缓冲池大大超过其所容纳的表和索引的大小并不会有额外的好处。当然,为一个快速增长的数据库提前规划,设置更大的缓冲池并没有错,但有时我们会看到巨大的缓冲池中只有少量数据,这是没有必要的。
大型缓冲池会带来一些挑战,比如更长的关闭时间和预热时间。如果缓冲池中有很多脏(修改过的)页,InnoDB可能需要很长时间才能关闭,因为它会在关闭时将脏页写到数据文件中。当然也可以强制快速关闭,但在重新启动时,InnoDB需要做更多的恢复工作,因此实际上不能加快关闭和重新启动周期时间。如果提前知道什么时候需要关闭,可以在运行时将innodb_max_dirty_pages_pct变量更改为较低的值,等待刷新线程清理缓冲池,然后在脏页数量变少时关闭。可以通过监控innodb_buffer_pool_pages_dirty服务器状态变量或使用innotop监控SHOW INNODB STATUS来查看脏页数量。还可以使用变量innodb_fast_shutdown来调整关闭InnoDB的方式。
降低innodb_max_dirty_pages_pct变量的值并不能保证InnoDB在缓冲池中保留更少的脏页。相反,它控制的是InnoDB停止“lazy”行为的阈值。InnoDB默认使用同一个后台线程来刷新脏页,以及合并写操作并按顺序执行以提高效率。这种行为被称为“lazy”,因为它允许InnoDB延迟刷新缓冲池中的脏页,除非需要为其他数据提供空间。当脏页的百分比超过阈值时,InnoDB会尽可能快地刷新页面,以尽量降低脏页的数量。与之前的行为相比,这些页面清理操作已经得到了极大的优化(参见链接19 https://oreil.ly/S8ong),包括能够配置多个线程来执行刷新。
当MySQL再次启动时,缓冲池缓存是空的,也称为冷缓存。在内存中保存行和页的所有好处现在都没有了。值得庆幸的是,默认情况下,innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup这两个配置可以配合使用,以在启动时预热缓存池。启动时的加载需要时间,但它可以比等待服务器自然填充缓冲池更快地提高性能。
线程缓存
线程缓存保存了当前没有与连接关联但已准备好为新连接提供服务的线程。创建新连接时,如果缓存中有一个线程,MySQL会从缓存中取出该线程并将其提供给新连接。当连接关闭时,如果缓存中还有空间,MySQL会将线程放回缓存中。如果缓存中已经没有空间,MySQL会销毁线程。只要MySQL在缓存中有空闲线程,它就可以快速响应连接请求,因为不必为每个新连接创建新线程。
变量thread_cache_size指定了MySQL可以保存在缓存中的线程数。其默认值为-1或auto-
sized,通常不需要更改这个变量,除非服务器会收到很多连接请求。要检查线程缓存是否足够大,请查看Threads_created状态变量。应该尽量保持线程缓存足够大,以使每秒创建的新线程数少于10个,但通常很容易使这个数字低于每秒1个。
一个好的方法是观察Threads_connected变量,并尝试将thread_cache_size设置得足够大,以处理工作负载中的典型波动。例如,如果Threads_connected通常保持在100到120之间,那么可以将缓存大小设置为20。如果停留在500到700之间,那么将缓存大小设置为200也足够大了。可以这样想:当同时有700个连接时,缓存中线程全部用光,当只有500个连接时,将有200个缓存线程作为备用,即便工作负载随后再增加到700也够用了。
对于大多数使用场景来说,不需要将线程缓存设置得非常大,但是将线程缓存设置得很小也不会节省太多内存,所以这样做没有什么好处。每个处于线程缓存或休眠状态的线程通常使用大约256KB内存。这与活动连接在处理查询时线程可以使用的内存量相比并不多。
通常应该保持线程缓存足够大,这样Threads_created就不会经常增加。但是,如果这是一个非常大的数字(例如,成千上万个线程),可能需要将其设置得更低一些,因为一些操作系统不能很好地处理大量线程,即使这些线程大部分处于休眠状态。
上一篇:《第4章-5 linux 网络管理》
下一篇:
相关文章:
第5章-1 优化服务器设置
上一篇:《第4章-5 linux 网络管理》,接着服务器设置 本章我们将解释如何为MySQL服务器创建合适的配置文件。这是一个迂回的旅程,有许多兴趣点和可以俯瞰风景的短途旅程。这些短途旅程是必要的。确定合适配置的最短路径并不是从研究配置选项并…...
进阶篇 第 4 篇:驾驭季节性波动 - SARIMA 模型实战
进阶篇 第 4 篇:驾驭季节性波动 - SARIMA 模型实战 (图片来源: Pixabay on Pexels) 在上一篇中,我们深入探索了经典的 ARIMA(p,d,q) 模型。它通过整合自回归 (AR)、差分 (I) 和移动平均 (MA) 提供了一个强大的框架来对(处理后)平…...
Android调用springboot接口上传大字段,偶现接口超时的优化
介绍 最近有个功能,Android通过okhttp上传实体类,实体类包含一个大字段,上传的字符串长度达到300k,偶现接口超时的情况,大概100次有5次,看日志发现数据并没有到达接口,可能在网络传输中就超时了…...
[特殊字符]【Qt自定义控件】创意开关按钮 - 丝滑动画+自定义样式+信号交互 | 附完整源码
话不多说直接上代码 1、.mybutton.h #ifndef MYBUTTON_H #define MYBUTTON_H#include <QWidget> #include <QPropertyAnimation>class MyButton : public QWidget {Q_OBJECT public:explicit MyButton(QWidget *parent nullptr);protected:void paintEvent(QPain…...
大数据开发的基本流程
大数据开发通常围绕数据的“采集 → 存储 → 处理 → 分析 → 展示”几个阶段来展开。下面是一个典型的大数据开发基本流程(适用于离线或实时场景): 一、数据采集(Data Ingestion) 目标:从各种来源采集原始…...
关于创建UNIX/Linux daemon进程的笔记
Linux daemon程序简单说就是Linux后台服务进程。 传统的、标准的创建方法:2次fork setsid 详细步骤 进程1(父进程)调用fork,创建子进程2,进程1退出。 1)这个步骤是为第二部做铺垫。 2)此时&a…...
国产紫光同创FPGA实现SDI视频编解码,基于HSSTHP高速接口,提供3套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目本博已有的 SDI 编解码方案本方案在Xilinx--Artix7系列FPGA上的应用本方案在Xilinx--Kintex系列FPGA上的应用本方案在Xilinx--Zynq系列FPGA上的应用本方案在Xilinx--U…...
Oracle--SQL性能优化与提升策略
前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除 一、导致性能问题的内在原因 系统性能问题的底层原因主要有三个方面: CPU占用率过高导致资源争用和等待内存使用率过高导致内存不足并需…...
drupal7可以从测试环境一键部署到生产环境吗
Drupal 7 本身并没有“内建的一键部署功能”,所以“从测试环境一键部署到生产环境”不能完全自动化完成,尤其是涉及数据库、配置和文件系统时。但你可以通过一些工具和方法实现接近“一键部署”的效果 ✅ 🚧 为什么不能直接一键部署ÿ…...
vue项目中axios统一或单独控制接口请求时间
先说统一 这里将请求时间统一控制在12秒 // 使用由库提供的配置的默认值来创建实例 // 此时超时配置的默认值是 0 const axiosInstance axios.create()// 覆写库的超时默认值 // 现在,在超时前,所有请求时间统一控制在10秒 axiosInstance.defaults.ti…...
chromedp 反反爬设计方案
二、基础防护层实现 1. 浏览器特征伪装 opts : append(chromedp.DefaultExecAllocatorOptions[:],// 禁用自动化特征chromedp.Flag("disable-blink-features", "AutomationControlled"),chromedp.Flag("useAutomationExtension", false),// 随…...
OpenLDAP 管理 ELK 用户
文章目录 一、新建 ELK 相关用户组二、配置 Elasticsearch2.1 修改 elasticsearch.yml 配置2.2 使用 API 接口建立角色和用户映射 三、Kibana 验证用户登录 一、新建 ELK 相关用户组 由于后续要将 LDAP 的用户与 ELK 的角色进行映射,所以需先创建几个以 ELK 的角色…...
深度解析MQTT源码架构与AIGC场景融合实战
一、结构体内存优化:支撑千万级设备连接 1.1 紧凑内存布局设计 classDiagramclass MQTTClient_message {char struct_id[4]int struct_versionvoid* payloadint payloadlenint qosint retainedint dupint msgidMQTTProperties properties}note for MQTTClient_mes…...
Node.js 操作 ElasticSearch 完整指南:从安装到实战
本文将手把手教你如何搭建 ElasticSearch 环境,并通过 Node.js 实现高效数据检索。包含 10 个可直接复用的代码片段,助你快速掌握搜索、聚合等核心功能! 环境搭建篇 1. ElasticSearch 安装要点 下载 es下载连接 下载下来后,进…...
Python+区块链:如何打造智能化资产管理系统?
Python+区块链:如何打造智能化资产管理系统? 在当今数字经济时代,区块链资产管理已成为金融科技、去中心化金融(DeFi)以及企业资金流转的关键应用。传统的资产管理往往依赖于中心化机构,存在数据透明度低、效率受限、管理成本高等问题,而区块链技术的出现,为资产管理提…...
Sentinel源码—8.限流算法和设计模式总结一
大纲 1.关于限流的概述 2.高并发下的四大限流算法原理及实现 3.Sentinel使用的设计模式总结 1.关于限流的概述 保护高并发系统的三把利器:缓存、降级和限流。限流就是通过限制请求的流量以达到保护系统的目的,比如秒杀抢购。具体就是对并发请求进行限…...
SpringMVC入门
1、SpringMVC概念 SpringMVC是在Spring框架的基础上引入MVC模式的思想,SpringMVC即是一种框架,也是一种思想,将前后端彻底分离,后端不再需要关注前端的代码。前后端分工明确 我们原先学习的MVC三层架构,MVC是web开发…...
MYSQL之库的操作
创建数据库 语法很简单, 主要是看看选项(与编码相关的): CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] ...] create_specification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name 1. 语句中大写的是…...
并发设计模式实战系列(3):工作队列
🌟 大家好,我是摘星! 🌟 今天为大家带来的是并发设计模式实战系列,第三章工作队列(Work Queue),废话不多说直接开始~ 目录 一、核心原理深度拆解 1. 生产者-消费者架构 …...
已安装爱思助手和Apple相关驱动,但仍无法有线连接iPhone热点,且网络适配器没有Apple Mobile Device Ethernet,问题解决
已安装爱思助手和Apple相关驱动,但仍无法有线连接iPhone热点,且网络适配器没有Apple Mobile Device Ethernet 问题解决: 用爱思助手连接手机,点击工具箱 - iTunes及驱动 点击高级修复 在系统存储的旧驱动文件项右侧࿰…...
用 Go 优雅地清理 HTML 并抵御 XSS——Bluemonday
1、背景与动机 只要你的服务接收并回显用户生成内容(UGC)——论坛帖子、评论、富文本邮件正文、Markdown 等——就必须考虑 XSS(Cross‑Site Scripting)攻击风险。浏览器在解析 HTML 时会执行脚本;如果不做清理&#…...
MySQL基本查询与数据操作全面解析
目录 1. CRUD操作概述 2. Create操作详解 2.1 表的创建 2.2 单行数据插入 2.3 多行数据插入 2.4 插入冲突处理 3. Retrieve操作详解 3.1 基础查询 全列查询(慎用) 指定列查询 表达式查询 结果去重 3.2 条件查询(WHERE子句&#…...
《C++ 模板:泛型编程的核心》
C模板详解 模板是C中实现泛型编程的重要特性,它允许你编写与数据类型无关的代码。模板可以分为函数模板和类模板两种。 1. 函数模板 函数模板允许你定义一个可以处理多种数据类型的函数。 基本语法 template <typename T> T functionName(T parameter1, T…...
Web3实战:从零开发你的ERC20代币合约
区块链技术的普及让代币发行不再是金融巨头的专利。本文将以Solidity 0.8.20和OpenZeppelin 5.0为技术栈,手把手教你开发具备铸造、销毁、权限管理等进阶功能的ERC20代币,并部署到以太坊Sepolia测试网。以下是完整开发路线图: 一、ERC20代币的…...
简述大疆无人机对接
文章目录 概述MSDK对接MSDK简介MSDK集成步骤直播推流获取飞机实时数据 UX SDK上云API上云API简介上云API对接步骤Pilot上云Pilot怎么安装配置三方云平台地址直播获取飞机数据 Dock上云Dock上云简介直播方案设备管理 如何对接多个飞机引用 概述 一般而言,对接大疆的…...
docker-compose搭建kafka
1、单节点docker-compose.yml version: 3 services:zookeeper:image: zookeeper:3.8container_name: zookeeperports:- "2181:2181"volumes:- ./data/zookeeper:/dataenvironment:ZOO_MY_ID: 1ZOO_MAX_CLIENT_CNXNS: 100kafka:image: bitnami/kafka:3.7container_na…...
FramePack V2版 - 支持首尾帧生成,支持LoRA,支持批量,支持50系显卡,一个强大的AI视频生成软件 本地一键整合包下载
FramePack 是斯坦福大学主导开发的视频生成框架,是一种用于视频生成的下一帧(下一帧部分)预测神经网络结构,可以逐步生成视频。FramePack 主要开发者之一,就是业内大名鼎鼎的张吕敏大佬,AI领域的“赛博佛祖…...
开发网页程序时预览时遇到跨域问题解决方法
CocosCreator 开发h5游戏要用接口、开发html程序网页程序在chrome中预览时都会遇到跨域问题,怎么办? 网上有很多方法,主要是通过服务器端去配置,但那个相对来说消弱安全问题,这个不建议,因为是开发,个人行业,我们知道问题所以,简单点就主要是通过chrome的参数来禁用: 关闭 Ch…...
【音视频】FFmpeg内存模型
FFmpeg内存模型 从现有的Packet拷贝一个新Packet的时候,有两种情况: 两个Packet的buf引用的是同一数据缓存空间,这时候要注意数据缓存空间的释放问题;两个Packet的buf引用不同的数据缓存空间,每个Packet都有数据缓存…...
基于nlohmann/json 实现 从C++对象转换成JSON数据格式
C对象的JSON序列化与反序列化 基于JsonCpp库实现C对象序列化与反序列化 JSON 介绍 JSON作为一种轻量级的数据交换格式,在Web服务和应用程序中广泛使用。 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读…...
在线视频转 AVI 的便捷之选,便捷操作,无需下载软件,在线使用
在视频处理的众多需求中,将视频转换为 AVI 格式是不少用户的刚需。小白工具网(https://www.xiaobaitool.net/videos/convert-to-avi/ )的在线视频转 AVI 功能,以其显著优势,多格式支持、便捷操作、数据安全保障以及广泛…...
【MCP Node.js SDK 全栈进阶指南】初级篇(3):MCP资源开发基础
引言 在前两篇文章中,我们已经详细介绍了MCP开发环境的搭建以及基础服务器开发。本文作为MCP TypeScript-SDK系列的第三篇,将聚焦于MCP资源开发基础,包括静态资源与动态资源的开发、资源模板设计与参数提取、资源列表与发现机制,以及常见资源类型与最佳实践。通过本文的学…...
L2-1、打造稳定可控的 AI 输出 —— Prompt 模板与格式控制
一、为什么需要 Prompt 模板? 在与 AI 模型交互时,我们经常会遇到输出不稳定、格式混乱的问题。Prompt 模板帮助我们解决这些问题,通过结构化的输入指令来获得可预测且一致的输出结果。 模板的作用主要体现在: 固定输出格式&am…...
Java集成Zxing和OpenCV实现二维码生成与识别工具类
Java集成Zxing和OpenCV实现二维码生成与识别工具类 本文将介绍如何使用Java集成Zxing和OpenCV库,实现二维码的生成和识别功能。识别方法支持多种输入形式,包括File对象、文件路径和Base64编码。 一、环境准备 添加Maven依赖 <dependencies><…...
jenkins pipeline ssh协议报错处理
一、jenkins版本 jenkins:2.492.3 openssh:OpenSSH_9.8p1, OpenSSL 3.3.1 # grep jenkins /etc/passwd jenkins:x:996:994:Jenkins Automation Server:/var/lib/jenkins:/bin/false 二、报错 三、处理 步骤1:手动添加目标主机密钥到Jenk…...
当OCR遇上“幻觉”:如何让AI更靠谱地“看懂”文字?
在数字化的世界里,OCR(光学字符识别)技术就像给机器装上了“电子眼”。但当这项技术遇上大语言模型,一个意想不到的问题出现了——AI竟然会像人类一样产生“幻觉”。想象一下,当你拿着模糊的财务报表扫描件时ÿ…...
vue watch监听路由,第一次进入不触发解决办法
“第一次进入的时候没触发,第二次就触发了”非常典型,它印证了路由监听(无论是 watch $route 还是 beforeRouteUpdate)主要是为了监听变化,而不是处理首次加载时的初始状态。 当你通过 this.$router.push 导航到一个新…...
JVM考古现场(二十四):逆熵者·时间晶体的永恒之战
"警告!时间晶体正在吞噬GC日志!" 我腰间的太极八卦镜突然迸发出刺目的量子辉光,终南山之巅的星宿大阵浮现出诡异的四维克莱因瓶拓扑——这是逆熵者文明穿越时空的拜帖! 楔子:时间晶体的觉醒 🕯️…...
spring中使用netty-socketio部署到服务器(SSL、nginx转发)
spring中使用netty-socketio部署到服务器(SSL、nginx转发) 本文实现前端socket.io-client连接后端netty-socketio,并且部署到服务器上的示例,以及说明一些实现过程中可能遇到的错误。 socketio默认基于的路径是/socket.io 传输…...
qt.tlsbackend.ossl: Failed to load libssl/libcrypto.
我的环境是windows,QT6.3.2(msvc2019_64/mingw_64) 出错原因 QT没有正确加载OpenSSL。 解决过程 1、确保安装的有openssl。 文章结尾有个注意,是其他方式安装过openssl,环境变量有,但是QT找不到的问题。…...
【Python爬虫基础篇】--3.cookie和session
目录 1.cookie 1.1.定义 1.2.参数 1.3.分类 2.session 3.使用cookie登录微博 4.使用session登录 1.cookie 由于http是一个无状态的协议,请求与请求之间无法相互传递或者记录一些信息,cookie和session正是为了解决这个问题而产生。 例子࿱…...
uView的u-modal不显示问题
问题分析:在项目中,其他页面显示正常,在这个页面显示不正常。 问题解决: 一般的原因,诸如层级遮挡控制器true后,被其他逻辑又改为了false最可恨的一个原因 :showshow被编辑器的提示功能误写成了v-modal&qu…...
联易融科技:以科技赋能驱动经营反转与价值重估
行业去重周期下,轻量化发展成破局关键。当前,供应链金融行业正经历从"规模扩张"到"价值深耕"的转型期,降本增效、轻资产运营成为行业共识。联易融公告表示,截至2024年末,公司现金储备高达51亿元,显示出财务状况健康良好,流动资金持续充裕。 董…...
Office文档图片批量提取工具
Office.Files.Images 是一款专注于从 Word、Excel、PPT 等 Office 文档中批量提取图片的轻量级工具,支持 .docx、.xlsx、.pptx 格式文件。该软件体积仅 343KB,无需安装即可运行,通过拖拽操作实现快速解析与导出,尤其适合需批量…...
Python 设计模式:回调模式
1. 什么是回调函数? 回调函数是指作为参数传递给另一个函数的函数。当这个函数执行到某个特定的点时,它会调用这个回调函数。回调函数通常用于处理异步操作、事件处理或在某些条件下执行特定的操作。 回调函数的特点: 作为参数传递&#x…...
DCDC芯片,boost升压电路设计,MT3608 芯片深度解析:从架构到设计的全维度技术手册
一、硬件架构解析:电流模式升压 converter 的核心设计 (一)电路拓扑与核心组件 MT3608 采用恒定频率峰值电流模式升压(Boost)转换器架构,核心由以下模块构成: 集成功率 MOSFET 内置 80mΩ 导通电阻的 N 沟道 MOSFET,漏极(Drain)对应引脚 SW,源极(Source)内部接…...
大数据学习(112)-HIVE中的窗口函数
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一…...
Hive学习
一、Hive 核心原理 1. Hive 架构与执行流程 Hive 是基于 Hadoop 的数据仓库工具,将 SQL 转化为分布式计算任务(MapReduce/Tez/Spark),核心组件如下: 元数据存储(Metastore):存储表…...
前端开发核心知识详解:Vue2、JavaScript 与 CSS
一、Vue2 核心知识点 1. Vue2 的双向绑定原理 Vue2 实现双向绑定主要依赖数据劫持与发布 - 订阅者模式。 利用Object.defineProperty方法对数据对象的属性进行劫持,为每个属性定义getter和setter。getter用于收集依赖,当视图中使用到该属性时…...
仅追加KV数据库
仅追加KV数据库 6.1 我们将要做什么 在本章中,我们将创建一个基于文件的键值存储(KV Store),其核心是一个写时复制(Copy-on-Write, CoW)B 树。这种设计的目标是实现数据的持久性和原子性。 1. 设计概述 …...