成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

日志系統成本飆升千萬,嚇得我趕緊把ES換成ClickHouse……

系統 運維
隨著公司的業務發展,日志應用場景逐漸遇到了一些瓶頸。

?一、背景

唯品會日志系統dragonfly 1.0是基于EFK構建,于2014年服務至今已長達7年,支持物理機日志采集,容器日志采集,特殊分類日志綜合采集等,大大方便了全公司日志的存儲和查詢。

隨著公司的業務發展,日志應用場景逐漸遇到了一些瓶頸,主要表現在應用數量和打印的日志越來越多,開發需要打印更多日志,定位業務問題,做出運營數據分析;另外外部攻擊問題和審計要求,需要更多安全相關的日志數據要上報并且能夠提供半年以上的保存時長,以應對潛在的攻擊和攻擊發生時調查原因和受影響面。ELK的架構的缺點顯現,ES集群規模達260臺機器,需要的硬件和維護成本高達千萬,如果通過擴容的方法去滿足上述業務場景,ES集群會太大會變動不穩定,創建獨立集群,也需要更高成本,兩者都會使得成本和維護工作量劇增。

鑒于這些問題,去年六月份我們開始探索新的日志系統架構,以徹底解決上面的問題。

二、日志系統演進之路

1、標準日志格式

規范標準日志格式,有利于正確的識別出日志關鍵元信息,以滿足查詢,告警和聚合計算的需求。從以上格式日志,通過filebeat轉換后的結果如下:

時間戳,日志級別,線程名,類名,eventName,和自定義字段將被日志采集Agent解析后和其他元數據如域名,容器名或主機名一起以JSON格式上報。

自定義字段是開發人員根據業務需要打印到日志,主要支持功能:

  • 查詢時支持各種聚合分析場景.

  • 根據自定義字段進行聚合函數告警。

2、ES存儲方案問題

1)ES日志存儲模型

EFK日志存儲在elasticsearch,每個域的日志以天粒度在ES創建一個索引,索引大小是根據前幾日數據大小計算得出,每個索引分片大小不超過30G,日志量越多的域分片越多。如果一個域的日志量寫入過大或超長,將會占用ES節點大量CPU來做解析和segment合并,這會影響其他域日志的正常寫入,導致整體寫入吞吐下降。

排查是哪個域的哪個分片日志過大通常較為困難,在面對這種熱點問題時經常要花很長時間。我們ES版本使用的是5.5,還不支持索引自動刪除和冷熱遷移,有幾個腳本每日定時執行,完成刪除索引,關閉索引,移動冷索引,創建新索引的任務,其中移動索引和創建新索引都是耗時非常長的操作。

整個生命周期每天循環執行,如果突然一天某個步驟執行失敗,或者執行時間太長,會導致整個生命周期拉長甚至無法完成,第二天的新數據寫入將受到嚴重影響,甚至無法寫入。另外ES的倒排索引需要對日志進行分詞,產生的索引文件較大,占用了大量磁盤空間。

不過ES也有其優點,基于倒排索引的特性使得ES查詢時,1個分片只需要一個核即可完成查詢,因為查詢速度通常較快,QPS較高。下面是在大規模(或海量)日志存儲場景下ES的主要存儲優點和缺點:

3、日志系統2.0方案

1)選擇clickhouse的原因

2019年我們嘗試了另外一種HDFS存儲方案,把每個域的數據按照域名+toYYDDMMHH(timestamp)+host作為鍵在客戶端緩存,當大小或過期時間到了之后,提交到HDFS生成一個獨立的文件,存儲路徑包含了域,主機和時間信息,搜索時即可根據這幾個標簽過濾,這種存儲方式有點類似loki,它的缺點顯而易見,優點是吞吐和壓縮率都非常高,可以解決我們吞吐和壓縮率不足的問題。

如果基于此方案繼續增強功能,如添加標簽,簡單的跳數索引,查詢函數,多節點并發查詢,多字段存儲,需要開發的工作量和難度都非常大。我們對比了業界前沿使用的一些存儲方案,最終選擇了clickhouse,他的批量寫入和列式存儲方案完全滿足我們的要求(基于HDFS存儲),另外還提供了占用磁盤空間非常小的主鍵索引和跳數索引,相比ES的全文索引,優勢明顯。

將近26G的應用日志分別使用clickhouse的lz4,zstd和ES的lz4壓縮算法對比:

實際生產環境中zstd的日志壓縮比更高,這和應用日志的相似度有關,最大達到15.8。

Clickhouse壓縮率這么高,但沒有索引,其查詢速度如何?雖然沒有索引,但其向量執行和SIMD配合多核CPU,可以大大緩解沒有全文索引的缺點。經過多次測試對比后,其查詢速度在絕大多數場景下和ES不相上下,在部分場景下甚至比ES還要快。

下圖是實際生產環境的數千個應用真實運行數據,查詢24小時時間范圍內日志和24小時以上時間范圍日志的耗時對比。

通過對日志的應用場景分析,我們發現萬億級別的日志,真正能被查詢的日志數量是非常非常少的,這意味著ES對所有日志的分詞索引,大多數是無效的,日志越多,這個分詞消耗的資源越浪費。相對比clickhouse的MergeTree引擎專一的多,主要資源消耗是日志排序壓縮和存儲。

另外Clickhouse的MPP架構使得集群非常穩定,幾乎不要太多運維工作。下面以一幅圖綜合對比ES和Clickhouse的優缺點,說明為什么我們選擇將clickhouse作為下一代日志存儲數據庫。

三、技術詳解

EFK架構發展這么多年體系要成熟得多,ES默認參數和倒排索引使得你不需要對ES有太多了解即可輕松使用,開源kibana又提供豐富的查詢界面和圖形面板,對于日志量不大的場景來講,EFK架構仍然是首選。Clickhouse是近幾年OLAP領域比較熱門的數據庫,其成熟度和生態仍在快速發展中,用來存儲日志的開源方案不是很多,要用好它不但需要對Clickhouse有深入的了解,還需要做很多開發工作。

1、日志攝入 - vfilebeat

起初dragonfly使用logstash來做日志采集,但logstash的配置較復雜并且無法支持配置文件下發,不便于容器環境下的日志采集,當時另一個使用GO語言開發的采集工具vfilebeat在性能和擴展性方面較好,我們在此基礎上做了定制開發自己的日志采集組件vfilebeat。

vfilebeat運行在宿主機上,啟動時可以通過參數指定采集的宿主機日志所屬的域,如果沒有指定,則讀取安裝時CMDB配置文件的域名和主機名,宿主機采集的每條日志均帶上域名和主機名作為標簽。

容器環境下vfilebeat還會監聽容器的創建和銷毀,當容器創建時,讀取容器的POD信息獲取到域名和主機名,然后從ETCD拉取到域的日志采集路徑等配置參數,按照域名和POD名稱生成容器所屬目錄的日志文件采集路徑,并在本地生成新的配置文件,vfilebeat重新加載配置文件,即可滾動采集。

現在我們環境絕大部分應用均使用vfilebeat采集,少部分場景保留使用logstash采集。vfilebeat將采集到的日志附帶上應用和系統環境等標簽,序列化配置的數據格式,上報到kafka集群,應用日志是JSON,Accesslog為文本行。

2、日志解析 - flink writer

采集到kafka的日志將被一個flink writer任務實施消費后再寫入到clickhouse集群。

writer把從kafka消費的數據先轉換為結構化數據,vfilebeat上報的時候可能會上報一些日期較久的數據,太久的數據,報上來意義不大,并且會導致產生比較多的小part,消耗clickhosue cpu資源,這一步把這些過期超過三天的日期丟掉,無法解析的數據或者缺少必須字段的日志也會丟掉。經解析過濾后的數據再經過轉換步驟,轉換為clickhouse的表字段和類型。

轉換操作從schema和metadata表讀取域日志存儲的元信息,schema定義了clickhouse本地表和全局表名,字段信息,以及默認的日志字段和表字段的映射關系。metadata定義了域日志具體使用的schema信息,日志存儲的時長,域分區字段值,域自定義字段映射到的表字段,通過這些域級別的配置信息,我們做到可以指定域存儲的表,存儲的時長,超大日志域獨立分區存儲,降低日志合并的CPU消耗。自定義字段默認是按照數組存儲,有些域打印的自定義日志字段較多,在日志量大的情況下,速度較慢,配置了自定義映射物理字段存儲,可以提供比數組更快的查詢速度和壓縮率。

1)clickhouse表schema信息

2)域自定義存儲元數據信息

經過轉換后的數據,攜帶了存儲到CK表所需要的所有信息,將臨時存儲在本地的一個隊列內,本地隊列可能混合存儲了多個域多張表的日志,達到指定的長度或時間后,再被提交到一個進程級的全局隊列內。

因為writer進程是多線程消費多個kafka分區,全局隊列將同一個表多個線程的數據合并到一起,使得單次提交的批次更大,全局線程短暫緩沖,當滿足寫入條數,大小或超時后,數據將被作為一次寫入,提交到submit worker線程。submit worker負責數據的寫入,高可用,負載均衡,容錯和重試等邏輯。

submit收到提交的批量數據后,隨機尋找一個可用的clickhosue分片,提交寫入到分片節點。clickhouse集群配置是雙副本,當一個副本節點失敗時,將嘗試切換寫入到另一個節點上,如果兩個都失敗,則暫時剔除分片,重新尋找一個健康的分片寫入。

寫入數據到Clickhouse我們使用的是clickhouse-jdbc,起初寫入時消耗內存和CPU都較大,對jdbc源碼進行分析后,我們發現jdbc寫入數據時,先把所有數據轉換成一個List對象,這個list對象相當于提交數據的byte[]副本格式,為了降低這個占用,在數據轉換步驟我們進行優化,每條日志數據直接轉換為jdbc可以直接使用的List數據,這樣jdbc在構造生成SQL的時候,拿到的數據其實是List的一個引用,這個優化降低了約三分之一內存消耗。

另外對writer進程做火焰圖分析時,我們發現jdbc在生成SQL時,會把提交數據的每個字符進行判定,識別出特殊字符如'\', '\n', '\b'等做轉義,這個轉義操作使用的是map函數,在數據量大時,消耗了約17%的CPU,我們對此做了優化,使用swtich后,內存大幅降低,節約了13%的CPU消耗。

clickhouse的弱集群概念保證了單節點宕機時,整個集群幾乎不受影響,submit高可用保證了當節點異常時,數據仍然可以正常寫入到健康節點,從而使得整個日志寫入非常穩定,幾乎沒有因為節點宕機導致的延遲情況。

關于日志攝入Clickhouse的方式,石墨開源了另一種攝入方式,創建KafkaEngine表直接消費clickhouse,再將數據導入到物化視圖內,通過物化視圖最終導入到本地表。這種方式好處是節省了一個writer的組件,上報到kafka的數據直接就可以存儲到clickhouse,但缺點非常多:

  • 每個topic都需要創建獨立的KafkaEngine,如果需要切換表,增加topic,都要變更DDL,并且無法支持一個topic不同域存儲到不同表。

  • 另外解析kafka數據和物化視圖都要消耗節點CPU資源,而clickhouse合并和查詢都是非常依賴cpu資源的操作,這會加重clickhouse的負載,從而限制了clickhosue整體吞吐,影響了查詢性能,需要擴容更多的節點來緩解此問題,clickhouse的單臺服務器需要更多核數,SSD和大磁盤存儲,因此擴容成本很高。 

選擇了將解析寫入組件獨立出來,可解決上面提到的很多問題,也為后期很多擴展功能提供了很大靈活性,好處很多,不再一一列舉。

3、存儲 - Clickhouse

1)高吞吐寫入

提交到Clickhouse的數據以二維表的形式存儲,二維表我們使用的是Clickhouse最常用的MergeTree引擎,關于MergeTree更詳細的描述可以參考網上這篇文章《MergeTree的存儲結構》。

https://developer.aliyun.com/article/761931spm=a2c6h.12873639.0.0.2ab34011q7pMZK

  • 數據在磁盤的邏輯存儲示意圖

MergeTree采用類似LSM-Tree數據結構存儲,每次提交的批量數據,按照表的分區鍵,分別保存到不同的part目錄內,一個part內的行數據按照排序鍵進行排序后,再按列壓縮存儲到不同的文件內,Clickhouse后臺任務會持續對這些每個小型的part進行合并,生成更大的part。

MergeTree雖然沒有ES的倒排索引,但有更輕量級的分區鍵,主鍵索引和跳數索引。

  • 分區鍵可以確保查找的時候快速過濾掉很多part,例如按照時間搜索時,只命中時間范圍的part。

  • 主鍵索引和關系型數據庫的主鍵不同,是用來對排序數據塊進行快速查找的輕量級索引。

  • 跳數索引則根據索引類型對字段值進行索引,例如minmax索引指定字段的最大值和最小值,set存儲了字段的唯一值進行索引,tokenbf_v1則對字段進行切分,創建bloomfilter索引,查詢的時候可以直接根據關鍵字計算日志是否在對應數據塊內.

一個part的數據會被按照排序鍵進行排序,然后按照大小切分成一個個較小的塊(index_granularity),塊默認有8192行,同時主鍵索引對每個塊的邊界進行索引,跳數索引則根據索引的字段生成索引文件,通常這三者生成的索引文件都非常小,可緩存在內存中加速查詢。

了解了MergeTree的實現原理,我們可以發現,影響Clickhouse寫入的一個關鍵因素是part的數量,每次寫入都會產生一個part,part越多,那么后臺合并任務也將越繁忙。除了這個因素外,part的生成和合并均需要消耗CPU和磁盤IO。

所以總結一下,三個影響寫入的因素:

  • part數量 - 少

  • CPU核數 - 多

  • 磁盤IO - 高

要提高寫入吞吐,就需要從這三個因素入手,降低part數量,提高CPU核數,提高磁盤IO。

將圖中的方法按照實現手段進行分類:

  • 硬件

CPU核數越多越好,我們生產環境40+,磁盤SSD是標配,由于SSD價格貴容量小,采用SSD+HDD冷熱分離模式

  • 表結構

長日志量又大的域使用bloomfilter索引加速查詢,其他域則使用普通跳數索引即可,我們測試觀察能節約近一半的CPU。

  • 數據寫入

Writer提交的數據,按照分區鍵進行分批提交,或者部分分區字段都可,也即單次提交的分區鍵基數盡可能小,最理想為1,此方法可大大降低小part數量。分區鍵的選擇上,可根據應用日志的數量選擇獨立分區鍵,存儲大日志量域,大日志量應用通常會達到條數閾值提交,可使得合并的part都是較大part,效率高;或者混合分區鍵,將小應用混合在一個分區提交。

2)高速查詢

很多次,我和別人解釋為什么日志系統沒有(全文索引)仍然這么快的原因時,我都直接丟出這張圖,圖源自商用產品Humio公司的網站,也是我們老板多次推薦我們學習參考的一個產品,2021年初已被CrowdStrike以4億美元收購。

1PB的數據存儲,沒有了全文索引的情況,直接暴力檢索一個關鍵字,肯定是超時的,如果先經過時間,標簽以及bloomfilter進行過濾篩選后,再執行暴力搜索,則需要檢索的數據量會小的多。MergeTree引擎是列式存儲,壓縮率很高,高壓縮率有很多優勢,從磁盤讀取的數據量少,頁面緩存需要的內存少,更多的文件可以緩存在高速內存中,Clickhouse有和Humio一樣的向量化執行和SIMD,在查詢時,這些內存中的壓縮數據塊會被CPU批量的執行SIMD指令,由于塊足夠小,通常為壓縮前1M,這樣函數向量執行和SIMD計算的數據足夠全部放在cpu緩存內,不僅減少了函數調用次數,并且cpu cache的miss率大大降低。查詢速度相比沒有向量執行和SIMD有數倍提升。

4、應用維度日志TTL

起初我們計劃使用表級別的TTL來管理日志,將不同存儲時長的日志放入不同的表內,但這樣會導致表和物化視圖變得非常多,不方便管理,后來使用了一個改進方案,將TTL放在表分區字段內,開發一個簡單的定時任務,每天掃描刪除所有超過TTL日期的part,這樣做到了一張表支持不同TTL的日志存儲,靈活性非常高,應用可以通過界面很方便查看和調整存儲的時長。

5、自定義字段存儲方案

標準格式日志內的自定義字段名稱由業務輸出,基數是不確定的,我們第一版方案是創建數百個字符串,整數和浮點數的擴展字段,由開發自行配置這個自定義映射,后來發現這個方案存在嚴重缺陷:

  • 開發需要將日志的每一個字段均手動配置到映射上去,隨著日志的變更,這樣的字段越來越多,隨著數量膨脹將難以維護,

  • Clickhouse需要創建大量的列來保存這些字段,由于所有應用混合在一起存儲,對于大多數應用,太多列不但浪費,并且降低了存儲速度,占用了大量的文件系統INODE節點

后來借鑒了Uber日志存儲的方案,每種數據類型的字段,分別創建兩個數組,一個保存字段名稱,另一個保存字段值,名字和值按順序一一對應,查詢時,使用clickhouse的數組檢索函數來檢索字段,這種用法支持所有的Clickhouse函數計算。

[type]_names和[type]_values分別存儲對應數據類型字段的名稱和值。

1)插入

多層嵌套的json字段將被打平存儲,例如{"json": {"name": "tom"}}將轉換為 json_name="tom"字段。

不再支持數組的存儲,數組字段值將被轉換為字符串存儲,例如:{"json": [{"name": "tom", "age": 18}]},轉換為json="[{\"name\": \"tom\", \"age\": 18}]"。

2)查詢

原來的映射自定義字段目前仍然保留10個,如果不夠,可以隨時添加,可以支持一些域的固定自定義字段,或者一些特殊類型的日志,例如審計日志,系統日志等,這些字段在查詢的時候用戶可以使用原來的名稱,訪問Clickhouse之前會被替換為表字段名稱

自定義字段的另一個方案是存儲在map內,可以節約兩個字段,查詢也更簡單,但經過我們測試,查詢性能沒有數組好:

  • 數組存儲壓縮率相比比Map略好。

  • 數組查詢速度比Map快1.7倍以上。

  • Map的查詢語法比數組簡單,在前端簡化了數組的查詢語法情況下,這個優勢可忽略。

四、前端日志查詢系統

日志系統第一版是基于kibana開發的,版本較老。2.0系統我們直接拋棄舊版,自研了一套查詢系統,效果如下:

新版查詢會自動對用戶輸入的查詢語句進行分析,添加上查詢的應用域名和時間范圍等,降低用戶操作難度,支持多租戶隔離。

自定義字段的查詢是非常繁瑣的,我們也做了一個簡化操作:

  • string_values[indexOf(string_names, 'name')] 簡化為:str.name

  • number_values[indexOf(number_names, 'height')] 簡化為:num.height

Clickhouse一次執行一條語句,日志查詢時柱狀圖和TOP示例日志是兩條語句,會使得查詢時間范圍翻倍,參考攜程的優化方法,查詢詳情時,我們會根據柱狀圖的結果,將時間范圍縮小至TOP條記錄所在的時間區間。

豐富查詢用法

Clickhouse豐富的查詢語法,讓我們新日志系統的查詢分析功能非常強大,從海量日志提取關鍵字,非常容易,下面列舉兩個查詢用法:

  • 從文本和JSON混合的日志數據中提取JSON字段

  • 從日志計算分位數

五、正確使用姿勢

  • 打印日志不要太長,不超過10K。

  • 查詢條件帶上有跳數索引的標簽,或者其他非日志詳情的字段,召回日志數越小,查詢速度越快。

OLAP數據庫Clickhouse是處理大規模數據密集型場景的利器,非常適合海量日志存儲和查詢分析,構建了一個低成本,無單點,高吞吐,高速查詢的下一代日志系統。?

責任編輯:張燕妮 來源: 唯技術
相關推薦

2022-09-21 09:27:51

日志系統

2015-12-29 18:49:35

樂視生態

2021-12-01 23:01:29

Windows 10Windows微軟

2025-04-14 00:10:00

人工智能AIAI 模型

2022-07-20 09:47:49

日志架構

2023-10-10 07:24:59

SRE日志OnCall

2016-10-24 09:37:51

系統日志日志分析

2019-03-01 08:22:26

數據泄露網絡保險網絡安全

2023-07-13 15:02:34

數據中心

2016-06-01 09:33:02

海量日志處理架構

2021-04-30 07:42:37

Windows10操作系統微軟

2022-08-22 10:31:39

數據中心運營商能源成本

2010-10-25 18:25:01

用友財會軟件

2024-11-04 09:34:17

2017-04-02 14:36:22

2021-07-08 06:52:41

ESClickHouse Lucene

2021-02-05 06:41:52

運維生產日志重復打印

2021-05-11 10:17:31

Windows 功能系統

2021-05-20 08:30:47

運維日志打印

2025-02-28 09:02:38

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美激情一区 | 91在线看网站 | 久久久久久高潮国产精品视 | www.久久 | 欧美一区成人 | 911精品美国片911久久久 | 韩国精品在线观看 | 亚洲精品免费在线 | 亚洲国产精品一区二区www | 国产精品成人国产乱 | 中文字幕一区二区三区乱码在线 | 久草网站| 成人国产午夜在线观看 | 久久国产精品精品 | 精品久久久久久中文字幕 | 精品亚洲视频在线 | 国产精品久久久久aaaa九色 | 精品99久久久久久 | 91在线电影| 九九热精品在线 | 一级午夜aaa免费看三区 | 特黄一级 | 国产在线精品一区二区 | 精品伊人久久 | 成人片免费看 | 久久久久久久电影 | 久草在线高清 | 免费骚视频 | 国产欧美日韩一区 | 国产精品久久久久久 | 欧美天堂 | 亚洲 欧美 日韩 在线 | 美女张开腿露出尿口 | 亚洲一区二区三区福利 | 日韩成人免费在线视频 | 亚洲精品中文字幕av | 一区二区三区欧美在线观看 | 国产剧情一区 | 欧美日韩国产一区二区三区 | 日韩a v在线免费观看 | 久久精品国产一区 |