- 從可觀測性建設(shè)角度出發(fā),總結(jié)大家在日常工作中遇到的痛點(diǎn);
- 介紹 DeepFlow 的軟件架構(gòu)、系統(tǒng)組成;
- 講解 DeepFlow 的關(guān)鍵特性 AutoTagging 技術(shù);
- 講解支撐 AutoTagging 10x 性能提升的 SmartEncoding 技術(shù);
-
總結(jié)并分享后續(xù)的迭代和演進(jìn)計(jì)劃。
01觀測數(shù)據(jù)存儲的挑戰(zhàn)
可觀測性建設(shè)從去年開始在國內(nèi)非常的火熱,大家談的越來越多。隨著云原生、微服務(wù)的發(fā)展落地,可觀測性建設(shè)逐漸成為了一個必不可少的工程手段。可觀測性建設(shè)耗時長我們認(rèn)為應(yīng)用開發(fā)團(tuán)隊(duì)花了一半的時間用于可觀測性的建設(shè)。這張圖里面可以看到,開發(fā)者通常需要考慮在不同的 Dev Stack 和 Infra Stack 中如何埋點(diǎn)、如何插碼、如何傳遞追蹤上下文、如何生成指標(biāo)/追蹤/日志數(shù)據(jù)并進(jìn)行關(guān)聯(lián),需要考慮的問題太多太雜。除此之外開發(fā)者還有很多時間在做 Debug,而這些 Debug 之所以耗費(fèi)了這么多時間,通常大部分是因?yàn)榭捎^測性建設(shè)的欠缺導(dǎo)致。可觀測性建設(shè)數(shù)據(jù)關(guān)聯(lián)難可觀測性指標(biāo)數(shù)據(jù)一般分為Tracing、Metric和Logging三類。
- Tracing關(guān)注的元數(shù)據(jù)是traceID/spanID/service/...;
- Metric關(guān)注的元數(shù)據(jù)是vpc/instance/node/kvm/...;
-
Logging關(guān)注的元數(shù)據(jù)是type/level/time/message/...。
02、DeepFlow 軟件架構(gòu)
DeepFlow軟件架構(gòu)DeepFlow的架構(gòu)其實(shí)非常簡單,它簡單到只有一個Agent和一個Server,分別是數(shù)據(jù)采集組件和數(shù)據(jù)存儲查詢組件。Agent是使用Rust來實(shí)現(xiàn)的,高性能且內(nèi)存安全,它通過eBPF技術(shù)實(shí)現(xiàn)了對任意開發(fā)技術(shù)棧、任意基礎(chǔ)設(shè)施的全自動應(yīng)用性能指標(biāo)數(shù)據(jù)采集(AutoMetrics),以及自動化的分布式鏈路追蹤(AutoTracing),這兩項(xiàng)是DeepFlow Agent獨(dú)有的能力,能極大降低開發(fā)者建設(shè)可觀測性的工作量。Server包含了4個內(nèi)部模塊:Controller面向采集器Agent的管理,能納管多資源池的10萬量級的Agent;Labeler面向標(biāo)簽數(shù)據(jù)的自動注入,提供AutoTagging的能力;Querier面向數(shù)據(jù)查詢,提供統(tǒng)一的SQL接口;Ingester面向數(shù)據(jù)存儲,提供插件化的、可替換可組合的數(shù)據(jù)庫接口。它支持水平擴(kuò)展,而且完全不依賴外部的消息隊(duì)列或負(fù)載均衡,就能夠去實(shí)現(xiàn)對多個Region、多個資源池中Agent的負(fù)載均攤。Server也有兩個非常核心的技術(shù),AutoTagging和SmartEncoding。通過AutoTagging我們能為Agent采集到的所有觀測數(shù)據(jù)自動注入統(tǒng)一的資源、實(shí)例和API標(biāo)簽,使得我們能夠消除不同數(shù)據(jù)類型之間的隔閡,增強(qiáng)所有數(shù)據(jù)的關(guān)聯(lián)、切分、下鉆能力。SmartEncoding是我們非常創(chuàng)新的一個高性能的標(biāo)簽編碼機(jī)制,通過這個機(jī)制,我們既能方便的進(jìn)行數(shù)據(jù)關(guān)聯(lián),又能將標(biāo)簽注入的存儲性能提升10倍,這在我們的實(shí)際生產(chǎn)環(huán)境中已經(jīng)進(jìn)行了廣泛的驗(yàn)證。
03、AutoTagging:構(gòu)建標(biāo)準(zhǔn)化的標(biāo)簽體系
AutoTagging通過云API、K8s apiserver自動同步30多種資源標(biāo)簽、100多種自定義微服務(wù)標(biāo)簽,來構(gòu)建標(biāo)準(zhǔn)化的標(biāo)簽體系。DeepFlow資源同步DeepFlow的標(biāo)簽體系:
-
自定義標(biāo)簽
- k8s.label/k8s.env/k8s.annotation/..
- os.app/os.proc/...
- cloud.tag
-
進(jìn)程
- 進(jìn)程名
-
云資源
- 資源池:區(qū)域/可用區(qū)
- 計(jì)算資源:云服務(wù)器/宿主機(jī)
- 網(wǎng)絡(luò)資源:VPC/子網(wǎng)/路由器/IP地址
- 網(wǎng)絡(luò)服務(wù):安全組/負(fù)載均衡器/NAT網(wǎng)關(guān)/對等連接/云企業(yè)網(wǎng)
- 存儲資源:云數(shù)據(jù)庫RDS/Redis
-
容器資源
- 容器集群/容器節(jié)點(diǎn)/命名空間/Ingress/容器服務(wù)/工作負(fù)載/POD
- 為什么是 Agent watch 并上報(bào) K8s資源?一個 Server 可以管理多個集群中的 Agent,Agent在所屬集群中watch K8s,避免了集群外部用 server watch 時涉及到的權(quán)限和配置問題。
- 如何控制 Agent 對 K8s 資源的 watch?避免 K8s 的 API 壓力過大,不能讓所有的 Agent 都去 watch K8s,Server 在每個集群中選舉一個 Agent;僅讓被選中的 Agent watch K8s 資源。
- 內(nèi)存優(yōu)化:Agent 僅抓取同步必須的字段,同時會第一時間進(jìn)行壓縮。
- 帶寬優(yōu)化:僅當(dāng) K8s 資源有變化時,Agent 才會向 Server 發(fā)送具體的資源信息
-
同步云資源信息:通過調(diào)用云平臺 API 進(jìn)行資源抽象和轉(zhuǎn)換,然后將相關(guān)標(biāo)簽信息保存至 MySQL 中,并定期更新 ClickHosue 中的字典。
-
同步 Legacy Host 信息:一些環(huán)境中,可能沒有真正意義的云平臺,或者存在一些傳統(tǒng)主機(jī)需要監(jiān)控,這就需要用Legacy Host同步方案。由于沒有具體的云API,我們完全通過Agent抓取所在服務(wù)器的名稱等基本信息和網(wǎng)卡信息,上報(bào)給Server匯總并進(jìn)行資源抽象。
-
同步托管 K8s 信息:當(dāng) K8s 平臺部署在云資源上時,要做到真正的可觀測性,需要將K8s的資源和云資源關(guān)聯(lián)起來,才能真正做到無縫地關(guān)聯(lián)、切分和下鉆。我們一方面通過獲取 K8s 資源所在的 VPC,基于 VPC 內(nèi) IP 的唯一性,通過 VPC + IP 將 K8s 的容器節(jié)點(diǎn)與云服務(wù)器關(guān)聯(lián)起來;另一方面通過將云平臺的 API 調(diào)用與 K8s 獨(dú)立,兩者使用不同的調(diào)用頻率,從而解決大規(guī)模場景下,云平臺 API 慢與 K8s 資源更新快的矛盾。
04、SmartEncoding:實(shí)現(xiàn) 10x 性能提升
SmartEncoding 將標(biāo)簽注入分為3個階段,通過采集時編碼、存儲時編碼、和查詢時編/解碼降低標(biāo)簽寫入的資源消耗,我們來詳細(xì)看看每個階段都如何實(shí)現(xiàn):采集時編碼采集時編碼Controller 根據(jù)云平臺和 K8s 資源抽象好標(biāo)簽信息進(jìn)行 Int 編碼后,并不會將所有的標(biāo)簽下發(fā)給 Agent。僅會下發(fā)最少量的標(biāo)簽。這樣 Agent 只需要為數(shù)據(jù)追加很少的Int標(biāo)簽即可。在混合云場景下,為了標(biāo)識資源我們可以用 VPC ID 作為基,它能和 IP 地址聯(lián)合決定客戶端、服務(wù)端對應(yīng)的實(shí)例和服務(wù);可以通過 gpid 解決遠(yuǎn)端進(jìn)程信息標(biāo)記的問題。我們主要考慮 Agent 做的工作盡量少,這樣可以最大限度的降低采集器的 CPU、內(nèi)存消耗,以及傳輸數(shù)據(jù)的帶寬消耗。我們在生產(chǎn)環(huán)境中發(fā)現(xiàn)有些 K8s 的標(biāo)簽會非常長,key 和 value 高達(dá)上百個字節(jié)。可以想象如果我們將上百個標(biāo)簽注入每個請求傳輸?shù)胶蠖耍牡膸挄浅?捎^。存儲時編碼存儲時編碼同樣 Controller 會向 Ingester 下發(fā) Int 標(biāo)簽,但僅下發(fā)持久化存儲的標(biāo)簽。Ingester 在收到 Agent 發(fā)過來的數(shù)據(jù)后,會進(jìn)行一輪標(biāo)簽的擴(kuò)充,將 Agent 注入的少量標(biāo)簽擴(kuò)展為更為豐富的標(biāo)簽集合。但這里注意的是,我們并不存儲自定義標(biāo)簽。標(biāo)簽的存儲是為了方便檢索和聚合,我們只需要保證每個切分粒度上都有標(biāo)簽存在即可。舉例來講我們存儲 Region、AZ、VM、Node、Namespace、Service、POD 等固定的云或者 K8s 資源標(biāo)簽即可,而其他的自定義的標(biāo)簽一般是依附在這些標(biāo)簽之上的,存在一定的對應(yīng)的關(guān)系。另外,自定義標(biāo)簽動態(tài)性高,也不適合全部存儲。根據(jù)我們的經(jīng)驗(yàn),一般每一個請求涉及到的的固定標(biāo)簽在40個左右,自定義標(biāo)簽在60個左右。通過只存儲固定的資源標(biāo)簽,我們能將壓力進(jìn)一步降低。查詢時編/解碼查詢時編解碼DeepFlow SQL支持通過字符串查詢和聚合,并且也支持自定義標(biāo)簽的查詢和聚合。這里我們依賴 ClickHouse 的字典能力。通過編碼自定義標(biāo)簽的 Filter 和 Group 查詢請求,利用 ClickHouse 的字典轉(zhuǎn)換為系統(tǒng)標(biāo)簽;同時對于 Select 請求也可以利用 ClickHouse 的字典將系統(tǒng)標(biāo)簽轉(zhuǎn)為字符串或者自定義標(biāo)簽返回。我們再來回顧一下這三級編解碼,可以發(fā)現(xiàn)它能為我們節(jié)省大量的資源消耗,性能提升應(yīng)該十分可觀。一方面采集器的CPU、內(nèi)存可以降低,傳輸帶寬可以降低,最主要的還是后端存儲開銷的降低。我們在談?wù)摽捎^測性時經(jīng)常會談到采樣、避免高基數(shù)等。ClickHouse 采用稀疏索引,很好的避免了高基數(shù)問題。我們在此之上的多級編解碼又能將存儲開銷顯著降低,而且由于查詢階段掃描的數(shù)據(jù)量變小了,所以能獲得更好的查詢性能。這里有一些數(shù)據(jù)可以看一下,DeepFlow 默認(rèn)使用 ClickHouse 存儲數(shù)據(jù),在 SmartEncoding 的加持下,標(biāo)準(zhǔn) Tag 的 CPU 和磁盤消耗相比 LowCard 存儲或直接存儲有一個數(shù)量級的優(yōu)化,而由于自定義 Tag 不會隨數(shù)據(jù)寫入,在通常的場景下整體寫入資源消耗可降低50倍。做了這么復(fù)雜的編碼以后,如何讓查詢變得簡單呢?下面我們來介紹 deepflow-server 的查詢抽象層,它向用戶隱藏了寫時編碼和讀時關(guān)聯(lián)的復(fù)雜邏輯,用戶對數(shù)據(jù)的查詢就像在一張大寬表上進(jìn)行,體驗(yàn)非常絲滑。例如,我們可以直接查詢所有表中的數(shù)據(jù):
SELECTcol_1,col_2,col_3 FROMtbl_1 WHEREcol_4=y GROUPBYcol_1,col_2 HAVINGcol_5>100 ORDERBYcol_3 LIMIT100 ``` 我們可以查詢某個 Tag 的所有候選項(xiàng): ```sql SHOWtag${tag_name}valuesFROM${table_name}
SHOWtag${tag_name}values FROM${table_name} WHEREdisplay_nameLIKE'*abc*'
SELECTpod FROM`vtap_flow_port.1m` WHEREpod_cluster='cluster1' GROUPBYpod 更多詳細(xì)用法[4]查詢 Universal Tag
- ClickHouse 的觀測數(shù)據(jù)表中保存tag ID
CREATETABLEflow_metrics.`vtap_flow_port.1m` ( `time`DateTime('Asia/Shanghai')COMMENT'v6.1.8'CODEC(DoubleDelta), `ip4`IPv4COMMENT'IPv4地址', `ip6`IPv6COMMENT'IPV6地址', `is_ipv4`UInt8COMMENT'是否IPV4地址.0:否,ip6字段有效,1:是,ip4字段有效', `l3_device_id`UInt32COMMENT'ip對應(yīng)的資源ID', `l3_device_type`UInt8COMMENT'ip對應(yīng)的資源類型', `l3_epc_id`Int32COMMENT'ip對應(yīng)的EPCID', `pod_cluster_id`UInt16COMMENT'ip對應(yīng)的容器集群ID', `pod_group_id`UInt32COMMENT'ip對應(yīng)的容器工作負(fù)載ID', `pod_id`UInt32COMMENT'ip對應(yīng)的容器PODID', `pod_node_id`UInt32COMMENT'ip對應(yīng)的容器節(jié)點(diǎn)ID', `pod_ns_id`UInt16COMMENT'ip對應(yīng)的容器命名空間ID' ) ENGINE=Distributed(...)
- ClickHouse 的字典表中保存tag ID和名稱對應(yīng)關(guān)系
CREATEDICTIONARYflow_tag.pod_map ( `id`UInt64, `name`String, `icon_id`Int64 ) PRIMARYKEYid SOURCE(...)
- 通過 dictGet 實(shí)現(xiàn)tag ID到名稱的轉(zhuǎn)換
SELECTdictGet(flow_tag.pod_map,'name',toUInt64(pod_id))ASpod FROM`vtap_flow_port.1m` WHEREpod='deepflow' GROUPBYpod LIMIT1 查詢 K8s label
- ClickHouse 的字典表中保存tag ID和 K8s label對應(yīng)關(guān)系
CREATEDICTIONARYflow_tag.k8s_label_map ( `pod_id`UInt64, `key`String, `value`String, ) PRIMARYKEYpod_id,key SOURCE(...) LIFETIME(MIN0MAX60) LAYOUT(COMPLEX_KEY_HASHED())
- 通過 dictGet 實(shí)現(xiàn)tag ID到 K8s label 的轉(zhuǎn)換
SELECTdictGet(flow_tag.k8s_label_map,'value',(toUInt64(pod_id),'app'))AS`label.app` FROM`vtap_flow_port.1m` WHERE`label.app`='xxx' LIMIT1 查詢集成數(shù)據(jù),包括 Prometheus、Telegraf、OpenTelemetry 等數(shù)據(jù)。
- 存儲集成數(shù)據(jù)時,會將數(shù)據(jù)中原有的 Tag 和 Metric 的 name 和 value 分別定義為 Array 類型,一一對應(yīng)。
CREATETABLEext_metrics.prometheus_web ( `time`DateTime('Asia/Shanghai')CODEC(DoubleDelta), `_tid`UInt8COMMENT'用于區(qū)分trident不同的pipeline', `az_id`UInt16COMMENT'可用區(qū)ID', `host_id`UInt16COMMENT'宿主機(jī)ID', `tag_names`Array(String)COMMENT'額外的tag', `tag_values`Array(String)COMMENT'額外的tag對應(yīng)的值', `metrics_float_names`Array(String)COMMENT'額外的metrics', `metrics_float_values`Array(Float64)COMMENT'額外的metrics值' )
- Tag 候選項(xiàng)只需要保留不重復(fù)的值,所以我們使用 ReplacingMergeTree Engine
CREATETABLEflow_tag.ext_metrics_custom_field_local ( `time`DateTime('Asia/Shanghai')CODEC(DoubleDelta), `table`LowCardinality(String), `vpc_id`Int32, `pod_ns_id`UInt16, `field_type`LowCardinality(String)COMMENT'value:tag,metrics', `field_name`LowCardinality(String), `field_value_type`LowCardinality(String)COMMENT'value:string,float' ) ENGINE=ReplacingMergeTree(time)
- 通過 indexOf 進(jìn)行 name 和 value 的對應(yīng)
SELECTtag_values[indexOf(tag_names,'host')]AS`tag.host` FROMdeepflow_agent_collect_sender WHERE(tag_values[indexOf(tag_names,'host')])='xxxx' LIMIT1
05、總結(jié)與后續(xù)迭代計(jì)劃
通過以上分享,相信您會發(fā)現(xiàn)DeepFlow有豐富、統(tǒng)一的標(biāo)準(zhǔn)化標(biāo)簽體系,非常方便進(jìn)行數(shù)據(jù)關(guān)聯(lián)、切分、下鉆。通過 SmartEncoding 的性能優(yōu)化,Server + ClickHouse 的資源消耗通常為業(yè)務(wù)消耗的 1%,即監(jiān)控100個 16c64g 的容器節(jié)點(diǎn),大概需要1個 16c64g 的 Node 部署 Server + ClickHouse,且可以通過對象存儲轉(zhuǎn)儲冷數(shù)據(jù);而且常見的可觀測性數(shù)據(jù)一般都需要注入百量級的標(biāo)簽,DeepFlow Agent 由于只注入了 VPC、GPID 少數(shù)幾個字段,因此它用于標(biāo)簽注入的資源消耗幾乎只有其他方案的百分之幾。這樣10x性能的使用體驗(yàn),相信 Cloud-Native、NewOps 都會喜歡!后續(xù)我們會支持更豐富的自定義標(biāo)簽,包括通過 K8s API 獲取的k8s.annotation 和 k8s.env、通過操作系統(tǒng)獲取的 os.proc 信息、通過執(zhí)行命令獲取 os.app 信息;會從時間和帶寬消耗兩方面進(jìn)一步優(yōu)化AutoTagging的性能,通過不同類型資源的 API 可以設(shè)置不同的調(diào)用頻率,避免每次都是重新獲取全部資源來縮短縮短大規(guī)模下的資源同步時間;通過Agent 僅發(fā)送有變化的 K8s 資源信息,進(jìn)一步降低帶寬消耗。06、關(guān)于DeepFlow
DeepFlow[5]是一款開源的高度自動化的可觀測性平臺,是為云原生應(yīng)用開發(fā)者建設(shè)可觀測性能力而量身打造的全棧、全鏈路、高性能數(shù)據(jù)引擎。DeepFlow 使用 eBPF、WASM、OpenTelemetry 等新技術(shù),創(chuàng)新的實(shí)現(xiàn)了 AutoTracing、AutoMetrics、AutoTagging、SmartEncoding 等核心機(jī)制,幫助開發(fā)者提升埋點(diǎn)插碼的自動化水平,降低可觀測性平臺的運(yùn)維復(fù)雜度。利用 DeepFlow 的可編程能力和開放接口,開發(fā)者可以快速將其融入到自己的可觀測性技術(shù)棧中。 審核編輯 :李倩
-
核心技術(shù)
+關(guān)注
關(guān)注
4文章
625瀏覽量
19607 -
數(shù)據(jù)存儲
+關(guān)注
關(guān)注
5文章
971瀏覽量
50909 -
軟件架構(gòu)
+關(guān)注
關(guān)注
0文章
64瀏覽量
10288
原文標(biāo)題:DeepFlow AutoTagging 10x性能提升實(shí)戰(zhàn)
文章出處:【微信號:AI_Architect,微信公眾號:智能計(jì)算芯世界】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論