干货 | 解读MySQL 8.0新特性:网络模块优化

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 本文主要描述MySQL 8.0在网络模块的几个小优化, 由于本人对server层代码不熟悉,所以只是列出自己的理解和相关的patch以及worklog,不做深入详细实现的解释,感兴趣的可自行从连接中找到对应的代码。

640.gif

作者:阿里云数据库产品事业部

高级技术专家 印风


导读:

本文主要描述MySQL 8.0在网络模块的几个小优化, 由于本人对server层代码不熟悉,所以只是列出自己的理解和相关的patch以及worklog,不做深入详细实现的解释,感兴趣的可自行从连接中找到对应的代码。

Admin Port

运维大并发负载数据库的同学经常会碰到的情况是,max_connection被占满,甚至root账户都无法登陆上去,kill掉这些链接来让实例恢复正常。

Alibaba RDS MySQL的做法是把connection的个数拆分成不同的使用目的,例如系统维护账户占用一部分,用户账户占用一部分,两者不互相影响。

另外一种方式是比较高危的,通过gdb的方式直接进入进程去修改max_connection的值,但注意符号表要编译到mysqld里面,不然无法识别。

此外在mariadb/percona server的线程池实现里,也引入了extra port,当线程池用满无法登陆时,可以使用extra port来连上实例。

在MySQL 8.0里,则引入了admin port的概念,顾名思义,就是单独开一个端口给管理员用,该特性从8.0.14开始引入。可以说这是个对运维非常有用,关键时候可以救命的特性。这个feature由facebook贡献给上游

主要包含几个配置参数:

  • admin_address: 用于指定管理员发起tcp连接的主机地址,可以是ipv4,ipv6, 或者Host name等等,他类似bind-address,但不同的是只能接受一个ip地址
  • admin_port: 顾名思义,就是管理员用来连接的端口号,注意如果admin_address没有设置的话,这个端口号是无效的
  • create_admin_listener_thread: 是否创建一个单独的listener线程来监听admin的链接请求,默认值是关闭的,facebook的建议是打开,否则其会使用已有的监听线程去监听admin连接。该参数同样需要admin_address打开, 否则没有任何影响

注意必须要有权限SERVICE_CONNECTION_ADMIN(https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/privileges-provided.html)才能登陆该端口,否则会报错

根据文档描述2(https://dev.mysql.com/doc/refman/8.0/en/client-connections.html),admin port的连接个数不受max_connection或者Max_user_connection的限制。

参考文档

官方文档:

https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html

Administrative Connection Management:

https://dev.mysql.com/doc/refman/8.0/en/client-connections.html

WL#12138: Add Admin Port:

https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont700077.19.62b94216LfYbta&id=12138

相关代码:

https://github.com/zhaiwx1987/mysql-server/commit/56b48f3f75dbeb0584b96e9b7049b5d576852e95?spm=a2c4e.11153940.blogcont700077.20.62b94216LfYbta

Multiple addresses for the--bind-address

通常在大规模允许的实例上我们不会去设置bind-address, 但在特定场景下还是有用的。从MySQL8.0.13开始,可以通过bind-address设置多个网络地址,对应release note:

To enable the server to listen on a set of addresses, the bind_address system variable now permits a list of comma-separated IP addresses or host names, not just a single address or name. For details, see Server System Variables.

也就是说如果你想通过bind-address绑定多个地址,需要使用8.0.13及之后的版本, 当然在之前的版本你也可以指定为使用 * 来匹配多个地址。

可以混合指定Ipv4和ipv6的地址,例如:

bind_address=198.51.100.20,2001:db8:0:f101::1

参考文档

bind address参数说明

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html?spm=a2c4e.11153940.blogcont700077.21.62b94216LfYbta#sysvar_bind_address

WL#11652: Support multiple addresses for the --bind-address command option:

https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont700077.22.62b94216LfYbta&id=11652

相关代码:

https://github.com/zhaiwx1987/mysql-server/commit/b72b101aa9435c637e1aa6e29417f03b937bf296?spm=a2c4e.11153940.blogcont700077.23.62b94216LfYbta

Performance for connect/disconnect

这是一个性能优化,尤其是针对频繁断开链接的短连接。这是因为MySQL里是使用一个全局大锁来保护LOCK_thd_list和LOCK_thd_remove来保护链接链表的。

优化的思路其实很简单直接:就是分区。所有的包括锁,链接链表,COND_thd_list都被分成8个分区(hardcode, 无法配置)来减少冲突, 根据thread id来分区。唯一的负面影响就是出于监控目的,可能performance schema需要获取全部分区来获得线程信息,但通常这是可以容忍的。

参考文档

WL#9250: Split LOCK_thd_list and LOCK_thd_remove mutexes:

https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont700077.24.62b94216LfYbta&id=9250

相关代码:

https://github.com/zhaiwx1987/mysql-server/commit/58187639671bf5266bd755dc84d2649b7296d664?spm=a2c4e.11153940.blogcont700077.25.62b94216LfYbta

Remove metadata from resultset

这是个老话题了,我们知道在mysql返回的结果集了除了用户的数据外,还包含了库,表名,列名,甚至表列的别名等信息,这些信息占据了返回值的很大一部分网络包开销,特别的,当你需要是点查询时,可能你的返回包的元数据要远远大于你需要的数据,而多数情况下,你并不需要这些元数据

例如当你返回n个列时,元数据包含:

- column count (n);
- n * column definitions

而每个column definition包含:

- catalog
- schema
- table alias
- table
- column alias
- column name
etc.

8.0版本里,你可以选择的移除resultset的metadata,通过参数resultset_metadata来控制,不过当我登陆终端,想设置这个参数时 却报错:

root@(none) 10:15:27>set session resultset_metadata = 'none';
ERROR 3640 (HY000): The client doesn't support optional metadata transfer

这是因为标准客户端的连接没有打开选项CLIENT_OPTIONAL_RESULTSET_METADATA,如果您使用C API,可以通在调用mysql_real_connect时把该flag设置到参数client_flag中,这样你就可以可选的设置这个session级别参数来关闭metadata了.

实际上在大概2012年左右,twitter mysql也做过类似的尝试,我在14年也做过类似的尝试,当时的测试结果如下:

After porting twitter’s patch ( Great thanks to Davi Arnaut) to MySQL5.6.16, I slightly changed it to make protocol_mode support more options:

0/METADATA_FULL: return all metadata, default value.
1/METADATA_REAL_COLUMN: only column name;
2/METADATA_FAKE_COLUMN: fake column name ,use 1,2...N instead of real column name
3/METADATA_NULL_COLUMN: use NULL to express the metadata information
4/METADATA_IGNORE: ignore metadata information, just for test..

CREATE TABLE `test_meta_impact` (
`abcdefg1` int(11) NOT NULL AUTO_INCREMENT,
`abcdefg2` int(11) DEFAULT NULL,
`abcdefg3` int(11) DEFAULT NULL,
`abcdefg4` int(11) DEFAULT NULL,
……
……
`abcdefg40` int(11) DEFAULT NULL,
PRIMARY KEY (`abcdefg1`)
) ENGINE=InnoDB AUTO_INCREMENT=229361 DEFAULT CHARSET=utf8

mysqlslap --no-defaults -uxx --create-schema=test -h$host -P $port --number-of-queries=1000000000 --concurrency=100 --query='SELECT * FROM test.test_meta_impact where abcdefg1 = 2'

METADATA_FULL : 3.48w TPS, Net send 113M
METADATA_REAL_COLUMN: 7.2W TPS, Net send 111M
METADATA_FAKE_COLUMN: 9.2W TPS , Net send 116M
METADATA_NULL_COLUMN: 9.6w TPS , Net send 115M
METADATA_IGNORE: 13.8w TPS, Net send 30M

可以看到去掉元数据后,不但网络传输少了至少三倍多, tps也上升了不少.

参考文档

WL#8134: Make metadata information transfer optional:

https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont700077.26.62b94216LfYbta&id=8134

resultset_metadata:

https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html?spm=a2c4e.11153940.blogcont700077.27.62b94216LfYbta#sysvar_resultset_metadata

CAPI

https://dev.mysql.com/doc/refman/8.0/en/c-api-optional-metadata.html

相关代码
https://github.com/zhaiwx1987/mysql-server/commit/3f4ac020306ed5000d3cf8c908efa9786097d42d?spm=a2c4e.11153940.blogcont700077.29.62b94216LfYbta

异步query

从最新的8.0.16版本开始,新的C API开始支持异步的无阻塞的提交查询,相关的API包括:

mysql_real_connect_nonblocking()

mysql_real_query_nonblocking()

mysql_store_result_nonblocking()

mysql_next_result_nonblocking()

mysql_fetch_row_nonblocking()

mysql_free_result_nonblocking()

函数的名字就是原有阻塞性api加上后缀_nonblocking,比如说如果query的执行时间比较长,你可以先去干别的事情,然后再回来查询结果集。当然啦你必须要使用8.0.16或之后的client api

参考文档

WL#11381:

Add asynchronous support into the mysql protocol:

https://dev.mysql.com/worklog/task/?spm=a2c4e.11153940.blogcont700077.30.62b94216LfYbta&id=11381

C API Asynchronous Interface:

https://dev.mysql.com/doc/refman/8.0/en/c-api-asynchronous-interface.html

相关代码:

https://github.com/mysql/mysql-server/commit/c1fffc3c651f22451154c9834a43c661112b368c?spm=a2c4e.11153940.blogcont700077.32.62b94216LfYbta

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
传感器 机器学习/深度学习 算法
基于GA遗传算法的WSN网络节点覆盖优化matlab仿真
本研究应用遗传优化算法于无线传感器网络(WSN),优化节点布局与数量,以最小化节点使用而最大化网络覆盖率。MATLAB2022a环境下,算法通过选择、交叉与变异操作,逐步改进节点配置,最终输出收敛曲线展现覆盖率、节点数及适应度值变化。无线传感器网络覆盖优化问题通过数学建模,结合遗传算法,实现目标区域有效覆盖与网络寿命延长。算法设计中,采用二进制编码表示节点状态,适应度函数考量覆盖率与连通性,通过选择、交叉和变异策略迭代优化,直至满足终止条件。
|
2天前
|
缓存 关系型数据库 MySQL
MySQL优化
【7月更文挑战第21天】MySQL优化
7 1
|
6天前
|
关系型数据库 MySQL 调度
MySQL高级功能与优化策略深度探索
MySQL高级功能与优化策略深度探索
|
12天前
|
机器学习/深度学习 数据采集 监控
算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient
**神经网络与AI学习概览** - 探讨神经网络设计,包括MLP、RNN、CNN,激活函数如ReLU,以及隐藏层设计,强调网络结构与任务匹配。 - 参数初始化与优化涉及Xavier/He初始化,权重和偏置初始化,优化算法如SGD、Adam,针对不同场景选择。 - 学习率调整与正则化,如动态学习率、L1/L2正则化、早停法和Dropout,以改善训练和泛化。
9 0
算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient
|
20天前
|
传感器 监控 算法
基于虚拟力优化的无线传感器网络覆盖率matlab仿真
**摘要:** 本文探讨了基于虚拟力优化提升无线传感器网络(WSNs)覆盖率的方法。通过在MATLAB2022a中仿真,显示了优化前后网络覆盖率对比及收敛曲线。虚拟力优化算法模拟物理力,以优化传感器节点布局,防止重叠并吸引至目标区域,同时考虑墙壁碰撞。覆盖计算利用平面扫描法评估圆形和正方形传感器的覆盖范围。算法通过迭代优化网络性能,以提高WSNs的监控能力。
|
10天前
|
网络协议 Python
在Python中,我们使用`socket`模块来进行网络通信。首先,我们需要导入这个模块。
在Python中,我们使用`socket`模块来进行网络通信。首先,我们需要导入这个模块。
|
10天前
|
关系型数据库 MySQL API
MySQL上亿数据查询优化:实践与技巧
MySQL亿级数据查询优化涉及索引设计、分区表、查询语句优化和数据库架构调整。例如,通过为常用查询列创建索引、使用EXPLAIN分析查询计划、避免全表扫描和SELECT *,以及采用垂直拆分、水平拆分和读写分离来提升性能。分区表能减少查询数据量,API接口测试可验证优化效果。
20 0
|
10天前
|
存储 传感器 算法
基于ACO蚁群优化算法的WSN网络路由优化matlab仿真
摘要(Markdown格式): - 📈 ACO算法应用于WSN路由优化,MATLAB2022a中实现,动态显示迭代过程,输出最短路径。 - 🐜 算法模拟蚂蚁寻找食物,信息素更新与蚂蚁选择策略确定路径。信息素增量Δτ += α*τ*η,节点吸引力P ∝ τ / d^α。 - 🔁 算法流程:初始化→蚂蚁路径选择→信息素更新→判断结束条件→输出最优路由。优化WSN能量消耗,降低传输成本。
|
13天前
|
机器学习/深度学习 数据采集 算法
Python实现人工神经网络回归模型(MLPRegressor算法)并基于网格搜索(GridSearchCV)进行优化项目实战
Python实现人工神经网络回归模型(MLPRegressor算法)并基于网格搜索(GridSearchCV)进行优化项目实战
|
19天前
|
SQL Oracle 关系型数据库
MySQL单表千万级数据查询优化大家怎么说(评论有亮点)
单表千万级数据是MySQL查询的一个坎,可能还不是天花板。“一个人走的慢,一群人走的快”,通过讨论可以发现MySQL千万数据的全貌大概是怎样的。
33 0

推荐镜像

更多