【 使用环境 】 测试环境
【 OB or 其他组件 】OB
【 使用版本 】OB4.2.4
【问题描述】建表用的是默认压缩方式是zstd_1.3.8,抓火焰图发现,DAG线程和MINOR_EXE线程实际执行的是lz4的压缩解压缩函数,想问下这是为什么
根据文档库中的信息,可以对您的问题进行如下分析和解答:
1. 默认压缩方式
在 OceanBase 数据库中,表的默认压缩方式由参数 default_compress_func
控制,默认值为 zstd_1.3.8
(文档片段 2)。这意味着在创建表时,如果没有显式指定压缩算法,OceanBase 会使用 zstd_1.3.8
对数据进行压缩。
2. 压缩算法的实际执行
尽管表的默认压缩方式是 zstd_1.3.8
,但在某些场景下,实际执行的压缩解压函数可能是其他算法(如 lz4
)。这种现象可能与以下因素有关:
(1) 日志传输压缩
- 参数
log_transport_compress_func
控制事务日志内部传输时使用的压缩算法,默认值为lz4_1.0
(文档片段 7 和 文档片段 1)。 - 在事务处理过程中,DAG 线程和 MINOR_EXE 线程可能会涉及事务日志的生成和传输。因此,即使表的压缩方式是
zstd_1.3.8
,这些线程仍可能使用lz4
进行日志传输的压缩和解压。
(2) 临时数据的压缩
- 在执行查询或写入操作时,OceanBase 可能会生成一些临时数据(如 Minor Freeze 阶段的增量数据)。这些临时数据的压缩算法可能并不完全依赖于表的默认压缩方式,而是由系统内部的优化策略决定。
- 例如,
lz4
的压缩速度较快,适合用于需要快速处理的临时数据场景。
(3) 性能优化
- OceanBase 数据库在设计上会根据不同的场景选择最适合的压缩算法。虽然
zstd_1.3.8
提供了较高的压缩率,但其压缩和解压速度相对较慢。在某些高性能要求的场景下,系统可能会优先选择速度更快的lz4
算法。
3. 验证方法
如果您希望进一步确认为何实际执行的是 lz4
压缩解压函数,可以通过以下步骤进行验证:
- 检查租户级参数
log_transport_compress_func
的值,确认是否为lz4_1.0
。 - 查看火焰图中具体调用栈的信息,判断是否与事务日志传输相关。
- 如果需要强制使用
zstd_1.3.8
,可以尝试调整相关参数或优化查询逻辑。
4. 总结
实际执行的压缩解压函数可能因场景不同而异。在您的环境中,DAG 线程和 MINOR_EXE 线程实际执行的是 lz4
压缩解压函数,这很可能是由于事务日志传输或临时数据处理的需求所致。这种行为属于 OceanBase 数据库的正常优化策略,并不意味着表的默认压缩方式发生了变化。
如果仍有疑问,建议联系 OceanBase 的技术支持团队以获取更详细的解答。
更多信息请查看:
火焰图这一块,都是微块在做压缩,不涉及日志哈
对压缩可以理解有两个部分
- 写入需要压缩, ob内部所有数据是通过compaction写入, 因此也在这里做压缩
- 读取需要解压, 所有压缩数据读取后要解压, 这里会发生在后台io或者前台同步io
根据您提供的火焰图信息以及描述,可以进一步分析为什么在 OceanBase 4.2.4 中,尽管表的默认压缩方式是 zstd_1.3.8
,但在实际执行中,DAG 线程和 MINOR_EXE 线程却使用了 lz4
的压缩解压函数。
分析与解答
1. 微块压缩的实际行为
从火焰图中可以看出,涉及的模块主要是 blocksstable::ObMicroBlock
和 compaction
相关的逻辑。这表明当前的行为发生在微块(Micro Block)的压缩和解压过程中。以下是关键点:
-
OceanBase 的微块压缩机制
在 OceanBase 数据库中,数据是以微块为单位进行存储和管理的,默认微块大小为 16KB。对于微块的压缩,系统可能会根据性能优化策略选择不同的压缩算法。 -
压缩算法的选择依据
尽管表级别的默认压缩方式是zstd_1.3.8
,但微块的压缩可能并不完全依赖于表的设置。具体原因如下:-
性能优化:
lz4
的压缩和解压速度非常快,适合高频操作场景(如 Minor Freeze 阶段的增量数据写入)。因此,在某些内部实现中,OceanBase 可能会优先选择lz4
来处理微块的压缩和解压。 -
临时数据处理:在 Compaction(合并)过程中,生成的中间数据可能需要快速压缩和解压,此时也会倾向于使用
lz4
。
-
性能优化:
2. 火焰图中的关键信息
火焰图显示了以下调用栈:
oceanbase::blocksstable::ObMacroBlockWriter::append_row
oceanbase::compaction::ObPartitionMinorMerger::inner_process
这些调用栈表明当前的操作与微块写入和 Minor Merge(小合并)相关。在这些场景下,OceanBase 的实现可能会优先选择性能更高的压缩算法(如 lz4
),而不是严格遵循表级别的默认压缩方式。
3. 为什么选择了 lz4
?
根据文档片段中的信息(文档片段 4 和 文档片段 5),lz4
和 snappy
的压缩速度较快,但压缩率较低。相比之下,zstd
和 zlib
提供了更高的压缩率,但压缩和解压速度较慢。因此,OceanBase 在以下场景中可能会选择 lz4
:
- 高频写入场景:如 Minor Freeze 阶段的增量数据写入。
- Compaction 过程中的临时数据处理:为了加快合并速度,系统可能会选择更快的压缩算法。
4. 表压缩方式与微块压缩的关系
虽然表的默认压缩方式是 zstd_1.3.8
,但这仅影响最终存储到磁盘上的数据块(Macro Block)的压缩方式。而在微块层面,OceanBase 的实现可能会根据具体的场景选择更适合的压缩算法。这种设计是为了平衡性能和存储空间利用率。
总结
在您的环境中,DAG 线程和 MINOR_EXE 线程实际执行的是 lz4
压缩解压函数,这是由于以下原因:
- 微块的压缩和解压可能不完全依赖于表的默认压缩方式。
- 在高频写入或 Compaction 场景中,OceanBase 会选择性能更高的压缩算法(如
lz4
)以优化性能。 - 这种行为属于 OceanBase 数据库的正常优化策略,并不意味着表的默认压缩方式发生了变化。
如果您希望进一步确认这一行为,可以通过以下方法验证:
- 检查
default_compress_func
参数的值,确认表的默认压缩方式是否为zstd_1.3.8
。 - 使用
EXPLAIN
或其他诊断工具查看具体查询的执行计划,分析是否涉及 Compaction 或高频写入场景。
如果仍有疑问,建议联系 OceanBase 的技术支持团队以获取更详细的解答。
检索到的文档如下:
根据文档库中的信息,OceanBase 数据库在数据写入和读取时的压缩与解压机制如下:
- 写入时的压缩
OceanBase 数据库采用 LSM-Tree 架构,在数据写入过程中,MemTable 中的数据达到一定阈值或触发每日合并时会转储/合并到磁盘上形成 SSTable。这一过程发生在 Compaction 阶段,因此所有的数据压缩操作也在此阶段完成(参考片段标题:压缩与编码)。您可以配置参数 default_compress_func 来选择具体的压缩算法,默认值为 zstd_1.3.8(参考片段标题:合并管理概述 → 合并的压缩算法)。
- 读取时的解压
当从 SSTable 中读取数据时,如果数据被压缩,则需要进行解压操作。解压可能发生在后台异步 IO 或前台同步 IO 中(参考片段标题:压缩与编码)。具体来说:
-
如果数据是通过后台线程预读取的,则解压会在后台异步 IO 中完成。
-
如果数据是按需读取的,则解压会在前台同步 IO 中完成。
总结:
-
写入时的压缩发生在 Compaction 阶段,不会影响实时写入性能。
-
读取时的解压可能发生在后台异步 IO 或前台同步 IO 中,具体取决于数据的访问模式和系统配置。
如果您需要进一步调整压缩策略,可以通过创建表时指定 COMPRESSION 属性来控制单个表的压缩算法(参考片段标题:表压缩)。例如:
CREATE TABLE my_table (
id INT PRIMARY KEY,
name VARCHAR(255)
) COMPRESSION = ‘zstd_1.0’;
以上内容基于以下文档信息:
-
合并管理概述 → 合并的压缩算法
-
压缩与编码
-
表压缩
检索到的文档如下: