从 MySQL 8.0.19 开始,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 协议压缩算法特征
Algorithm | Alias | Compression Ratio | Throughput | CPU Cost | Default Priority |
---|---|---|---|---|---|
zsth_stream |
zstd |
高 | 高 | 中等 | 第一 |
lz4_message |
lz4 |
低 | 高 | 最低 | 第二 |
deflate_stream |
deflate |
高 | 低 | 最高 | 第三 |
X 协议允许的压缩算法集(无论是用户指定的还是默认的)独立于 MySQL 服务器为经典 MySQL 协议连接所指定的压缩算法集,该集由 protocol_compression_algorithms
服务器系统变量指定。如果您不指定 mysqlx_compression_algorithms
系统变量,X 插件不会回退到使用经典 MySQL 协议连接的压缩设置。相反,默认情况下,它将允许所有在 表 22.1 中显示的算法。这与 TLS 上下文的情况不同,在该情况下,如果 X 插件系统变量未设置,MySQL 服务器设置将被使用,如 第 22.5.3 节,“使用 X 插件的加密连接” 所述。有关经典 MySQL 协议连接的压缩信息,请参阅 第 6.2.8 节,“连接压缩控制”。
在客户端,X 协议连接请求可以指定多个参数以控制压缩:
-
压缩模式。
-
压缩级别(从 MySQL 8.0.20 开始)。
-
允许的压缩算法列表,以优先顺序排列(从 MySQL 8.0.22 开始)。
某些客户端或连接器可能不支持特定的压缩控制功能。例如,指定 X 协议连接的压缩级别仅由 MySQL Shell 支持,而不是由其他 MySQL 客户端或连接器支持。请查看特定产品的文档,以了解支持的功能和使用方法。
连接模式具有以下允许值:
-
disabled
:连接未压缩。 -
preferred
:服务器和客户端协商以找到它们都允许的压缩算法。如果没有共同的算法可用,则连接未压缩。这是默认模式,如果未明确指定。 -
required
:压缩算法协商与preferred
模式相同,但如果没有共同的算法可用,则连接请求将以错误终止。
除了同意每个连接的压缩算法外,服务器和客户端还可以同意使用该算法的压缩级别。随着压缩级别的增加,数据压缩比率增加,从而减少了网络带宽和传输时间以将消息发送到客户端。然而,数据压缩所需的努力也增加,占用服务器的时间、CPU 和内存资源。压缩努力的增加与压缩比率的增加之间没有线性关系。
在 MySQL 8.0.19 中,X 插件始终使用每个算法的库默认压缩级别(zstd 为 3,LZ4 为 0,Deflate 为 6),客户端无法协商此项。从 MySQL 8.0.20 开始,客户端可以在 X 协议连接的功能协商中请求特定的压缩级别。
从 MySQL 8.0.20 开始,X 插件使用的默认压缩级别是通过性能测试选择的,以找到压缩时间和网络传输时间之间的良好平衡。这些默认值不是每个算法的库默认值。如果客户端没有请求算法的压缩级别,则使用这些默认值。可以使用 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 协议压缩算法特征”。从 MySQL 8.0.22 开始,对于支持指定压缩算法的客户端,连接请求可以包括客户端允许的算法列表,使用算法名称或别名指定。该列表中的算法顺序将被服务器视为优先顺序。使用的算法是客户端列表中第一个也在服务器端允许的算法。然而,压缩算法选项取决于压缩模式:
-
如果压缩模式是
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
将显示所选的压缩级别。这些会话状态变量从 MySQL 8.0.20 开始可用。
从 MySQL 8.0.19 开始,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
状态变量包括压缩后的消息负载、任何未压缩的项目和任何未压缩的消息。