X 插件支持压缩通过 X 协议连接发送的消息。如果服务器和客户端就相互支持的压缩算法达成一致,则可以压缩连接。启用压缩可以减少通过网络发送的字节数,但会增加服务器和客户端用于压缩和解压缩操作的额外 CPU 成本。因此,压缩的好处主要体现在网络带宽较低、网络传输时间在压缩和解压缩操作成本中占主导地位以及结果集较大时。
不同的 MySQL 客户端以不同的方式实现对连接压缩的支持;有关详细信息,请参阅您的客户端文档。例如,对于经典 MySQL 协议连接,请参阅 第 6.2.8 节“连接压缩控制”。
默认情况下,X 插件支持 zstd、LZ4 和 Deflate 压缩算法。使用 Deflate 算法的压缩是使用 zlib 软件库执行的,因此 X 协议连接的 deflate_stream
压缩算法设置等效于经典 MySQL 协议连接的 zlib
设置。
在服务器端,您可以通过设置 mysqlx_compression_algorithms
系统变量以仅包含允许的算法来禁止任何压缩算法。算法名称 zstd_stream
、lz4_message
和 deflate_stream
可以以任何组合指定,顺序和大小写并不重要。如果系统变量值为字符串,则不允许使用任何压缩算法,并且连接未压缩。
下表比较了不同压缩算法的特性,并显示了它们分配的优先级。默认情况下,服务器会选择服务器和客户端共同允许的最高优先级算法;客户端可以更改优先级,如下所述。客户端在指定算法时可以使用算法的简称。
表 22.1 X 协议压缩算法特性
算法 | 别名 | 压缩率 | 吞吐量 | CPU 成本 | 默认优先级 |
---|---|---|---|---|---|
zsth_stream |
zstd |
高 | 高 | 中等 | 第一 |
lz4_message |
lz4 |
低 | 高 | 最低 | 第二 |
deflate_stream |
deflate |
高 | 低 | 最高 | 第三 |
X 协议允许的压缩算法集(无论是用户指定的还是默认的)独立于 MySQL 服务器为经典 MySQL 协议连接允许的压缩算法集,后者由 protocol_compression_algorithms
服务器系统变量指定。如果您没有指定 mysqlx_compression_algorithms
系统变量,X 插件不会回退到使用经典 MySQL 协议连接的压缩设置。相反,它的默认设置是允许 表 22.1“X 协议压缩算法特性” 中显示的所有算法。这与 TLS 上下文的情况不同,如果未设置 X 插件系统变量,则使用 MySQL 服务器设置,如 第 22.5.3 节“将加密连接与 X 插件一起使用” 中所述。有关经典 MySQL 协议连接的压缩的信息,请参阅 第 6.2.8 节“连接压缩控制”。
在客户端,X 协议连接请求可以指定几个用于压缩控制的参数
压缩模式。
压缩级别。
允许的压缩算法列表(按优先级顺序)。
某些客户端或连接器可能不支持给定的压缩控制功能。例如,仅 MySQL Shell 支持为 X 协议连接指定压缩级别,而其他 MySQL 客户端或连接器不支持。有关受支持功能以及如何使用它们的详细信息,请参阅特定产品的文档。
连接模式具有以下允许值
disabled
:连接未压缩。preferred
:服务器和客户端协商以找到它们都允许的压缩算法。如果没有通用的算法可用,则连接未压缩。如果没有明确指定,则这是默认模式。required
:压缩算法协商与preferred
模式相同,但如果没有通用的算法可用,则连接请求以错误终止。
除了就每个连接的压缩算法达成一致外,服务器和客户端还可以就适用于 agreed 算法的数字范围内的压缩级别达成一致。随着算法压缩级别的增加,数据压缩率也会增加,这减少了将消息发送到客户端所需的网络带宽和传输时间。但是,数据压缩所需的工作量也会增加,从而占用服务器上的时间、CPU 和内存资源。压缩工作量的增加与压缩率的增加没有线性关系。
客户端可以在与服务器进行 X 协议连接的功能协商期间请求特定的压缩级别。
MySQL 8.4 中 X 插件使用的默认压缩级别已通过性能测试选择,作为压缩时间和网络传输时间之间的良好折衷。这些默认值不一定与每个算法的库默认值相同。如果客户端没有为算法请求压缩级别,则适用这些默认值。默认压缩级别最初为 zstd 设置为 3,LZ4 设置为 2,Deflate 设置为 3。您可以使用 mysqlx_zstd_default_compression_level
、mysqlx_lz4_default_compression_level
和 mysqlx_deflate_default_compression_level
系统变量调整这些设置。
为了防止服务器上的资源过度消耗,X 插件为每个算法设置了服务器允许的最大压缩级别。如果客户端请求的压缩级别超过此设置,则服务器将使用其允许的最大压缩级别(仅 MySQL Shell 支持客户端对压缩级别的请求)。最大压缩级别最初为 zstd 设置为 11,LZ4 设置为 8,Deflate 设置为 5。您可以使用 mysqlx_zstd_max_client_compression_level
、mysqlx_lz4_max_client_compression_level
和 mysqlx_deflate_max_client_compression_level
系统变量调整这些设置。
如果服务器和客户端允许多个相同的算法,则在协商期间选择算法的默认优先级顺序如 表 22.1“X 协议压缩算法特性” 中所示。对于支持指定压缩算法的客户端,连接请求可以包含客户端允许的算法列表,使用算法名称或其别名指定。列表中这些算法的顺序被服务器视为优先级顺序。在这种情况下使用的算法是客户端列表中服务器端也允许的第一个算法。但是,压缩算法的选项取决于压缩模式
如果压缩模式为
disabled
,则忽略压缩算法选项。如果压缩模式为
preferred
,但客户端允许的算法在服务器端不允许,则连接未压缩。如果压缩模式是
required
,但客户端允许的算法在服务器端都不允许,则会发生错误。
要监控消息压缩的效果,请使用监控 X 插件的连接压缩中描述的 X 插件状态变量。您可以使用这些状态变量来计算当前设置下消息压缩的好处,并使用该信息来调整您的设置。
X 协议连接压缩按以下行为和边界运行
算法名称中的
_stream
和_message
后缀指的是两种不同的操作模式:在流模式下,单个连接中的所有 X 协议消息都被压缩成一个连续的流,并且必须以相同的方式解压缩,即按照它们被压缩的顺序,并且不能跳过任何消息。在消息模式下,每条消息都单独独立地压缩,并且不需要按照它们被压缩的顺序解压缩。此外,消息模式不要求所有压缩消息都被解压缩。压缩不应用于身份验证成功之前发送的任何消息。
压缩不应用于控制流消息,例如
Mysqlx.Ok
、Mysqlx.Error
和Mysqlx.Sql.StmtExecuteOk
消息。如果服务器和客户端在功能协商期间就相互允许的压缩算法达成一致,则所有其他 X 协议消息都可以被压缩。如果客户端在该阶段没有请求压缩,则客户端和服务器都不会对消息应用压缩。
当通过 X 协议连接发送的消息被压缩时,
mysqlx_max_allowed_packet
系统变量指定的限制仍然适用。消息负载解压缩后,网络数据包必须小于此限制。如果超过限制,X 插件将返回解压缩错误并关闭连接。以下几点与客户端的压缩级别请求有关,这仅受 MySQL Shell 支持
客户端必须将压缩级别指定为整数。如果提供任何其他类型的值,连接将关闭并显示错误。
如果客户端指定了算法但没有指定压缩级别,则服务器将使用该算法的默认压缩级别。
如果客户端请求的算法压缩级别超过服务器允许的最大级别,则服务器将使用允许的最大级别。
如果客户端请求的算法压缩级别低于服务器允许的最小级别,则服务器将使用允许的最小级别。
您可以使用 X 插件状态变量来监控消息压缩的效果。当使用消息压缩时,会话 Mysqlx_compression_algorithm
状态变量显示当前 X 协议连接使用的是哪种压缩算法,Mysqlx_compression_level
显示选择的压缩级别。
X 插件状态变量可用于计算所选压缩算法的效率(数据压缩率)以及使用消息压缩的整体效果。使用以下计算中状态变量的会话值来查看具有已知压缩算法的特定会话的消息压缩的好处。或者使用状态变量的全局值来检查服务器上所有使用 X 协议连接的会话的消息压缩的整体好处,包括用于这些会话的所有压缩算法,以及所有未使用消息压缩的会话。然后,您可以通过调整允许的压缩算法、最大压缩级别和默认压缩级别来调整消息压缩,如配置 X 插件的连接压缩中所述。
当使用消息压缩时,Mysqlx_bytes_sent
状态变量显示从服务器发送的字节总数,包括压缩后的压缩消息负载(在压缩后测量)、压缩消息中未压缩的任何项目(如 X 协议标头)以及任何未压缩的消息。Mysqlx_bytes_sent_compressed_payload
状态变量显示作为压缩消息负载发送的字节总数(在压缩后测量),Mysqlx_bytes_sent_uncompressed_frame
状态变量显示相同消息负载但在压缩前测量的字节总数。因此,可以使用以下表达式计算压缩率,它显示了压缩算法的效率
mysqlx_bytes_sent_uncompressed_frame / mysqlx_bytes_sent_compressed_payload
服务器发送的 X 协议消息的压缩效率可以使用以下表达式计算
(mysqlx_bytes_sent - mysqlx_bytes_sent_compressed_payload + mysqlx_bytes_sent_uncompressed_frame) / mysqlx_bytes_sent
对于服务器从客户端接收的消息,Mysqlx_bytes_received_compressed_payload
状态变量显示作为压缩消息负载接收的字节总数(在解压缩前测量),Mysqlx_bytes_received_uncompressed_frame
状态变量显示相同消息负载但在解压缩后测量的字节总数。Mysqlx_bytes_received
状态变量包括在解压缩前测量的压缩消息负载、压缩消息中任何未压缩的项目以及任何未压缩的消息。