写在最前
敬畏生产!——zilliz技术总监栾小凡
Birdwatcher 对 Etcd 的写操作必须有Dry run ——某匿名 Birdwatcher 作者
用 Birdwatcher 操作前先备份!——某匿名 Birdwatcher 作者
Birdwatcher 作为一款 Milvus 2.x 元数据工具,自 2022 年诞生,目前已正式发布至 v1.0.1 版本。根据之前的文章,大家已经对 Birdwatcher 有了基本的了解。不过,大部分用户可能并不清楚 Birdwatcher 的真正实力,悄悄透露一下,在版本发布期间,Birdwatcher 已经帮助 Milvus 社区的开发者、用户定位和解决了若干问题。而 Birdwatcher 的 Etcd 备份已经成为 Milvus issue 中“现象”“日志”“Birdwatcher 备份”三大常客之一。
本文将通过社区中几个常见的典型场景,为大家介绍 Birdwatcher 在 Milvus 的优化和问题定位中起到何种作用以及用户该如何去使用它。
性能问题分析
Milvus 2.x 作为一款支持流批一体的向量数据库,能同时处理流式(未创建索引)和批式(已创建)的数据。由于向量记录本身的特性,对于流式的数据的查询(ANN、点查等)通常会比批式数据慢。这往往是在实际场景中查询性能下降/不稳定的原因。
在实际生产环境推荐使用 Info 级别的日志,在这个级别下,我们通常无法通过日志信息获知是否在 QueryNode 上发生的流式数据的查询。不止如此,在旧版本的 Promethues Dashboard 上,也无法查询此信息。
此时,Birdwatcher 闪亮登场:
Birdwatcher 提供了查询show segment-index
命令,用来查询 segment 的索引构建进度:
(注:旧版本截图)
上图为 issue 中用户提供的截图,从中可以看到有部分 segment 的索引一直处于 “Unissued/InProgress” 状态,即数据处于无索引状态,因此,所有的搜索都处于暴搜状态导致性能下降。
https://github.com/milvus-io/milvus/issues/19042
https://github.com/milvus-io/milvus/issues/20012
对于没有部署 promethues 监控的用户(这里还是推荐大家部署的!),可以使用 Birdwatcher 来快速查询 querynode 上的 segment 状态。
2.1.x 系统卡死的修复
在 Milvus 2.1.x 版本中,由于一些已经修复的 bug,collection 的 load/release 操作可能会因为内存或者其它问题被卡死导致系统无法服务,在“远古”时代,Birdwatcher 是安全清理 Querycoord 上被卡死的 Load/Release 操作的工具。
具体 issue 参见:
https://github.com/milvus-io/milvus/issues/19061
https://github.com/milvus-io/milvus/issues/19586
https://github.com/milvus-io/milvus/issues/19818
另外,建议仍在使用 Milvus 2.1.x 版本的用户升级至 2.2 版本,升级链接参见:https://milvus.io/docs/upgrade_milvus_cluster-helm.md
元数据修复
Etcd 元数据是 Milvus 2.x 得以正常运行的根本,但是在某些特殊情况下,如:
- 使用有特定bug的开发版本
- 错误的升级方式
- 某些未修复的隐藏bug
可能会导致 Milvus 的元数据发生问题,而这正是 Birdwatcher 的强项。
Empty Segment
在系统中,设计上不允许一个没有任何 binlog、statslog 和 deltalog 的 sealed segment 存在,但是由于 2.1 版本中一个已经修复的 bug,在重启集群时,会产生一个行数为 0 的空 segment,使得系统进入一个无法恢复的错误状态。
这种时候,通过外部 API 是无法快速地清理此问题,所以 Birdwatcher 为这个场景提供了一个clean-empty-segment
(正式release更名为remove segment
)
https://github.com/milvus-io/milvus/issues/16451
Segment Binlog 和索引文件不匹配
在当前的 Milvus 系统中,索引文件和 binlog 是“一一对应”的(实际上是一批对一批,原谅一个技术人对细节描述的强迫症),我们会在元数据中记录这批 binlog 的总行数和索引文件对应数据的总行数。
而因为一个设计上的疏忽,在旧版本的 Milvus 系统中,出现部分数据被重复落盘并且多余索引文件的情况。这会导致 segment 在加载时元数据校验失败,最终引起 Load 操作报错。
最终通过 Birdwatcher 的备份定位到索引文件和 binlog 的文件的对应问题,并且提供了修复此问题的命令:
详情见:
https://github.com/milvus-io/milvus/issues/19500
残留的 Segment 信息
这个场景是某位社区用户提供的,造成 bug 的初始原因已不可考,但是从日志可以看到系统处于一个 Etcd 元数据和对象存储不匹配的状态。即 Etcd 的元数据记录该 segment 的 binlog/statslog/deltalog 为如下若干文件,但是在对应的 minio 或者 s3 的路径下,文件已经被删除了(表现为报错—— NoSuchKey)。
在认为该 segment 已经被 compacted,并且数据完整的情况下,引入了下列命令:remove segment
https://github.com/milvus-io/milvus/issues/19610
远古 Channel checkpoint
在 Milvus 2.2 之前,各个组件从 MQ 消费数据的 checkpoint 是由所有对应的 segment 的 checkpoint 计算而来的。这个逻辑易错且容易引入各种 bug,所以在 2.2 版本我们重新设计了 channel checkpoint 机制。
不过,如果系统是从 Milvus 低版本升级到 2.2.x,那么系统还需要从 segment 重新计算一个 channel checkpoint,而这个 checkpoint 可能因为低版本的各种问题十分落后(先于当前时间若干天)。这会导致系统需要很长的恢复时间,在某些情况下甚至无法恢复。
遇到此类问题的时候,就需要 birdwatcher 来快速止血。我们为此类问题加入了如下命令,将对应 channel 的 checkpoint 设置为对应 topic 的指定 position,让系统可以快速恢复可服务状态:
1 repair checkpoint --collection 437744071571606912 --vchannel by-dev-rootcoord-dml_3_437744071571606912v1 --mq_type kafka --address localhost:9092 --set_to latest-msgid
2 repair checkpoint --collection 437744071571606912 --vchannel by-dev-rootcoord-dml_3_437744071571606912v1 --mq_type pulsar --address pulsar://localhost:6650 --set_to latest-msgid
https://github.com/milvus-io/milvus/issues/21527
残留 Channel Watch 信息
线下用户从 2.1 升级 2.2 时,替换了 pulsar 集群,但是复用了 etcd 和对象存储(并且配置 RootPath 完全相同),导致消息队列和 Etcd 发生不一致。
这个时候会导致系统不断消费一个不存在的 topic,并且由于其时间点非常久远,会导致 pulsar 集群的资源使用异常(打在了冷数据上)。这就使得系统处于一个非常不稳定的状态,于是 Birdwatcher 为此提供了修复命令:
以上就是本次有关 Birdwatcher 场景的全部内容,欢迎有兴趣的小伙伴使用或加入贡献代码的行列!
本文由mdnice多平台发布
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net