MySQL 8.0 参考手册  / 第 20 章使用 MySQL 作为文档存储  / 20.5 X 插件  /  20.5.5 使用 X 插件进行连接压缩

20.5.5 使用 X 插件进行连接压缩

从 MySQL 8.0.19 开始,X 插件支持压缩通过 X 协议连接发送的消息。如果服务器和客户端同意相互支持的压缩算法,则可以压缩连接。启用压缩可减少通过网络发送的字节数,但会增加服务器和客户端用于压缩和解压缩操作的额外 CPU 成本。因此,压缩的好处主要出现在网络带宽较低、网络传输时间支配压缩和解压缩操作成本以及结果集很大的情况下。

笔记

不同的 MySQL 客户端实现对连接压缩的支持不同;有关详细信息,请参阅您的客户文档。例如,对于经典的 MySQL 协议连接,请参阅 第 4.2.8 节,“连接压缩控制”

为 X 插件配置连接压缩

默认情况下,X Plugin 支持 zstd、LZ4 和 Deflate 压缩算法。Deflate算法压缩是使用zlib软件库进行的,所以 deflate_streamX协议连接的压缩算法设置等同 zlib于经典MySQL协议连接的设置。

在服务器端,您可以通过将 mysqlx_compression_algorithms 系统变量设置为仅包含允许的压缩算法来禁止任何压缩算法。算法名称zstd_streamlz4_messagedeflate_stream可以任意组合指定,顺序和字母大小写并不重要。如果系统变量值为空字符串,则不允许使用任何压缩算法并且连接未压缩。

下表比较了不同压缩算法的特性并显示了它们分配的优先级。默认情况下,服务器选择服务器和客户端共同允许的最高优先级算法;客户端可以更改优先级,如下所述。客户端在指定算法时可以使用算法的短格式别名。

表 20.1 X 协议压缩算法特性

算法 别名 压缩率 吞吐量 CPU成本 默认优先级
zsth_stream zstd 高的 高的 中等的 第一的
lz4_message lz4 低的 高的 最低 第二
deflate_stream deflate 高的 低的 最高 第三

X 协议允许的压缩算法集(无论是用户指定的还是默认的)独立于 MySQL 服务器允许的经典 MySQL 协议连接的压缩算法集,由 protocol_compression_algorithms 服务器系统变量指定。如果不指定 mysqlx_compression_algorithms 系统变量,X Plugin 不会回退到对经典 MySQL 协议连接使用压缩设置。相反,它的默认值是允许 表 20.1 “X 协议压缩算法特性”中显示的所有算法。这与 TLS 上下文的情况不同,如果未设置 X 插件系统变量,则使用 MySQL 服务器设置,如中所述 第 20.5.3 节,“使用 X 插件的加密连接”。有关经典 MySQL 协议连接压缩的信息,请参阅第 4.2.8 节,“连接压缩控制”

在客户端,一个 X 协议连接请求可以指定几个压缩控制参数:

  • 压缩模式。

  • 压缩级别(来自 MySQL 8.0.20)。

  • 按优先顺序排列的允许压缩算法列表(来自 MySQL 8.0.22)。

笔记

某些客户端或连接器可能不支持给定的压缩控制功能。例如,仅 MySQL Shell 支持为 X 协议连接指定压缩级别,其他 MySQL 客户端或连接器不支持。有关支持的功能及其使用方法的详细信息,请参阅特定产品的文档。

连接模式具有以下允许值:

  • disabled: 连接未压缩。

  • preferred:服务器和客户端协商以找到它们都允许的压缩算法。如果没有通用算法可用,则连接未压缩。如果没有明确指定,这是默认模式。

  • required: 压缩算法协商与preferred模式相同,但如果没有可用的通用算法,连接请求将因错误而终止。

除了为每个连接商定压缩算法外,服务器和客户端还可以商定适用于商定算法的数字范围内的压缩级别。随着算法压缩级别的增加,数据压缩率也会增加,从而减少将消息发送到客户端所需的网络带宽和传输时间。但是,数据压缩所需的工作量也会增加,占用服务器上的时间以及 CPU 和内存资源。压缩力的增加与压缩比的增加没有线性关系。

在 MySQL 8.0.19 中,X Plugin 始终为每个算法使用库默认压缩级别(zstd 为 3,LZ4 为 0,Deflate 为 6),客户端无法对此进行协商。从 MySQL 8.0.20 开始,客户端可以在与服务器进行 X 协议连接的能力协商期间请求特定的压缩级别。

MySQL 8.0.20 中的 X 插件使用的默认压缩级别已通过性能测试选择,作为压缩时间和网络传输时间之间的良好折衷。这些默认值不一定与每个算法的库默认值相同。如果客户端不请求算法的压缩级别,则它们适用。zstd 的默认压缩级别最初设置为 3,LZ4 为 2,Deflate 为 3。mysqlx_zstd_default_compression_level您可以使用、 mysqlx_lz4_default_compression_levelmysqlx_deflate_default_compression_level 系统变量 调整这些设置 。

为了防止服务器过度消耗资源,X Plugin 为每个算法设置了服务器允许的最大压缩级别。如果客户端请求的压缩级别超过此设置,服务器将使用其最大允许压缩级别(客户端的压缩级别请求仅由 MySQL Shell 支持)。zstd 的最大压缩级别最初设置为 11,LZ4 为 8,Deflate 为 5。mysqlx_zstd_max_client_compression_level您可以使用、 mysqlx_lz4_max_client_compression_levelmysqlx_deflate_max_client_compression_level 系统变量 调整这些设置 。

如果服务器和客户端允许多个共同算法,协商期间选择算法的默认优先级顺序如 表 20.1 “X 协议压缩算法特征”所示。从 MySQL 8.0.22 开始,对于支持指定压缩算法的客户端,连接请求可以包含客户端允许的算法列表,使用算法名称或其别名指定。服务器将这些算法在列表中的顺序作为优先顺序。在这种情况下使用的算法是客户端列表中第一个在服务器端也被允许的算法。但是,压缩算法的选项取决于压缩模式:

  • 如果压缩模式为disabled,压缩算法选项将被忽略。

  • 如果压缩模式是preferred,但服务器端不允许客户端允许的算法,则连接未压缩。

  • 如果压缩方式为required客户端允许的算法,但服务器端不允许,则报错。

要监视消息压缩的效果,请使用监视 X 插件的连接压缩中 描述的 X 插件状态变量 。您可以使用这些状态变量来计算使用当前设置进行消息压缩的好处,并使用该信息来调整您的设置。

X 插件的压缩连接特性

X 协议连接压缩以下列行为和边界运行:

  • 算法名称中的_stream_message后缀指的是两种不同的操作模式: 在流模式中,单个连接中的所有 X 协议消息都被压缩成一个连续的流,并且必须以相同的方式解压缩——遵循它们被压缩的顺序并且不跳过任何消息。在消息模式下,每条消息都是单独压缩的,不需要按照压缩的顺序进行解压缩。此外,消息模式不需要解压缩所有压缩消息。

  • 压缩不适用于身份验证成功之前发送的任何消息。

  • 压缩不适用于控制流消息,例如 Mysqlx.OkMysqlx.ErrorMysqlx.Sql.StmtExecuteOkmessages。

  • 如果服务器和客户端在能力协商期间就相互允许的压缩算法达成一致,则可以压缩所有其他 X 协议消息。如果客户端在该阶段不请求压缩,则客户端和服务器都不会对消息应用压缩。

  • 当通过 X 协议连接发送的消息被压缩时, mysqlx_max_allowed_packet 系统变量指定的限制仍然适用。消息负载解压缩后,网络数据包必须小于此限制。如果超过限制,X Plugin 会返回解压错误并关闭连接。

  • 以下几点与客户端的压缩级别请求有关,只有 MySQL Shell 支持:

    • 压缩级别必须由客户端指定为整数。如果提供了任何其他类型的值,则连接会因错误而关闭。

    • 如果客户端指定算法但未指定压缩级别,则服务器将使用其算法的默认压缩级别。

    • 如果客户端请求的算法压缩级别超过服务器最大允许级别,则服务器将使用最大允许级别。

    • 如果客户端请求的算法压缩级别低于服务器的最低允许级别,则服务器将使用最低允许级别。

监控 X 插件的连接压缩

您可以使用 X 插件状态变量监视消息压缩的效果。使用消息压缩时,会话 Mysqlx_compression_algorithm 状态变量会显示当前 X 协议连接正在使用哪种压缩算法,并 Mysqlx_compression_level显示所选的压缩级别。这些会话状态变量可从 MySQL 8.0.20 获得。

从MySQL 8.0.19开始,X Plugin状态变量可以用来计算所选压缩算法的效率(数据压缩率),以及使用消息压缩的整体效果。在以下计算中使用状态变量的会话值来查看消息压缩对具有已知压缩算法的特定会话的好处。或者使用状态变量的全局值来检查使用 X 协议连接的所有会话中服务器的消息压缩的总体好处,包括已用于这些会话的所有压缩算法,以及所有未使用消息压缩的会话. 为 X 插件配置连接压缩

使用消息压缩时, Mysqlx_bytes_sent状态变量显示从服务器发出的总字节数,包括压缩后测量的压缩消息有效负载、压缩消息中未压缩的任何项目(例如 X 协议标头)以及任何未压缩的消息。status 变量显示压缩后测量的作为压缩消息有效负载发送的 Mysqlx_bytes_sent_compressed_payload 字节总数,以及 Mysqlx_bytes_sent_uncompressed_frame status 变量显示那些相同消息有效载荷但在压缩前测量的总字节数。因此,可以使用以下表达式计算显示压缩算法效率的压缩率:

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压缩消息有效负载、压缩消息中的任何未压缩项目以及任何未压缩消息。