穩撐30+PB數據,攜程10年日誌系統治理演進之路

来源:https://www.cnblogs.com/88223100/archive/2023/03/08/The-evolution-of-Ctrip-10-year-log-system-governance.html
-Advertisement-
Play Games

本文將從以下五部分切入,講述日誌系統的演進之路:攜程日誌的背景和現狀、如何搭建一套日誌系統、從 ElasticSearch 到 Clickhouse 存儲演進、日誌3.0重構及未來計劃。 ...


本文將從以下五部分切入,講述日誌系統的演進之路:攜程日誌的背景和現狀、如何搭建一套日誌系統、從 ElasticSearch 到 Clickhouse 存儲演進、日誌3.0重構及未來計劃。

 

一、日誌背景及現狀

 

圖片

圖1

 

2012年以前,攜程的各個部門日誌自行收集治理(如圖1)。這樣的方式缺乏統一標準,不便治理管控,也更加消耗人力和物力。

 

從2012年開始,攜程技術中心推出基於 ElasticSearch 的日誌系統,統一了日誌的接入、ETL、存儲和查詢標準。隨著業務量的增長,數據量膨脹到 4PB 級別,給原來的 ElasticSearch 存儲方案帶來不少挑戰,如 OOM、數據延遲及負載不均等。此外,隨著集群規模的擴大,成本問題日趨敏感,如何節省成本也成為一個新的難題。

 

2020年初,我們提出用 Clickhouse 作為主要存儲引擎來替換 ElasticSearch 的方案,該方案極大地解決了 ElasticSearch 集群遇到的性能問題,並且將成本節省為原來的48%。2021年底,日誌平臺已經累積了20+PB 的數據量,集群也達到了數十個規模(如圖2)。

 

2022年開始,我們提出日誌統一戰略,將公司的 CLOG 及 UBT 業務統一到這套日誌系統,預期數據規模將達到 30+PB。同時,經過兩年多的大規模應用,日誌集群累積了各種各樣的運維難題,如集群數量激增、數據遷移不便及表變更異常等。因此,日誌3.0應運而生。該方案落地了類分庫分表設計、Clickhouse on Kubernetes、統一查詢治理層等,聚焦解決了架構和運維上的難題,並實現了攜程 CLOG 與 ESLOG 日誌平臺統一。

 

圖片

圖2

 

二、如何搭建日誌系統

 

2.1 架構圖

 

從架構圖來看(如圖3),整個日誌系統可以分為:數據接入、數據 ETL、數據存儲、數據查詢展示、元數據管理系統和集群管理系統。

 

圖片

圖3

 

2.2 數據接入

 

數據接入主要有兩種方式:

 

第一種是使用公司框架 TripLog 接入到消息中間件 Kafka(Hermes協議)(如圖4)。

 

圖片

圖4

 

第二種是用戶使用 Filebeat/Logagent/Logstash 或者寫程式自行上報數據到 Kafka(如圖5),再通過 GoHangout 寫入到存儲引擎中。

 

圖片

圖5

 

2.3  數據傳輸ETL(GoHangout)

 

GoHangout 是仿照 Logstash 做的一個開源應用(Github鏈接),用於把數據從 Kafka 消費併進行 ETL,最終輸出到不同的存儲介質(Clickhouse、ElasticSearch)。其中數據處理 Filter 模塊包含了常見的 Json 處理、Grok 正則匹配和時間轉換等一系列的數據清理功能(如圖6)。GoHangout 會將數據 Message 欄位中的 num 數據用正則匹配的方式提取成單獨欄位。

 

圖片

圖6

 

2.4 ElasticSearch 數據存儲

 

早期2012年第一版,我們使用 ElasticSearch 作為存儲引擎。ElasticSearch 存儲主要由 Master Node、Coordinator Node、Data Node 組成(如圖7)。Master 節點主要負責創建或刪除索引,跟蹤哪些節點是集群的一部分,並決定哪些分片分配給相關的節點;Coordinator 節點主要用於處理請求,負責路由請求到正確的節點,如創建索引的請求需要路由到 Master 節點;Data 節點主要用於存儲大量的索引數據,併進行增刪改查,一般對機器的配置要求比較高。

 

圖片

圖7

 

2.5  數據展示

 

數據展示方面我們使用了 Elastic Stack 家族的 Kibana(如圖8)。Kibana 是一款適合於 ElasticSearch 的數據可視化和管理工具,提供實時的直方圖、線形圖、餅狀圖和表格等,極大地方便日誌數據的展示。

 

圖片

圖8

 

2.6  表元數據管理平臺

 

表元數據管理平臺是用戶接入日誌系統的入口,我們將每個 Index/ Table 都定義為一個Scenario(如圖9)。我們通過平臺配置並管理 Scenario 的一些基礎信息,如:TTL、歸屬、許可權、ETL 規則和監控日誌等。

 

圖片

圖9

 

三、  從Elasticsearch到Clickhouse

 

我們將會從背景、Clickhouse 簡介、ElasticSearch 對比和解決方案四方面介紹日誌從 ElasticSearch 到 Clickhouse 的演進過程。2020年初,隨著業務量的增長,給 ElasticSearch 集群帶來了不少難題,主要體現在穩定性、性能和成本三個方面。

 

(1)穩定性上:

 

ElasticSearch 集群負載高,導致較多的請求 Reject、寫入延遲和慢查詢。

每天 200TB 的數據從熱節點搬遷到冷節點,也有不少的性能損耗。

節點間負載不均衡,部分節點單負載過高,影響集群穩定性。

大查詢導致 ElasticSearch 節點 OOM。

 

(2)性能上:

 

ElasticSearch的吞吐量也達到瓶頸。

查詢速度受到整體集群的負載影響。

 

(3)成本上:

 

倒排索引導致數據壓縮率不高。

大文本場景性價比低,無法保存長時間數據。

 

3.1 Clickhouse 簡介與 Elasticsearch 對比

 

Clickhouse 是一個用於聯機分析(OLAP)的列式資料庫管理系統(DBMS)。Yandex 在2016年開源,使用 C++ 語法開發,是一款PB級別的互動式分析資料庫。包含了以下主要特效:列式存儲、Vector、Code Generation、分散式、DBMS、實時OLAP、高壓縮率、高吞吐、豐富的分析函數和 Shared Nothin g架構等。

 

圖片

圖10

 

Clickhouse採用的是 SQL 的交互方式,非常方便上手。接下來,我們將簡單介紹一下 Clickhouse 的類 LSM、排序鍵、分區鍵特效,瞭解 Clickhouse 的主要原理。

 

首先,用戶每批寫入的數據會根據其排序鍵進行排序,並寫入一個新的文件夾(如201905_1_1_0),我們稱為 Part C0(如圖10)。隨後,Clickhouse 會定期在後臺將這些 Part 通過歸併排序的方式進行合併排序,使得最終數據生成一個個數據順序且空間占用較大的 Part。這樣的方式從磁碟讀寫層面上看,能充分地把原先磁碟的隨機讀寫巧妙地轉化為順序讀寫,大大提升系統的吞吐量和查詢效率,同時列式存儲+順序數據的存儲方式也為數據壓縮率提供了便利。201905_1_1_0與201905_3_3_0合併為201905_1_3_1就是一個經典的例子。

 

另外,Clickhouse 會根據分區鍵(如按月分區)對數據進行按月分區。05、06月的數據被分為了不同的文件夾,方便快速索引和管理數據。

 

圖片

圖11

 

我們看中了 Clickhouse 的列式存儲、向量化、高壓縮率和高吞吐等特效(如圖11),很好地滿足了我們當下日誌集群對性能穩定性和成本的訴求。於是,我們決定用Clickhouse來替代原本 ElasticSearch 存儲引擎的位置。

 

3.2 解決方案

 

有了存儲引擎後,我們需要實現對用戶無感知的存儲遷移。這主要涉及了以下的工作內容(如圖12):自動化建表、GoHangout 修改、Clickhouse 架構設計部署和 Kibana 改造。

 

圖片

圖12

 

(1)庫表設計

 

圖片

圖13

 

我們對ck在日誌場景落地做了很多細節的優化(如圖13),主要體現在庫表設計:

 

我們採用雙 list 的方式來存儲動態變化的 tags(當然最新的版本22.8,也可以用map和新特性的 json 方式)。

按天分區和時間排序,用於快速定位日誌數據。

Tokenbf_v1 布隆過濾用於優化 term 查詢、模糊查詢。

_log_increment_id 全局唯一遞增 id,用於滾動翻頁和明細數據定位。

ZSTD 的數據壓縮方式,節省了40%以上的存儲成本。

 

(2)Clickhouse 存儲設計

 

Clickhouse 集群主要由查詢集群、多個數據集群和 Zookeeper 集群組成(如圖14)。查詢集群由相互獨立的節點組成,節點不存儲數據是無狀態的。數據集群則由Shard組成,每個 Shard 又涵蓋了多個副本 Replica。副本之間是主主的關係(不同於常見的主從關係),兩個副本都可以用於數據寫入,互相同步數據。而副本之間的元數據一致性則有 Zookeeper 集群負責管理。

 

 

圖片

圖14

 

(3)數據展示

 

為了實現用戶無感知的存儲切換,我們專門實現了 Kibana 對 Clickhouse 數據源的適配並開發了不同的數據 panel(如圖15),包括:chhistogram、chhits、chpercentiles、chranges、chstats、chtable、chterms 和 chuniq。通過 Dashboard 腳本批量生產替代的方式,我們快速地實現了原先 ElasticSearch 的 Dashboard 的遷移,其自動化程度達到95%。同時,我們也支持了使用 Grafana 的方式直接配置 SQL 來生成日誌看板。

 

圖片

圖片

圖片

圖15

 

(4)集群管理平臺

 

為了更好地管理 Clickhouse 集群,我們也做了一整套界面化的 Clickhouse 運維管理平臺。該平臺覆蓋了日常的 shard 管理、節點生成、綁定/解綁、權重修改、DDL 管理和監控告警等治理工具(如圖16)。

 

圖片

圖16

 

3.3 成果

 

遷移過程自動化程度超過95%,基本實現對用戶透明。

存儲空間節約50+%(如圖17),用原有ElasticSearch的伺服器支撐了4倍業務量的增長。

 

查詢速度比ElasticSearch快4~30倍,查詢P90小於300ms,P99小於1.5s。

  

圖片

圖17

 

四、日誌3.0構建

 

時間來到2022年,公司日誌規模再進一步增加到 20+PB。同時,我們提出日誌統一戰略,將公司的 CLOG 及 UBT 業務統一到這套日誌系統,預期數據規模將達到 30+PB。另外,經過兩年多的大規模應用,日誌系統也面臨了各種各樣的運維難題。

 

(1)  性能與功能痛點

 

單集群規模太大,Zookeeper 性能達到瓶頸,導致 DDL 超時異常。

當表數據規模較大時,刪除欄位,容易超時導致元數據不一致。

用戶索引設置不佳導致查詢慢時,重建排序鍵需要刪除歷史數據,重新建表。

查詢層缺少限流、防呆和自動優化等功能,導致查詢不穩定。

 

(2)  運維痛點

 

表與集群嚴格綁定,集群磁碟滿後,只能通過雙寫遷移。

集群搭建依賴 Ansible,部署周期長(數小時)。

Clickhouse 版本與社區版本脫節,目前集群的部署模式不便版本更新。

 

面對這樣的難題,我們在2022年推出了日誌3.0改造,落地了集群 Clickhouse on Kubernetes、類分庫分表設計和統一查詢治理層等方案,聚焦解決了架構和運維上的難題。最終,實現了統一攜程 CLOG 與 ESLOG 兩套日誌系統。

 

4.1  ck on k8s

 

我們使用 Statefulset、反親和、Configmap 等技術實現了 Clickhouse 和 Zookeeper 集群的 Kubernetes 化部署,使得單集群交付時間從2天優化到5分鐘。同時,我們統一了部署架構,將海內外多環境部署流程標準化。這種方式顯著地降低了運維成本並釋放人力。更便利的部署方式有益於單個大集群的切割,我們將大集群劃分為多個小集群,解決了單集群規模過大導致 Zookeeper 性能瓶頸的問題。

 

4.2 類分庫分表設計

 

圖片

圖18

 

(1)數據跨如何跨集群

 

假設我們有三個數據集群1、2、3和三個表A、B、C(如圖18)。在改造之前,我們單張表(如A)只能坐落在一個數據集群1中。這樣的設計方式,導致了當集群1磁碟滿了之後,我們沒有辦法快速地將表A數據搬遷到磁碟相對空閑的集群2中。我們只能用雙寫的方式將表A同時寫入到集群1和集群2中,等到集群2的數據經過了TTL時間(如7天)後,才能將表A從數據集群1中刪除。這樣,對我們的集群運維管理帶來了極大的不方便和慢響應,非常耗費人力。

 

於是,我們設計一套類分庫分表的架構,來實現表A在多個集群1、2、3之間來回穿梭。我們可以看到右邊改造後,表A以時間節點作為分庫分表的切換點(這個時間可以是精確到秒,為了好理解,我們這裡以月來舉例)。我們將6月份的數據寫入到集群1、7月寫到集群2、8月寫到集群3。當查詢語句命中6月份數據時,我們只查詢集群1的數據;當查詢語句命中7月和8月的數據,我們就同時查詢集群2和集群3的數據。

 

我們通過建立不同分散式表的方式實現了這個能力(如:分散式表tableA_06/tableA_07/tableA_08/tableA_0708,分散式表上的邏輯集群則是是集群1、2、3的組合)。這樣,我們便解決了表跨集群的問題,不同集群間的磁碟使用率也會趨於平衡。

 

(2)如何修改排序鍵不刪除歷史數據

 

非常巧妙的是,這種方式不僅能解決磁碟問題。Clickhouse 分散式表的設計只關心列的名稱,並不關心本地數據表的排序鍵設置。基於這種特性,我們設計表A在集群2和集群3使用不一樣的排序鍵。這樣的方式也能夠有效解決初期表A在集群2排序鍵設計不合理的問題。我們通過在集群3上重新建立正確的排序鍵,讓其對新數據生效。同時,表A也保留了舊的7月份數據。舊數據會在時間的推移一下被TTL清除,最終數據都使用了正確的排序鍵。

 

(3)如何解決刪除大表欄位導致元數據不一致

 

更美妙的是,Clickhouse 的分散式表設計並不要求表A在7月和8月的元數據欄位完全一致,只需要有公共部分就可以滿足要求。比如表A有在7月有11個欄位,8月份想要刪除一個棄用的欄位,那麼只需在集群3上建10個欄位的本地表A,而分散式表 tableA_0708 配置兩個表共同擁有的10個欄位即可(這樣查分散式表只要不查被刪除的欄位就不會報錯)。通過這種方式,我們也巧妙地解決了在數據規模特別大的情況下(單表百TB),刪除欄位導致常見的元數據不一致問題。

 

(4)集群升級

 

同時,這種多版本集群的方式,也能方便地實現集群升級迭代,如直接新建一個集群4來存儲所有的09月的表數據。集群4可以是社區最新版本,通過這種迭代的方式逐步實現全部集群的升級。

 

4.3 元數據管理

 

為了實現上述的功能,我們需要維護好一套完整的元數據信息,來管理表的創建、寫入和 DDL(如圖19)。該元數據包含每個表的版本定義、每個版本數據的數據歸屬集群和時間範圍等。

 

圖片

圖19

 

4.4  統一查詢治理層

 

(1)Antlr4 的 SQL 解析

 

在查詢層,我們基於 Antlr4 技術,將用戶的查詢 SQL 解析成 AST 樹。通過 AST 樹,我們能夠快速地獲得 SQL 的表名、過濾條件、聚合維度等(如圖20)。我們拿到這些信息後,能夠非常方便地對 SQL 實時針對性的策略,如:數據統計、優化改寫和治理限流等。

 

圖片

圖20

 

(2)查詢代理層

 

圖片

圖21

 

我們對所有用戶的SQL查詢做了一層統一的查詢網關代理(如圖21)。該程式會根據元數據信息和策略對用戶的 SQL 進行改寫,實現了精準路由和性能優化等功能。同時,該程式會記錄每次查詢的明細上下文,用於對集群的查詢做統一化治理,如:QPS 限制、大表掃描限制和時間限制等拒絕策略,來提高系統的穩定性。

 

五、未來計劃

 

通過日誌3.0的構建,我們重構了日誌系統的整體架構,實現集群 Kubernetes 化管理,併成功地解決了歷史遺留的 DDL 異常、數據跨集群讀寫、索引重構優、磁碟治理和集群升級等運維難題。2022年,日誌系統成果地支撐了公司 CLOG 與 UBT 業務的數據接入,集群數據規模達到了30+PB。

 

當然,攜程的日誌系統演進也不會到此為止,我們的系統在功能、性能和治理多方面還有不少改善的空間。在未來,我們將進一步完善日誌統一查詢治理層,精細化地管理集群查詢與負載;推出日誌預聚合功能,對大數據量的查詢場景做加速,並支持 AI智能告警;充分地運用雲上能力,實現彈性混合雲,低成本支撐節假日高峰;推到日誌產品在攜程系各個公司的使用覆蓋等。讓我們一起期待下一次的日誌升級。

 

作者丨 Dongyu

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/The-evolution-of-Ctrip-10-year-log-system-governance.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 說實話在寫這篇文章的時候,鹹魚不禁又想起了那件男默女淚的往事 我喜歡做筆記,我覺得好記性不如爛筆頭,所以在我的學生以及職業生涯階段,我用過四款筆記應用——Onenote、語雀、印象筆記、Typora 其中我個人覺得體驗最好的非 Typora 莫屬了 ​ 在 2022 年的時候,由於 Typor ...
  • 系統增強工具PowerToys 下載地址:https://github.com/microsoft/PowerToys 什麼是 Windows 系統中,最好的輔助工具? PowerToys 一定可以獲得提名。PowerToys 是一款來自微軟的系統增強工具,就像是一個神奇的系統外掛,整套軟體由若幹子 ...
  • 通用表表達式 通用表表達式(Common Table Expression、CTE)是一個臨時的查詢結果或者臨時表,可以 在其他 SELECT、INSERT、UPDATE 以及 DELETE 語句中使用。通用表表達式只在當前語句中 有效,類似於子查詢。 使用 CTE 的主要好處包括: 提高複雜查詢的 ...
  • 一、Redis簡介 Redis全稱為 Remote Dictionary Server(遠程詞典服務),開源(BSD許可)的,使用 C 語言開發的。 Redis是記憶體中的數據結構存儲系統,它可以用作資料庫、緩存和消息中間件。 支持多種類型的數據結構,如 字元串(strings), 散列(hashes ...
  • MySQL查看資料庫性能常用命令 # 列出MySQL伺服器運行各種狀態值 show global status; # 查詢MySQL伺服器配置信息語句 show variables; # 慢查詢 show variables like '%slow%'; # MySQL伺服器最大連接數 show v ...
  • 摘要:Bucket存儲是數據共用中重要的一環,當前階段,bucket存儲可以將列存中的CU數據和DN節點解綁。 本文分享自華為雲社區《存算分離之bucket表——【玩轉PB級數倉GaussDB(DWS)】》,作者:yd_278301229 。 在雲原生環境,用戶可以自由配置cup型號、記憶體、磁碟、帶 ...
  • 《高性能MySQL》第四版發佈後,收到了很多讀者的反饋,其中關註最多的是作為一個初學者,應該如何能夠較為系統的學習MySQL,從而應對日常工作或者獲得更好的職業發展。於是和多個業內朋友討論後,整理了一些MySQL學習的推薦資源,供初學者參考。 本文分成幾部分,包括業界專家的經驗、推薦書籍、視頻/音頻 ...
  • 摘要: Gaussdb的HA採用主備從的架構實現數據可靠性。當主DN發生故障時,備DN走failover流程,升級成為新主DN,保證集群不因單DN故障而中斷業務。 本文分享自華為雲社區《【玩轉PB級數倉GaussDB(DWS)】dws高可用之failover流程大解密》,作者:fxy0224。 眾所 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...