Databend 全鏈路追蹤
全鏈路追蹤意味著能夠追蹤到每一個(gè)調(diào)用請(qǐng)求的完整調(diào)用鏈路、收集性能數(shù)據(jù)并反饋異常。Databend 使用 tracing 賦能可觀測(cè)性,實(shí)現(xiàn)全鏈路追蹤。
Databend 與 Tracing
初步了解 Databend 怎么實(shí)現(xiàn)全鏈路跟蹤。
初識(shí) Tracing

項(xiàng)目地址:https://github.com/tokio-rs/tracing
示例:
use?tracing::{info,?Level};
use?tracing_subscriber;
fn?main()?{
????let?collector?=?tracing_subscriber::fmt()
????????//?filter?spans/events?with?level?TRACE?or?higher.
????????.with_max_level(Level::TRACE)
????????//?build?but?do?not?install?the?subscriber.
????????.finish();
????tracing::collect::with_default(collector,?||?{
????????info!("This?will?be?logged?to?stdout");
????});
????info!("This?will?_not_?be?logged?to?stdout");
}
Databend 中的 Tracing
Databend 的 tracing-subscriber 被統(tǒng)一整合在 common/tracing,由 query 和 meta 共用。
//?Use?env?RUST_LOG?to?initialize?log?if?present.
//?Otherwise?use?the?specified?level.
let?directives?=?env::var(EnvFilter::DEFAULT_ENV).unwrap_or_else(|_x|?level.to_string());
let?env_filter?=?EnvFilter::new(directives);
let?subscriber?=?Registry::default()
????.with(env_filter)????????????????#?根據(jù)環(huán)境變量過濾
????.with(JsonStorageLayer)??????????#?利用?tracing-bunyan-formatter?格式化為?json
????.with(stdout_logging_layer)??????#?標(biāo)準(zhǔn)輸出
????.with(file_logging_layer)????????#?輸出到文件,默認(rèn)位于?`_logs`?目錄下
????.with(jaeger_layer);?????????????#?opentelemetry-jaeger
#[cfg(feature?=?"console")]
let?subscriber?=?subscriber.with(console_subscriber::spawn());?#?tokio?console
tracing::subscriber::set_global_default(subscriber)
????.expect("error?setting?global?tracing?subscriber");
具體到內(nèi)部的 tracing 記錄,大致有兩類:
普通:與其他 log 方式一樣,利用 info!、debug! 來收集信息。
use?common_tracing::tracing;
tracing::info!("{:?}",?conf);
tracing::info!("DatabendQuery?{}",?*databend_query::DATABEND_COMMIT_VERSION)Instruments:在調(diào)用函數(shù)時(shí)創(chuàng)建并進(jìn)入 tracing span(跨度),span 表示程序在特定上下文中執(zhí)行的時(shí)間段。
use?common_tracing::tracing::debug_span;
#[tracing::instrument(level?=?"debug",?skip_all)]
async?fn?read(&mut?self)?->?Result<Option<DataBlock>>?{
????...
????????fetched_metadata?=?read_metadata_async(&mut?self.reader)
????????????.instrument(debug_span!("parquet_source_read_meta"))
????????????.await
????????????.map_err(|e|?ErrorCode::ParquetError(e.to_string()))?;
????...
}
示例:
{
??"v":?0,
??"name":?"databend-query-test_cluster@0.0.0.0:3307",
??"msg":?"Shutdown?server.",
??"level":?30,
??"hostname":?"dataslime",
??"pid":?53341,
??"time":?"2022-05-11T00:51:56.374807359Z",
??"target":?"databend_query",
??"line":?153,
??"file":?"query/src/bin/databend-query.rs"
}
觀測(cè) Databend 跟蹤的方式
Databend 原生提供了多種觀測(cè)方式,以方便診斷和調(diào)試:
http tracing :訪問 localhost:8080/v1/logs(根據(jù)配置)
stdout/filelog :檢查終端輸出或 _logs 目錄(根據(jù)配置)
system.tracing 表 :執(zhí)行 select * from system.tracing limit 20;
jaeger :運(yùn)行 jaeger ,訪問?http://127.0.0.1:16686/
console :按特定方式構(gòu)建后,運(yùn)行 tokio-console
Jaeger 分布式跟蹤
使用 Jaeger 對(duì) Databend 進(jìn)行全鏈路跟蹤。
Opentelemetry & Jaeger
OpenTelemetry是工具、API 和 SDK 的集合。使用它來檢測(cè)、生成、收集和導(dǎo)出遙測(cè)數(shù)據(jù)(度量、日志和跟蹤),以幫助您分析軟件的性能和行為。Jaeger是一個(gè)開源的端到端分布式跟蹤系統(tǒng)。由 Uber 捐贈(zèng)給 CNCF 。它可以用于監(jiān)視基于微服務(wù)的分布式系統(tǒng),提供以下能力:
分布式上下文傳播
分布式事務(wù)監(jiān)視
根本原因分析
服務(wù)依賴性分析
性能/延遲優(yōu)化

Step by Step
遵循下述步驟,即可使用 Jaeger 探索 Databend :
構(gòu)建二進(jìn)制程式:cargo build(可以使用 --bin 指定)
將日志級(jí)別設(shè)定為 DEBUG ,運(yùn)行需要調(diào)試的應(yīng)用程式。例如,LOG_LEVEL=DEBUG ./databend-query
運(yùn)行 jaeger :docker run -d -p6831:6831/udp -p6832:6832/udp -p16686:16686 jaegertracing/all-in- one:latest
打開?http://127.0.0.1:16686/?以查看 jaeger 收集的信息
結(jié)果探索

執(zhí)行下述語(yǔ)句即可得到上圖所示跟蹤結(jié)果:
Timeline
下圖是點(diǎn)擊最大的圓點(diǎn)得到的跟蹤情況:

點(diǎn)開第一個(gè)跨度,可以看到這是執(zhí)行 INSERT INTO t1 SELECT *FROM t1 查詢時(shí)的情況。

Graph
切換到 graph 模式,可以看到各個(gè) span 之間的調(diào)用鏈,每個(gè) span 具體用時(shí) ,以及百分比。

Compare
連起來的各個(gè)部分形成整個(gè) trace 的調(diào)用鏈。因?yàn)楸容^時(shí)一般會(huì)比較兩個(gè)相同類型的調(diào)用,所以看到的會(huì)是重合后的視圖。

對(duì)于顏色的一個(gè)說明:
深綠色,表示這個(gè) span 只存在于 trace-B 中,A 沒有這個(gè) span
深紅色,表示這個(gè) span 只存在于 trace-A 中,B 沒有這個(gè) span
淺綠色,表示這個(gè) span 在 trace-B(右邊這個(gè))的數(shù)量多
淺紅色,表示這個(gè) span 在 trace-A(左邊這個(gè))的數(shù)量多
tokio-console 診斷
tokio-rs 團(tuán)隊(duì)出品的診斷和調(diào)試工具,可以幫助我們?cè)\斷與 tokio 運(yùn)行時(shí)相關(guān)的問題。
console 是什么

tokio-console 是專為異步程序設(shè)計(jì)的調(diào)試與診斷工具,能夠列出 tokio 的任務(wù),提供對(duì)程序的任務(wù)和資源的實(shí)時(shí)、易于導(dǎo)航的視圖,總結(jié)了它們的當(dāng)前狀態(tài)和歷史行為。主要包含以下組件:
傳輸診斷數(shù)據(jù)的協(xié)議
用于收集診斷數(shù)據(jù)的儀器
當(dāng)然,用于展示和探索診斷數(shù)據(jù)的實(shí)用工具
項(xiàng)目地址:https://github.com/tokio-rs/console
Step by Step
使用特定的 rustflags 和 features 來構(gòu)建:RUSTFLAGS="--cfg tokio_unstable" cargo build --features tokio-console ,也可以只構(gòu)建單個(gè)二進(jìn)制程式,使用 --bin 進(jìn)行指定。
將日志級(jí)別設(shè)定為 TRACE ,運(yùn)行需要調(diào)試的應(yīng)用程式 LOG_LEVEL=TRACE databend-query 或者 databend-meta --single --log-level=TRACE??梢允褂?TOKIO_CONSOLE_BIND 指定端口,以避免潛在的端口搶占問題。
運(yùn)行 tokio-console,默認(rèn)連接到?http://127.0.0.1:6669
結(jié)果探索
任務(wù)
先看什么是 tokio 任務(wù):
任務(wù)是一個(gè)輕量級(jí)的、非阻塞的執(zhí)行單元。類似操作系統(tǒng)的線程,但是是由 tokio 運(yùn)行時(shí)管理,一般叫做“綠色線程”,與 Go 的 goroutine,Kotlin 的 coroutine 類似。
任務(wù)是協(xié)同調(diào)度的。大多數(shù)操作系統(tǒng)實(shí)現(xiàn)搶占式多任務(wù)。操作系統(tǒng)允許每個(gè)線程運(yùn)行一段時(shí)間,然后搶占它,暫停該線程并切換到另一個(gè)線程。另一方面,任務(wù)實(shí)現(xiàn)協(xié)同多任務(wù)。一個(gè)任務(wù)被允許運(yùn)行直到它讓出執(zhí)行權(quán),運(yùn)行時(shí)會(huì)切換到執(zhí)行下一個(gè)任務(wù)。

基礎(chǔ)視圖
通過左右切換,可以得到總忙時(shí)間或輪詢次數(shù)等指標(biāo)對(duì)任務(wù)進(jìn)行排序。控制臺(tái)通過高亮來提示較大差異,比如從毫秒到秒的切換。

控制臺(tái)還實(shí)現(xiàn)了一個(gè)“警告”系統(tǒng)。通過監(jiān)視應(yīng)用程序中任務(wù)的運(yùn)行時(shí)操作,控制臺(tái)可以檢測(cè)可能提示 bug 或性能問題的行為模式,并突出顯示這些行為模式供用戶分析。比如已經(jīng)運(yùn)行了很長(zhǎng)時(shí)間而沒有讓步的任務(wù),喚醒的次數(shù)比被其他任務(wù)喚醒的次數(shù)還要多的任務(wù)。
任務(wù)視圖
上下切換選中任務(wù),enter 查看關(guān)于每個(gè)任務(wù)的翔實(shí)數(shù)據(jù),比如輪詢持續(xù)時(shí)間的直方圖。

不僅列出任務(wù)。console 還會(huì)插入異步互斥和信號(hào)量等資源。Tokio Console 的資源詳細(xì)信息視圖顯示了哪些任務(wù)已經(jīng)進(jìn)入臨界區(qū),哪些任務(wù)正在等待獲得訪問權(quán)限。
還能做什么
與分布式跟蹤和日志系統(tǒng)相關(guān)的一些其他內(nèi)容。
可觀測(cè)性 + +
目前還有一系列關(guān)于可觀測(cè)性和 Tracing 的 Issue 有待解決:
Integrate tokio metrics for query task based tokio runtime monitoring #4205
Configure on jaeger tracing address similar to metrics api server #3633
Summary of todos about distributed tracing #1227
Query traces and analysis, based on user behavior. #1177
Http stack traces #1085
Shuffle read/write metrics #1004
另外,更進(jìn)一步的考量是,如何基于可觀測(cè)性來自動(dòng)/半自動(dòng)地發(fā)現(xiàn)問題并對(duì)系統(tǒng)進(jìn)行調(diào)優(yōu)。了解更多
了解更多
Tracing
https://github.com/tokio-rs/tracing
https://docs.rs/tracing/latest/tracing/
https://tokio.rs/blog/2019-08-tracing
Jaeger
https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-jaeger
https://21-lessons.com/ship-rust-tracing-spans-to-jaeger/
tokio-console
https://github.com/tokio-rs/console
https://hackmd.io/@aws-rust-platform/ByChcdB-t
https://tokio.rs/blog/2021-12-announcing-tokio-console
關(guān)于 Databend
Databend 是一款開源、彈性、低成本,基于對(duì)象存儲(chǔ)也可以做實(shí)時(shí)分析的新式數(shù)倉(cāng)。期待您的關(guān)注,一起探索云原生數(shù)倉(cāng)解決方案,打造新一代開源 Data Cloud。
Databend 文檔:https://databend.rs/
twitter:https://twitter.com/Datafuse_Labs
Slack:https://datafusecloud.slack.com/
Wechat:Databend
GitHub :https://github.com/datafuselabs/databend
