新聞中心
一、背景
日志記錄了一個系統(tǒng)的行為,對于了解系統(tǒng)、診斷問題、輔助審計等都有極其重要的作用。通常最近一段時間的日志訪問頻率是最高的,我們通過聚合日志,分析日志、匯總數(shù)據,幫助開發(fā)、運維、DBA了解業(yè)務的狀態(tài)和行為。這次實踐是針對MySQL的抓包日志進行分析,當前系統(tǒng)不足以支持新的需求,需要重構一套日志分析系統(tǒng)。

創(chuàng)新互聯(lián)建站-專業(yè)網站定制、快速模板網站建設、高性價比荊州網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式荊州網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋荊州地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。
現(xiàn)有抓包系統(tǒng)是將 MySQL 請求的所有 SQL 語句抓取并分析之后寫入到 Clickhouse 中,數(shù)據可以用來分析數(shù)據庫的操作。 可以查找當前實例、庫、表有多少 AppCode 在訪問、數(shù)據庫資源是否可以回收、輔助審計等功能。
Sniffer 抓包之后將數(shù)據寫入到 Kafka 中,Clickhouse 直接消費 Kafka 的隊列中數(shù)據,并將數(shù)據 merge 到 Clickhouse 中。由 Server 程序按照天級別定時讀取 Clickhouse 中的數(shù)據,分析、匯總數(shù)據,并解析請求 IP 對應的服務信息等,最后將結果寫入到 MySQL 中。
當前數(shù)據為日志數(shù)據,允許少部分丟失或重復,Kafka 隊列中的數(shù)據約有 133w/s (單個隊列最多 33W ),MySQL 中存儲的結果數(shù)據規(guī)模大約在 4.6T 左右。
二、名詞解釋
- AppCode
服務的名稱,是一個服務的基本屬性。
- Clickhouse
一個用于聯(lián)機分析(OLAP)的列式數(shù)據庫。
- Kafka
一個高性能的分布式隊列服務。
- Zookeeper
一個分布式的開源協(xié)調服務。
- 擴展性
在業(yè)務量上漲時,服務通過較低的代價就可以滿足對業(yè)務量上漲的需求。
- 聚合比
將 N 條數(shù)據按照同一緯度聚合為 M 條數(shù)據,M 一定小于等于 N。聚合比 = 聚合之后的數(shù)據條數(shù)/聚合之前的數(shù)據條數(shù)。
三、現(xiàn)狀分析
1、消費能力不足導致數(shù)據丟失
Clickhouse 消費 Kafka 隊列中的數(shù)據能力不足,延遲較高。并且 Kafka 中的數(shù)據只保留 3 個小時,根據測試四個節(jié)點 Clickhouse 消費的 Kafka 隊列中的數(shù)據,約有 80% 的數(shù)據丟失,導致數(shù)據不完整。
2、服務信息計算不準確
Server 是天級別計算請求的服務信息。由于服務已經上云部署,單個服務的 IP 變動非常頻繁,導致 Server 獲取到服務信息有延遲(最高延遲 24 小時),甚至很多計算的結果是錯誤的。這導致部分場景下分析出來的數(shù)據完全不可信。
3、匯總數(shù)據較少
當前只匯總了四個維度的請求數(shù)據,并且只有天級別的數(shù)據,粒度較大,無法下鉆查詢具體信息,展示的維度和明細信息較少。
4、服務監(jiān)控&可用性
Server 節(jié)點目前只有一個,缺乏可用性并沒有詳細的監(jiān)控信息。
四、需求
針對當前服務的不足,設計一套服務需要滿足當前日志計算性能和業(yè)務需求,并且具備較好的擴展性。
五、目標
1、高性能、高擴展性、高可用
服務需要具備以下特性:
1)高性能
在有限資源的情況下,盡可能提高數(shù)據消費、聚合能力,降低數(shù)據丟失的概率,降低數(shù)據入庫的延遲。
2)高可用
單個或多個節(jié)點出現(xiàn)問題時,不影響服務整體的可用性。
3)高擴展
在未來業(yè)務日志體量進一步增長時,僅通過增加部署節(jié)點或者修改配置,就可以滿足增長的需求,無需額外的工作。
2、降低計算請求業(yè)務信息的延遲
從請求 IP 到獲取服務信息的延遲降低在 1min 以內,確保 99.9% 的準確性。
3、更多維度匯總數(shù)據和下鉆查詢
支持更多維度的匯總信息查詢,以及支持部分場景下的下鉆查詢。
4、監(jiān)控
提供多種監(jiān)控數(shù)據,方便展示服務情況,根據監(jiān)控即可以方便定位到問題。
六、分析
當前 Clickhouse 消費能力不足可以通過擴展節(jié)點和調優(yōu)參數(shù)進一步解決,但是服務信息計算是 Clickhouse 做不到的,并且 OLAP 類型的數(shù)據庫對數(shù)據更新并不是太友好,尤其是大規(guī)模的更新。如果要解決【降低計算請求業(yè)務信息的延遲】這個問題可以有兩個解決方案:
如果采用方案一,會增加 Sniffer 端的不可控性,這與我們之前設計的盡可能減少 Sniffer 端資源消耗的初衷相違背,所以我們選擇方案二。
七、設計
1、整體流程
整體流程設計如下所示:
2、模塊劃分
所有模塊的目標: 高性能、高可用、高擴展。
3、dubaiMeta
1)說明
由于基礎服務不能提供高性能的 IP-AppCode 映射信息的接口,需要自行實現(xiàn)這一功能。對接基礎服務的 IP-AppCode 映射信息提供的接口,實時從 Kafka-OPS 隊列中獲取 IP-AppCode 映射變更的信息流,Merge 到當前數(shù)據,并提供 IP-AppCode 信息的接口;
2)設計
由于 dubaiMeta 是提供基礎信息的接口,訪問量比較大,需要提供高性能、高可用、高擴展性,故 dubaiMeta 需要盡可能設計成為無狀態(tài)的服務。
將所有的 IP-AppCode 映射數(shù)據存儲在 MySQL,映射為最新版本。所有的 IP-AppCode 變更歷史也都會存儲在 MySQL。通過版本信息持續(xù)將 IP-AppCode 變更信息 Merge 到最新版本。目前 IP-AppCode 數(shù)據整體體量不大,可以在服務內部緩存,不使用其他緩存。這樣既可以減少網絡和緩存的請求,降低請求耗時,也會避免因對緩存的依賴而導致的性能和可用性問題。這樣 dubaiMeta 就可能成為一個接近無狀態(tài)的服務。
單個請求如果不能命中緩存則會請求基礎服務的 IP-AppCode 接口,并將變更數(shù)據 Merge 到緩存。但是單個 dubaiMeta 節(jié)點數(shù)據變更之后如何與其他 dubaiMeta 節(jié)點通訊最后達到所有節(jié)點數(shù)據一致?
有兩種方案:
盡可能保證單個節(jié)點的高性能的,并檢測單個節(jié)點的數(shù)據一致性延遲,將有問題的服務及時下掉,通過這個方法可以盡可能減低數(shù)據不一致帶來的問題。故選擇【變更通知】的方式;
3)啟動流程
服務啟動時首先從 Kafka-OPS 持續(xù)訂閱信息流,所有變更信息 Merge 到內部緩存,然后再從 Self-Kafka-OPS 中持續(xù)訂閱變更信息流,所有變更信息 Merge 到內部緩存,最后從 MySQL 中獲取全量的數(shù)據信息,將所有數(shù)據 Merge 到緩存,組合成全量的數(shù)據。等到所有數(shù)據 Merge 完成,并且兩個 Kafka 隊列無堆積時,再提供服務。
4)性能分析
目前基礎信息的數(shù)據量不大,可以在服務內部緩存,不使用其他緩存。既可以減少網絡和訪問緩存的耗時,大幅度降低請求的耗時,又可以避免因對緩存的依賴而導致的性能和可用性問題。
單節(jié)點 IP-AppCode 映射變更會發(fā)起變更通知,異步通知其他節(jié)點,無需感知其他節(jié)點存在,故性能可以得到保證。
5)可用性分析
dubaiMeta 目前所有數(shù)據存儲在本地緩存,在 MySQL 中存儲一份副本和變更信息流。
由于 dubaiMeta 是接近無狀態(tài)的,部署多個節(jié)點,通過負載均衡服務下發(fā)到不同的節(jié)點就可以保證整體服務的可用性。
MySQL 通過平臺已有的 HA,保證可用性;
6)擴展性分析
由于 dubaiMeta 是接近無狀態(tài)的,故可以橫向擴展,不對其他節(jié)點產生影響,只需要在負載均衡器上添加節(jié)點即可。
4、SnifferServer
1)說明
從 Kafka-Sniffer 隊列獲取日志數(shù)據,在日志中補充各種業(yè)務信息,并聚合數(shù)據。最后將聚合之后的結果批量寫入到 Clickhouse 中。
由于隊列中的數(shù)據量比較大,無法全量存儲所有數(shù)據,需要按照一定的維度聚合數(shù)據。通過降低聚合比(聚合之后的數(shù)據條數(shù)/聚合之前的數(shù)據條數(shù))可以降低總體數(shù)據量,在保證性能的前提下盡可能縮短入庫的時間。
由于 Clickhouse 是 OLAP 分析類型的列式數(shù)據庫,更推薦批量寫入的方式提高數(shù)據庫的寫入性能(每次不少于 1000 條)。
2)設計
針對單個隊列,可以使用多個 SnifferServer 使用同一個 consumerGroup 消費數(shù)據,保證消費者的性能、可用性,同時 SnifferServer 也具備了一定的擴展性。
SnifferServer 是內存消耗和 cpu 消耗類型的服務。為了減少 gc 和內存消耗,通過復用對象,確保單個服務內部對象的數(shù)量不會有較大波動,可以大幅度降低 gc 以及內存的使用量,提高性能。
按照功能,將 SnifferServer 拆分成三個模塊:consumer 模塊、aggregator 模塊、writer 模塊。
consumer 模塊消費隊列中的數(shù)據,將數(shù)據傳遞給 aggregator 模塊;aggregator 模塊填充業(yè)務信息并聚合數(shù)據,將聚合之后的數(shù)據傳遞給 writer 模塊;writer 模塊將數(shù)據批量寫入到 Clickhouse 中。
① consumer 模塊
- 功能
從 Kafka-Sniffer 隊列中獲取數(shù)據,將數(shù)據組合之后批量傳輸給 aggregator 模塊。
- 分析
針對單個 Kafka 隊列,提升消費的速度途徑有:
經測試,在當前場景配置下,單個 SnifferServer 消費隊列速度可以達到 20W/s+。 通過對 consumer 的調優(yōu)已經能夠完全達到 33w/s (兩個 SnifferServer)的消費速度,已完全滿足業(yè)務的需求。
② aggregator 模塊
- 功能
從 consumer 接受數(shù)據,并獲取 IP-AppCode 映射信息和業(yè)務信息,將信息補充到日志數(shù)據中。等到一定數(shù)量的數(shù)據或者超時之后,將這一批次的數(shù)據按照指定的維度聚合。最后將聚合之后的結果傳輸給 writer 模塊
- 分析
- 如果每條數(shù)據都需要通過接口獲取 IP-AppCode 映射和業(yè)務信息,那樣會大大降低聚合的效率,故本地需要緩存 IP-AppCode 和業(yè)務信息。aggregator 模塊同樣也需要訂閱 Kafka-OPS 和 Self-Kafka-OPS 變更,Merge IP-AppCode 變更信息到本地緩存。
- 通過增加 aggregator 線程數(shù)量提升并發(fā)數(shù),可以有效的提升聚合的效率。但線程數(shù)越多會在不同程度上提高聚合比(和業(yè)務行為相關),通過增加單個批次的數(shù)量可以降低聚合比,兩個指標需要根據需要測試調優(yōu);
經測試:針對同一個隊列中的數(shù)據,單個 SnifferServer 的聚合比約為 10%-20% 左右,兩個 SnifferServer 的平均聚合比約為 15%-30% 左右,三個 SnifferServer 的平均聚合比約為 30% 以上,故在同等配置的情況下增加 SnifferServer 則會增加聚合比,存儲端將增加數(shù)據量。
③ writer 模塊
- 功能
從 aggregator 模塊接受數(shù)據,緩存在內存中。當緩存數(shù)據超過 N 條或者緩存時間超過 M 秒之后再將緩存數(shù)據批量寫入到 Clickhouse 中;
- 分析
每個批次應該盡可能緩存足夠的的數(shù)據量再寫入數(shù)據,提升寫入的效率,降低寫入的次數(shù),預設單個批次為 1w(最少,可配置)條數(shù)據;
3)分析
每個模塊均可以設置緩存大小和并行的線程數(shù),通過設置緩存大小和并行的線程數(shù)可以提高效率。但是需要注意的是,緩存大小和并行線程越多,占用的資源也就越多。并且如果程序意外終止,那么丟失的數(shù)據也會變多,需要酌情考慮各個參數(shù)的配置。
對于各個模塊的啟動和關閉順序需要額外關注。
① 模塊啟動順序
先啟動 writer 模塊,初始化 writer 模塊的緩存和線程,再啟動 aggregator 模塊,初始化 aggregator 的緩存和線程,最后啟動 consumer 模塊,初始化 consumer 模塊的線程和緩存。
② 模塊關閉順序
為了減少數(shù)據丟失,在正常情況下關閉服務時需要按照以下順序關閉模塊
- 關閉所有的Kafka的連接;
- 將 consumer 模塊中所有緩存數(shù)據發(fā)送到 aggregator 模塊之后,再關閉所有 consumer 模塊的線程;
- 將 aggregator 中的緩存數(shù)據立即聚合(所有日志數(shù)據補完業(yè)務信息,并聚合完成)。聚合完成的數(shù)據全部發(fā)送給 writer 模塊之后,再關閉所有 aggregator 模塊的線程;
- 將 writer 模塊中的數(shù)據分批次,全部寫入到 Clickhouse 中,最后關閉所有 writer 模塊的線程。
4)擴展性分析
由于 SnifferServer 是偏計算類型的服務,并且從 Kafka 到 SnifferServer 到 Clickhouse,需要大量的數(shù)據傳輸,需要較好的 cpu 和網卡才可以充分發(fā)揮 SnifferServer 的性能;
① SnifferServer 內部擴展性
SnifferServer 的每個模塊都可以通過設置線程數(shù)和緩存大小提高性能;
② SnifferServer 級別的擴展性
對于單個隊列,受限于 Kafka 的 partition 數(shù)量,最多有于 partition 數(shù)量相等的 SnifferServer 運行,超過 partition 數(shù)量時節(jié)點不再參與隊列消費;
③ Kafka 的 Partition
單個 Kafka 集群的 partition 理論上沒有限制,受限于服務器資源、Zookeeper 和運維的方便性等,需要設置上限;
④ 整個服務
可以規(guī)劃針對不同的 IDC,向不同的 Kafka 寫入日志數(shù)據,這樣日志數(shù)據將被分區(qū);
5)可用性分析
SnifferServer 之間通過 consumerGroup 消費 Kafka 隊列中的數(shù)據。對于單個隊列通過冗余 SnifferServer,即使單個 SnifferServer 掛掉,不會影響整體服務。
5、SnifferAnalyze
1)說明
按照天級別定時從 Clickhouse 中獲取聚合數(shù)據,分析、匯總,存儲分析之后的結果并提供接口和頁面展示結果。
2)設計
分析匯總之后的結果大概分為兩類數(shù)據,第一類是初步聚合的粗粒度數(shù)據,數(shù)據量比較大。數(shù)據一旦產生不會修改,只有大范圍的刪除,一般是溯源、分析、下鉆查詢使用,使用的頻率不是很高;第二類是匯總的報告數(shù)據。部分數(shù)據會存在大范圍的修改,較多的并發(fā)查詢。整體數(shù)據量相對于第一類數(shù)據量較少,一般是展示結果、接口查詢較多;
Clickhouse 在大規(guī)模存儲上的單表查詢和寫入效率較高,壓縮效率較高但不擅長做并發(fā)查詢和頻繁的修改數(shù)據,官網建議每秒最多查詢 100 次。相比較而言,MySQL 適合存儲小體量數(shù)據,以及數(shù)據的增刪改查,并擅長高并發(fā)查詢。
綜合考慮節(jié)省存儲成本以及各個存儲的特性,第一類數(shù)據適合存儲到 Clickhouse 中,第二類數(shù)據適合存儲到 MySQL 中。針對原始日志數(shù)據設置合適的過期時間,超過指定時間的數(shù)據都予以刪除,而匯總數(shù)據相較于原始數(shù)據量已經大幅度減少,可以保留較長的過期時間。
依托 Clickhouse 的分析能力,對于第一類數(shù)據直接將 Clickhouse 中的數(shù)據分析出來直接寫入到 Clickhouse 中,避免中間轉儲。第二類數(shù)據需要從 Clickhouse 中獲取出來,分析、計算、匯總之后再寫入到 MySQL 中。
每個任務執(zhí)行前都需要獲取鎖,只有成功獲取到鎖的任務才可以執(zhí)行該任務。SnifferAnalyze 多個節(jié)點在執(zhí)行任務前會通過搶占的方式獲取任務鎖,僅當成功獲取了鎖的節(jié)點會執(zhí)行任務,保證了單個節(jié)點掛掉不影響分析任務的執(zhí)行。但是如果任務執(zhí)行過成中被終端,目前需要人為介入處理。
3)擴展性分析
目前分析類型的任務節(jié)點擴展能力有限。
4)可用性分析
由于分析類型的任務擴展能力有限,故只能在節(jié)點之間保證高可用。并且一旦任務執(zhí)行中斷需要人為介入處理。
6、Clickhouse
1)說明
Clickhouse 架構圖
例如圖示 Clickhouse 有兩個分片(A 和 B),每個分片有兩個副本([A1,A2],[B1,B2]),集群與三節(jié)點的 Zookeeper 通訊。
① 同步
Clickhouse 集群 Replication 引擎的副本是通過 Zookeeper 實現(xiàn)的,Zookeeper 存儲數(shù)據塊的元數(shù)據信息。分片 A 有 A1 和 A2 兩個節(jié)點,A1 和 A2 共同監(jiān)聽 Zookeeper 執(zhí)行目錄下節(jié)點的數(shù)據。當 A1 節(jié)點寫入數(shù)據塊之后,A1 在 Zookeeper 上變更元數(shù)據信息。A2 收到 Zookeeper 的元數(shù)據變更之后,向 A1 發(fā)起拉取指定數(shù)據塊的通知,A1 將指定的數(shù)據塊發(fā)送給 A2,完成數(shù)據傳輸。同理 A2 也可以寫入數(shù)據,通知 Zookeeper 變更數(shù)據,并向 A1 傳輸數(shù)據。數(shù)據同步是異步的,傳輸數(shù)據塊時會去重。更多副本相關的信息請見官網說明。
② 分片
分片依靠 Distribute 引擎實現(xiàn)。Distribute 引擎不存儲任何數(shù)據,Clickhouse 有 Distribute 引擎支持將數(shù)據按照指定的規(guī)則(random,hash,range,自定義)將數(shù)據分發(fā)到各個分片。
數(shù)據寫入 Distribute 引擎時,數(shù)據在本地寫入完成后立即返回。Clickhouse 會周期性的按照規(guī)則將數(shù)據分發(fā)的其他節(jié)點上。
③ 查詢
通過 Distribute 引擎查詢時,無論分片規(guī)則是什么樣的,Distribute 都會將 SQL 分發(fā)到所有的分片上查詢,并在當前節(jié)點匯總數(shù)據,最后返回給客戶端。如果查詢 Replication 引擎的表,那么只查詢本地數(shù)據。
2)可用性分析
Clickhouse 的 Replication 引擎和 Zookeeper 實現(xiàn)數(shù)據副本,保證了每個分片內可以允許一個副本宕機。Distribute 引擎可以保證在 Clickhouse 所有節(jié)點上都可以寫入和讀取。
但是通過數(shù)據同步是異步的。如果節(jié)點寫入成功并在數(shù)據尚未完成傳輸之前宕機,無法恢復,則尚未同步的數(shù)據塊將會丟失。
3)擴展性分析
由于 Distribute 查詢的時候會將 SQL 分發(fā)到所有的分片上,無論分片的數(shù)據狀態(tài)如何,故新增的節(jié)點可以直接加入到 Clickhouse 集群中,而無需擔心舊數(shù)據遷移的問題。但是需要考慮數(shù)據傾斜問題,通過提高新加入節(jié)點權重可以將新寫入的數(shù)據更多的發(fā)送到新加入分片上。
向 Distribute 引擎寫入數(shù)據時,Distribute 引擎首先會寫入本地,再依次轉發(fā)給其他節(jié)點,可能會導致本地網絡流量增加、服務 merge 數(shù)據塊時產生額外的 cpu 以及 IO 使用的問題??梢酝ㄟ^只寫入本地表,而不寫入 Distribute 表解決這個問題。但是需要通過一定的策略(比如輪詢)寫入不同的 Clickhouse 節(jié)點,解決數(shù)據傾斜的問題。
7、監(jiān)控
1)說明
當前監(jiān)控只是用于查看各個節(jié)點的狀態(tài)情況,展示性能問題,并未提供高級別的功能。監(jiān)控告警接入公司現(xiàn)有的監(jiān)控系統(tǒng)。
八、效果
1、SnifferServer
所有 SnifferServer 節(jié)點平均內存占用約為 12G 左右,最大 gc 平均約為 21ms,75 分位的 gc 平均約為 0.6ms。
兩節(jié)點 SnifferServer 合計 CPU(32核)利用率峰值約 70%,網卡峰值 上行約 330Mb/s 下行 400Mb/s。
單個隊列數(shù)據生成速度峰值約為 30w/s,平均堆積約 20k,消費者速度要快于生產者。
aggregator 平均每秒聚合 1.2 次,數(shù)據聚合比約為 40%,writer 每秒約寫入 6 次,業(yè)務信息和 appCode 命中率幾乎 100%。
2、頁面展示
展示某個業(yè)務的平均響應時間和查詢次數(shù)
展示某個慢查詢的平均響應時間和查詢次數(shù)
九、總結
SnifferServer 將隊列中的日志數(shù)據補全業(yè)務信息、聚合數(shù)據、將結果寫入到 Clickhouse 中,SnifferAnalyze 定期分析數(shù)據,將結果寫入到 Clickhouse 和 MySQL。整個系統(tǒng)具備高性能、高可用性、高擴展性的優(yōu)點,內存和 CPU 使用率比較穩(wěn)定。日志分析系統(tǒng)呈現(xiàn)出來的結果可以幫助開發(fā)更好的了解業(yè)務的行為,發(fā)現(xiàn)潛在的問題,評估業(yè)務在數(shù)據庫方面的風險。結合慢查詢風險指數(shù)系統(tǒng)可以更精確的評估慢查詢的風險。
新聞名稱:去哪兒網MySQL日志分析實踐,80%數(shù)據丟失都給你救回來!
網站地址:http://m.fisionsoft.com.cn/article/cocdgjo.html


咨詢
建站咨詢
