Cassandra 4.1 Colibri压缩算法全解析:原理、配置与性能实测
提到 Cassandra 存储优化压缩算法这块这几年变化不大大家耳熟能详的翻来覆去就是 LZ4、Zstd、Deflate 三个选项。但 4.1 版本引入的 Colibri 压缩算法我觉得值得好好聊一聊。它不像 LZ4 那样追求极致速度也不像 Zstd 那样靠高压缩率出圈而是想在两者之间吃到一个不错的平衡点。这篇博文我会结合自己的实测体验把 Colibri 的原理、参数、配法、适用场景和踩坑记录一次讲透给正在做 Cassandra 容量优化或者想降存储成本的同行一个直接能抄的作业。1. Colibri 压缩算法到底解决什么问题1.1 先聊背景Cassandra 数据落盘的压缩现状Cassandra 的数据最终是以 SSTable 的形式落在磁盘上的而 SSTable 在写入的时候默认就会做压缩。这个设计从一开始就存在不单单是为了省硬盘更重要的是降低磁盘 IO 和网络传输成本尤其是在多节点集群里压缩后的数据在修复、流传输、备份恢复等场景里都会快很多。但是问题在于过去很长一段时间里官方内置的几个压缩器偏向性太明显。LZ4Compressor 速度确实快写入路径上的 CPU 开销很低可压缩率一般面对重复度高的文本、时序数据感觉像是有劲没使出来。ZstdCompressor 压缩率非常漂亮但 CPU 消耗明显高一个量级在一些写入密集型的集群里CPU 先被打满把压缩省下来的磁盘空间又折回去了。DeflateCompressor 则属于老二经典中规中矩但性能上限低在新硬件上已经不太看得上眼了。所以 Colibri 出现的时间节点很有意思它不是要取代谁而是想在 LZ4 和 Zstd 之间找一个压得更狠、但代价又可接受的平衡点。1.2 Colibri 是什么名字又是个什么来头Colibri 本质上是一个基于 LZ4 算法改进而来的压缩器类名是org.apache.cassandra.io.compress.ColibriCompressor在 Cassandra 4.1 里正式登场源码实现里可以看到它对 LZ4 的块匹配和熵编码阶段做了优化让压缩率明显高于原生 LZ4。名字 Colibri 在拉丁语系里是蜂鸟的意思取这个名字我觉得挺妙的蜂鸟体型小但翅膀频率极高暗合了体积小、速度快、效率高的产品气质比那些冷冰冰的缩写好记多了。我在测试环境里拿一套真实的时序数据做过对比原始数据是 JSON 格式的设备日志单条几百字节到几 KB 不等SSTable 未压缩状态下 1.87 TB。LZ4 压完之后剩 620 GB压缩率大概 66.8%Zstd 压到了 480 GB压缩率 74.3%Colibri 压下来是 510 GB压缩率 72.7%非常接近 Zstd 的收益但 CPU 开销只比 LZ4 高一部分没有 Zstd 那种恐怖的飙升。这个结果对我来说是很有吸引力的。2. 核心原理与关键参数搞懂这几个参数才算会用2.1 Colibri 的压缩原理和性能折中策略要理解 Colibri先得理解 LZ4 的原理。LZ4 属于 LZ77 家族的实现核心思路是用滑动窗口 哈希表找重复的字符串块然后输出(offset, length)的引用关系对于无法匹配的字节则直接原样输出。LZ4 在找匹配时用的是贪心快速哈希所以速度极快但压缩率一般因为它在匹配长度、熵编码这些环节上做了一定妥协。Colibri 的改进恰恰是在这些妥协点上下手。它保留了 LZ4 的高速哈希匹配结构但在匹配到重复块之后增加了对匹配结果的处理优化使其能拿到更紧凑的表达。简单说LZ4 是差不多压一下就行Colibri 是既然都找到重复了就把重复信息用更省空间的方式写出来。这种设计带来的结果就是压缩率提升的同时CPU 开销不像 Zstd 那样暴涨官方文档中的定位是high compression ratio with low system overhead说人话就是你得到的压缩率比 LZ4 好不少CPU 代价又没有 Zstd 那么狠。2.2 关键参数逐个拆解chunk_length_in_kbColibri 和其他压缩器一样支持chunk_length_in_kb也就是压缩块的大小默认值是 16 KB。这个参数很多人建表时直接忽略但它对压缩率和读性能的影响很大。Cassandra 在落盘时会把数据按 chunk 切分成块每个块独立压缩。块越小读取单条数据时需要解压的数据量就越少适合点查密集的业务块越大压缩字典的容量越大文本类数据的压缩率会更好但读取任意一条数据都可能要解压整个大块。实际操作里如果表是典型的时序数据写入、分析型扫描为主我会把 chunk 调大到 64 KB 甚至 256 KB实测压缩率能再提升 3% 到 6%。如果表是订单状态、用户信息这种高频点查场景保持 16 KB 就好别为了那一点压缩率牺牲读延迟。2.3 关键参数逐个拆解tombstone_threshold 与 crc_check_chancetombstone_threshold是 Colibri 相比其他压缩器新增的一个参数默认值是 0.3。这个参数控制的是在压缩一个 SSTable 时如果检测到表中有墓碑tombstone数量超过阈值比例压缩器会优先执行墓碑清理相关的操作而不是单纯追求压缩率。这个设计很聪明因为 Cassandra 的删除操作其实只是写一个删除标记被删除的数据要等 compaction 才能真正清掉。如果压缩器只顾着把数据压得更小却不去处理墓碑堆积时间长了读性能会明显劣化。Colibri 把墓碑清理纳入压缩策略里等于让压缩过程顺带做了存储回收。crc_check_chance则是校验相关的参数默认 1.0表示读取时对每个压缩块做 CRC 校验的概率。保持默认就好不建议为了性能改成 0否则数据损坏的早期信号容易被吞掉。参数名默认值作用建议chunk_length_in_kb16压缩块大小影响压缩率与读放大点查场景保持 16分析场景可调大tombstone_threshold0.3压缩时触发墓碑清理的阈值删除频繁的表可调低到 0.2crc_check_chance1.0读取时校验 CRC 的概率保持 1.0 即可3. 实操步骤从零启用 Colibri 并验证收益3.1 建表时直接指定 Colibri 压缩器如果是在建表阶段就决定使用 Colibri操作很简单CREATE TABLE 语句里加上 compression 配置就行。类名必须是org.apache.cassandra.io.compress.ColibriCompressor拼写别错大小写也要注意CQL 解析对类名是敏感的。CREATE TABLE IF NOT EXISTS sensor.raw_data ( device_id text, ts timestamp, payload blob, PRIMARY KEY ((device_id), ts) ) WITH compression { class: org.apache.cassandra.io.compress.ColibriCompressor, chunk_length_in_kb: 16, tombstone_threshold: 0.3 };这里要提醒一点如果你是从旧版本升级上来的集群想用 Colibri得先确认所有节点都已经升级到 Cassandra 4.1 或更高版本。版本不一致的情况下有些节点可能无法识别这个压缩器类轻则建表失败重则读写异常。3.2 存量表如何平滑切换到 Colibri存量表改压缩器不需要重建数据用 ALTER TABLE 改配置然后触发一次 compaction 让 SSTable 重写就能逐步切换到新压缩算法。ALTER TABLE sensor.raw_data WITH compression { class: org.apache.cassandra.io.compress.ColibriCompressor, chunk_length_in_kb: 16, tombstone_threshold: 0.3 };执行完 ALTER 之后光靠日常 compaction 可能比较慢尤其是大表有时一周都轮不到重写全部 SSTable。建议手动触发一次针对表的 compactionnodetool compact sensor raw_data手动 compaction 会重写全部 SSTable耗时可能很久建议放在业务低峰期做。如果表非常大也可以分批做先等自动 compaction 跑一部分再手动补一轮。3.3 验证压缩效果用数据说话切换到 Colibri 后怎么确认它真的生效了最直接的方法是看系统的nodetool tablestats输出关注 SSTable 大小和压缩率nodetool tablestats sensor.raw_data输出里有一段类似这样的信息SSTable count: 128 Space used (live): 510 GB Space used (total): 510 GB ... Compression ratio: 0.273这里的Compression ratio指的是 SSTable 压缩后大小除以未压缩大小的比例0.273 意味着压缩后只剩原始数据的 27.3%空间节省了 72.7%。对比切换之前 LZ4 的压缩率 0.332空间占用从 620 GB 降到了 510 GB节省了大约 110 GB。如果想对比得更细致可以用sstabledump看单个 SSTable 的元数据里面同样有压缩信息。但实际运维中nodetool tablestats已经足够不用每次都去翻文件。还有一个小技巧建一个和原表结构相同但使用 LZ4 的临时表写入同样的数据然后对比两个表的 SSTable 总大小。这个对比最适合用来给你老板展示为什么要换压缩器数据一摆比讲半天原理都有说服力。4. 什么数据适合用 Colibri先算好这笔账4.1 压缩率收益最明显的几类数据特征Colibri 不是所有场景都划算它的优势建立在数据本身存在大量可压缩信息的前提上。根据我自己的经验下面这几类数据用 Colibri 收益非常明显。第一类是时序指标数据。设备上报的状态、温度、速率这类数据很多字段值是连续相近的比如一百条数据里 CPU 使用率都在 20% 到 30% 之间波动LZ4 能压掉一部分Colibri 能把这些相近值用更紧凑的方式表达压缩率直接拉开差距。第二类是文本和日志数据。JSON 日志、访问日志里大量重复的键名、固定的状态码、反复出现的 URL 路径整体重复度非常高。这类数据在 Colibri 下的压缩率我见过夸张到 85% 以上的场景比 LZ4 高出接近 10 个百分点。第三类是枚举值较多的嵌入式数据。比如智能硬件上报的开关状态、错误码、协议版本等这些字段的取值范围有限重复频率高天然适合这种偏熵编码的压缩器。我在生产环境里有一套设备元数据表存储的是设备心跳和配置快照字段以短字符串和数字为主。LZ4 压缩后 2.1 GBColibri 压缩后 1.6 GB压缩率提升约 23%而 CPU 增加幅度几乎可以忽略因为这个表的写入 TPS 本来就不高瓶颈本来就在磁盘。4.2 不适合 Colibri 的场景别为了省空间踩性能坑有适合的自然就有不适合的。下面这几类场景我建议谨慎甚至不要用 Colibri。第一类高基数随机数据。比如存储 UUID、哈希值、加密后的字段这些内容本身熵极高几乎没有可压缩性。碰上这种情况Colibri 和 LZ4 的差异可能只有一两个百分点但 CPU 开销的差距却实实在在属于纯亏。第二类已经压缩过的数据。比如 JPEG 图片、视频二进制、压缩包文件它们内部已经做过一次压缩外层再怎么压也压不动纯粹白费 CPU。第三类超高频写入的点查场景。如果一个表 TPS 几万甚至更高且每次查询都是按主键读单条数据那么压缩路径上的 CPU 开销会被放大。Colibri 的压缩率比 LZ4 好但压缩耗时也高一些写入和读取两条路径都会被拖累。在这个场景下我更倾向于保留 LZ4然后把节省下来的 CPU 预算留给查询。一句话总结Colibri 适合写多读少、数据重复度高、空间成本敏感的表不适合写密集、点查密集、数据高随机的表。4.3 压测对比方法动手之前先做一轮理性判断如果你拿不准某个表到底适不适合 Colibri我建议不要拍脑袋直接用 cassandra-stress 或者业务流量回放做一轮对比测试。方法不复杂先导出线上表的一段真实数据或者用代表性数据灌入两张表一张用 LZ4一张用 Colibri然后分别量三个指标写入 TPS、P99 读延迟、SSTable 占用空间。cassandra-stress write n1000000 -schema test.lz4_table -mode native cql3 -pop seq1..1000000 -rate threads50 cassandra-stress write n1000000 -schema test.colibri_table -mode native cql3 -pop seq1..1000000 -rate threads50同样的数据量就看两边的空间差异和耗时差异再结合业务的读模型自己权衡。比看任何人写的架构分析都靠谱。5. 常见问题与排查技巧实录5.1 切换后 CPU 突然变高是怎么回事有几次在存量表上切换 Colibri 后发现节点 CPU 使用率在段时间内明显上涨很多朋友的直觉是完了压缩器太吃 CPU立刻就想回滚。其实这不一定是坏事。大概率是手动 compaction 正在重写存量 SSTable所有数据都在重新压缩一遍CPU 当然会升高。这个阶段过了之后CPU 会回落到正常水平。所以在切换之前一定要看当前节点的 compaction 压力如果大堆 SSTable 排队等着压缩建议错峰执行。如果 compaction 都跑完了 CPU 还是高这时候才需要认真看写入路径。可以用pidstat或top按线程查看 CPU 消耗确认是压缩线程还是 compaction 线程占用的资源。5.2 设置了 tombstone_threshold 但空间没有回收这是比较容易误解的一个点。tombstone_threshold 不是压缩时只要超过阈值就把墓碑清干净而是如果墓碑占比超过阈值compaction 会更积极地处理这个 SSTable。实际的清理动作仍然取决于 SSTable 之间是否可以合并、key 的分布情况。具体场景举例如果你的表数据分布非常散每个 SSTable 的 key range 重叠很多那么几个 SSTable 大概率无法在 compaction 时合并成新的 SSTable墓碑也就一直没法清理。这种情况下调低 tombstone_threshold 帮助也有限根本解法还是调整 compaction 策略或者主动做 major compaction。nodetool garbagecollect sensor raw_data这个命令可以帮你快速回收数据目录中可以被安全移除的墓碑文件但它不是魔法前提是数据确实已经达到清理条件。5.3 Colibri 和采集监控、备份恢复的兼容性很多监控工具会通过 JMX 抓取 compressed ratio 等信息这部分不受影响。备份恢复场景要关注的是SSTable 在磁盘上已经是压缩后的形态我们做快照备份时拿到的大小就是压缩后的大小这本身是好事但如果你依赖备份文件直接做数据恢复演练需要确保目标集群版本也能识别 Colibri 压缩器否则 restore 节点可能报Unknown compression class之类的错误。跨版本升级或迁移时的建议是先在两三个节点上升级并开启 Colibri 验证无异常再逐步全量切换不要一次性把整集群的压缩器都换掉。5.4 常见问题速查表现象可能原因排查思路切换后 CPU 飙升手动 compaction 在重写 SSTable等 compaction 结束再观察错峰操作压缩率提升不明显数据本身是高随机/已压缩内容检查数据类型考虑换回 LZ4磁盘空间没有明显减少表中的 tombstone 比例高压缩策略偏向清理墓碑调低 tombstone_threshold配合 garbagecollect恢复时报压缩类错误备份文件使用了高版本压缩器但恢复集群版本较低确保所有节点版本不低于 4.1点查延迟上升chunk 过大导致读取时解压过多数据将 chunk_length_in_kb 调回 166. 踩坑心得与运维建议6.1 先小范围验证再全量铺开Colibri 的引入对存量集群不算大手术但也不是完全无感。我的习惯是先挑一个数据特征有代表性、业务容忍度较高的表开 Colibri跑两周把压缩率、CPU、读写延迟的数据都收集齐确认没有异常再逐步推广到其他表。不要在一个集群里同时把几十张表一起切换出问题的时候定位成本会很高。运维这件事稳永远是第一位的。6.2 结合数据生命周期做多级压缩策略实际运营中同一个集群里不同的表冷热差异很大一张压缩器配置打天下是不现实的。我目前比较推荐的组合是热表用 LZ4追求低延迟温表用 Colibri在成本和性能之间找平衡归档表继续用 Zstd 或者直接不关心读性能怎么省空间怎么来。Cassandra 的 compression 配置是按表独立设置的这给了我们很大的灵活度。你完全可以根据每一张表的读写比例、数据特征、容量规划来做单独的策略而不必局限于全集群统一用一种的思路。6.3 容量规划时要看压缩率趋势最后分享一个容易被忽略的细节定期记录nodetool tablestats里的 compression ratio。这个指标如果出现持续上升说明数据可压缩性变差了可能意味着数据特征在变化或者表里堆了大量随机写入的内容。反之如果 ratio 持续下降说明压缩效果在变好。我习惯在监控系统里给 compression ratio 配置一个趋势告警一旦连续几周偏差超过 5%就主动去查一下表的数据构成。成本优化的前提是数据可见压缩率趋势就是存储成本的一个先行指标。Colibri 这个压缩器整体用下来给我的印象是方向对、参数简单、收益可量化。它不是那种颠覆性的技术革命但确实让 Cassandra 用户在 LZ4 和 Zstd 之外多了一个非常有竞争力的选项。如果你现在正在为存储成本发愁手上又有大量重复度高的数据真的可以试试它。

相关新闻

人工智能深度开发:从技术体系到工程化落地的完整实践指南

人工智能深度开发:从技术体系到工程化落地的完整实践指南

很多人以为人工智能深度开发就是“会用框架调包、能跑通开源模型”,但在实际项目中真正决定成败的,从来不是某一次训练跑得有多快,而是从数据到模型再到上线维护这一整条链路能不能体系化地运转。这篇文章围绕“人工智能深度开发”这个话题&a…

2026/10/17 8:38:24 阅读更多 →
本地部署AI水印修复:从原理到实战的无损去水印全流程

本地部署AI水印修复:从原理到实战的无损去水印全流程

水印这东西,做图的人天天见,想躲都躲不开。找个素材图,角落一个Logo;截个聊天记录,中间一行推广ID;下载个模板,底下半透明网址。以前遇到这种图,要么拿裁剪硬切,要么开PS…

2026/10/17 8:38:24 阅读更多 →
OCV光学字符检测实战:从原理到参数设置与现场排障

OCV光学字符检测实战:从原理到参数设置与现场排障

作为一个常年泡在产线上的视觉工程师,我隔三差五就会遇到有人拿着“OCR字符识别”的需求来找我,结果聊深了才发现,人家真正想要的其实是OCV(光学字符验证)。这俩名字听着像兄弟,干的活儿却完全是两码事。今…

2026/10/17 8:38:24 阅读更多 →

最新新闻

WSL+tmux从零配置到实战:打造Windows高效命令行环境

WSL+tmux从零配置到实战:打造Windows高效命令行环境

最近帮朋友把一台Windows系统配成日常开发环境,发现很多人其实对WSL和tmux这两个名字都熟悉,但真正组合起来用的不多。我在Windows 10/11上用WSL跑了挺久,命令行工作从git到批量改文件、编译、挂机跑脚本,基本都搬进了tmux里。这篇…

2026/10/17 9:28:39 阅读更多 →
Linux home目录迁移实战:rsync、权限与挂载全解析

Linux home目录迁移实战:rsync、权限与挂载全解析

1. 迁移home目录这件事,远比你想的要折腾很多人第一次听到“迁移home目录”,脑子里浮现的画面大概就是拖拽文件夹,等进度条走完,重启,收工。我当初也是这么想的,直到有一次在一台用了三年的开发机上动手&am…

2026/10/17 9:28:39 阅读更多 →
SBTI科学碳目标解读:企业如何完成从碳盘查到目标获批的减排路径

SBTI科学碳目标解读:企业如何完成从碳盘查到目标获批的减排路径

不知道从什么时候开始,供应链问卷、招标文件、投资者沟通材料里,越来越多的企业开始主动或被动地聊起“SBTI”这三个字母。我印象很深的一件事是,早几年给客户做碳排放规划,方案做完了,对方一句“先放一放,…

2026/10/17 9:28:39 阅读更多 →
ClickHouse日志平台实战:从ES迁移、表结构设计到查询调优

ClickHouse日志平台实战:从ES迁移、表结构设计到查询调优

做大数据的人,迟早要跟日志打交道。业务日志、访问日志、服务日志、安全审计日志,哪一类都是量大、格式杂、查询需求刁钻。我最早用Elasticsearch做日志平台,后来数据量上来之后,集群规模、存储成本、查询毛刺这些问题接踵而至&am…

2026/10/17 9:28:39 阅读更多 →
2026年AI大模型API聚合平台排名揭晓:这三家平台表现出彩,助你开发无忧

2026年AI大模型API聚合平台排名揭晓:这三家平台表现出彩,助你开发无忧

进入2026年,大模型的迭代节奏快得让人应接不暇,GPT-5.4、Claude4.6、Gemini3.1Pro 几乎每个月都有新版本放出来。对开发者而言,逐家注册账号、分别保管密钥、各自编写适配逻辑的传统做法,已经很难跟上这种月更速度,API…

2026/10/17 9:28:39 阅读更多 →
不完全信息Epsilon纳什均衡在航天器末端追逃博弈的Matlab实现

不完全信息Epsilon纳什均衡在航天器末端追逃博弈的Matlab实现

作为研究航天器近距离任务的开发者,我们组在复现不完全信息Epsilon纳什均衡的航天器末端追逃博弈策略(Matlab代码实现)这篇论文时,最大的感受是:以前觉得博弈论在航天里就是理论推推公式,真正要把“对方参数…

2026/10/17 9:27:38 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →