Iteration 9 开了一个新坑: reqsign,用于对用户的请求进行签名,使得用户不再需要依赖 SDK,在上一期的周报中已经进行了比较详细的介绍,今天就不再展开了。

Say goodbye to aws-s3-sdk

随着 reqsign 的实现和不断完善,opendal 终于能够彻底解决跟 SDK 相关的问题。在 PR refactor: Say goodbye to aws-s3-sdk 中,opendal 彻底去掉了 aws-s3-sdk,改成了使用 reqsign 来发送请求,这个变更随后也更新到了 databend。根据测试结果,这次的更新没有 break 现有的应用,也没有出现明显的性能影响,为后续基于统一的 HTTP Client 做超时,重试等逻辑打了一个比较好的基础。

Databend 长期以来一直备受 hyper 的 dispatch dropped without returning error panic 困扰,去掉 S3 SDK 之后,业务上对 HTTP Client 的行为有了更大的控制力度。在 PR refactor: Adapt reqsign and separate IO runtime 中,我将所有的 IO 相关任务都调度到了统一的 IO Runtime 上,彻底解决了这一问题。这个改动还是比较简单粗暴的,所有的 IO 任务都调度到了同一个全局的 Runtime 上。后续随着 Databend 的新调度框架上线,我计划配合做一些改造,让调度框架能够更好的调度 IO 任务。

Bug in blocking::Unblock

在压力测试中 Databend 发现 fs backend 有时候会返回 EOF 错误:bug: unblock fs will result in EOF under concurrent read_exact。研究发现 blocking::Unblock 的行为不符合 AsyncRead 的 Spec,在 read 中有时候会返回 0,而这通常会被视作所有数据已经读取完毕。尤其是在 read_exact 的时候,futures 会直接返回 EOF 错误:

2022-03-13T14:06:31.619308Z  INFO opendal::io: object 2/1/_b/660e9f382bec4fcd91e4c84ea0ede809.parquet poll_read: size 0
2022-03-13T14:06:31.619475Z ERROR databend_query::storages::fuse::io::block_reader: read file 2/1/_b/660e9f382bec4fcd91e4c84ea0ede809.parquet total 3783 at offset 1138 size 63: unexpected end of file

时间紧迫没有仔细研究 blocking 的具体实现,选择先 rollback 回到 tokio::fs: services/fs: Refactor via tokio::fs。下个 Iteration 有空的话需要研究一下如何最小化复现这个问题,并给上游提交一个 BUG。

Make pprof-rs works on musl

pprof-rs 是 TiKV 社区开发的 CPU profiler。因为 musl 不支持 pthread_getname_np,pprof-rs 长期以来一直无法在 musl target 上工作。根据 @YangKeao 的调研 [WIP] Support musl,除了 pthread_getname_np 的问题之外,backtrace 也无法正常工作。

不过对于 Databend 来说,我们没有在 musl target 上进行 benchmark 的需求,只需要 pprof-rs 能够正常编译。所以我提交了 PR profiler: Fix pthread_getname_np not available on musl,在 musl 平台下使用 write_thread_name_fallback 而不是 pthread_getname_np。在这个 PR 之后,pprof-rs 已经可以在 x86_64-unknown-linux-musl 上正常编译了。

基于这个修改,我为 databend 修复了 musl 构建支持:build: Fix musl support。社区的小伙伴在这个基础上增加了 databend 的 musl 纯静态二进制,摆脱了在特定平台上 libssl 和 libc 兼容性的问题。考虑到 musl 的性能一直备受争议,我们对纯静态的二进制做了一些 benchmark,结果显示大部分 Query 的性能出现了 2% 到 5% 左右的回退,个别 Query 性能下降了 10%,总的来说可以接受。对性能有要求的同学还是推荐使用动态编译的版本,而简单体验一下的话使用纯静态二进制完全能满足需求。


下个 Iteration 我计划对 OpenDAL 进行一次大规模的重构,使得用户能够更细致的控制底层的行为,减少 async 封装带来的开销,适应 Databend 新调度框架对 IO 的细致调度需求;同时为 OpenDAL 增加 Azure Blob 和 Google Cloud Storage 的支持,这样 OpenDAL 就完整地支持了三种主流的对象存储服务,初步地实现了项目的愿景:Open Data Access Layer that connect the whole world together.