Cloudflare如何分析每秒上百萬的DNS查詢

來源: CSDN
作者:weixin_34262482
時間:2020-12-03
16784
Cloudflare已經(jīng)有一個用于HTTP日志的數(shù)據(jù)管道。我們希望DNS分析工具可以利用該功能。每當邊緣服務處理一個HTTP請求時,它就會以Capn Proto格式生成一個結構化的日志消息,并將其發(fā)送到本地多路復用服務。


在本文中,我們將介紹DNS分析工具的組件,這些組件幫助我們每月處理數(shù)以萬億計的日志。

ia_12300000001.jpg

Cloudflare已經(jīng)有一個用于HTTP日志的數(shù)據(jù)管道。我們希望DNS分析工具可以利用該功能。每當邊緣服務處理一個HTTP請求時,它就會以Cap'n Proto格式生成一個結構化的日志消息,并將其發(fā)送到本地多路復用服務??紤]到數(shù)據(jù)量,我們只記錄部分DNS消息數(shù)據(jù),只包含我們感興趣的數(shù)據(jù),例如響應碼,大小或query name,這使得我們每個消息平均只保留約150字節(jié)數(shù)據(jù)。然后將其與元數(shù)據(jù)處理(例如在查詢處理期間觸發(fā)的定時信息和異常)融合。在邊緣融合數(shù)據(jù)和元數(shù)據(jù)的好處是,我們可以將計算成本分散到成千上萬的邊緣服務器,并且只記錄我們需要的信息。

多路復用服務(稱為“日志轉發(fā)器”)正在每個邊緣節(jié)點上運行,從多個服務組裝日志消息并將其傳輸?shù)轿覀兊膫}庫,以便通過TLS安全通道進行處理。運行在倉庫中的對應服務將日志接收并解分解到幾個Apache Kafka集群中。Apache Kafka用于生產(chǎn)者和下游消費者之間做緩沖,防止消費者故障或需要維護時的數(shù)據(jù)丟失。自0.10版本以來,Kafka允許通過機架感知分配副本,從而提高對機架或站點故障的恢復能力,為我們提供容錯的未處理消息存儲。

ia_12300000002.jpg

擁有結構化日志隊列使我們能夠追溯性地查問題,而不需要訪問生產(chǎn)節(jié)點。在項目的早期階段,我們會跳過隊列并找到我們所需的粗略時間段的偏移量,然后將數(shù)據(jù)以Parquet格式提取到HDFS中,以供離線分析。

關于聚合

HTTP分析服務是圍繞生成聚合的流處理器構建的,因此我們計劃利用Apache Spark將日志自動傳輸?shù)紿DFS。由于Parquet本身不支持索引以避免全表掃描,因此在線分析或通過API提供報告是不切實際的。雖然有像parquet-index這樣的擴展可以在數(shù)據(jù)上創(chuàng)建索引,但也不能實時運行。鑒于此,最初的設計是僅向客戶顯示匯總報告,并保留原始數(shù)據(jù)用以內部故障排除。

匯總摘要的問題在于,它們只能處理基數(shù)較低(大量唯一值)的列。通過聚合,給定時間范圍內的每個列都會擴展到很大的行數(shù)(與唯一條目個數(shù)相等),因此可以將響應碼(例如只有12個可能的值,但不包含查詢名稱)進行聚合。如果域名受歡迎,假設每分鐘被查詢1000次,那么可以預期每分鐘做聚合可以減少1000倍的數(shù)據(jù),然而實際上并不是這樣。

由于DNS緩存的存在,解析器在TTL期間不會進行DNS查詢。TTL往往超過一分鐘。因此,服務器多次看到相同的請求,而我們的數(shù)據(jù)則偏向于不可緩存的查詢,如拼寫錯誤或隨機前綴子域名攻擊。在實踐中,當用域名進行聚合時,我們可以看到最多可以減少為原來的1/60的行數(shù),而多個分辨率存儲聚合幾乎可以抵消行減少。使用多個分辨率和鍵組合也可以完成聚合,因此聚合在高基數(shù)列上甚至可以產(chǎn)生比原始數(shù)據(jù)更多的行。

ia_12300000003.jpg

由于這些原因,我們首先在zone層次上匯總日志,這對于趨勢分析來說已經(jīng)足夠,但是對于具體原因分析來說則太過粗糙。例如,我們正在調查其中一個數(shù)據(jù)中心的流量短暫爆發(fā)。具有未聚合的數(shù)據(jù)使我們能夠將問題縮小到特定DNS查詢,然后將查詢與錯誤配置的防火墻規(guī)則相關聯(lián)。像這樣的情況下,只有匯總日志就有問題,因為它只聚合一小部分請求。

所以我們開始研究幾個OLAP系統(tǒng)。我們研究的第一個系統(tǒng)是Druid。我們對前端(Pivot和以前的Caravel)是如何切分數(shù)據(jù)的能力印象很深刻,他使我們能夠生成具有任意維度的報告。Druid已經(jīng)被部署在類似的環(huán)境中,每天超過1000億事件,所以我們對它可以工作很有信心,但是在對抽樣數(shù)據(jù)進行測試之后,我們無法證明數(shù)百個節(jié)點的硬件成本。幾乎在同一時間,Yandex開源了他們的OLAP系統(tǒng)ClickHouse。

ClickHouse

ClickHouse的系統(tǒng)設計更加簡單,集群中的所有節(jié)點具有相同的功能,使用ZooKeeper進行協(xié)調。我們建立了一個由幾個節(jié)點組成的集群,發(fā)現(xiàn)性能相當可觀,所以我們繼續(xù)構建了一個概念驗證。我們遇到的第一個障礙是缺少工具和社區(qū)規(guī)模的規(guī)模太小,所以我們鉆研了ClickHouse設計,以了解它是如何工作的。

ClickHouse不直接支持Kafka,因為它只是一個數(shù)據(jù)庫,所以我們使用Go寫了一個適配器服務。它讀取來自Kafka的使用Cap'n Proto編碼的消息,將它們轉換為TSV,并通過HTTP接口分批插入ClickHouse。后來,我們講ClickHouse的HTTP接口替換為GO SQL驅動,以提高性能。從那以后,我們就開始為該項目提供了性能改進。我們在性能評估過程中學到的一件事是,ClickHouse寫入性能很大程度上取決于批量的大小,即一次插入的行數(shù)。為了理解為什么,我們需要進一步了解了ClickHouse如何存儲數(shù)據(jù)。

ClickHouse用于存儲的最常見的表引擎是MergeTree系列。它在概念上類似于Google的BigTable或Apache Cassandra中使用的LSM算法,但它避免了中間內存表,并直接寫入磁盤。這使得寫入吞吐量非常出色,因為每個插入的批次只能通過“主鍵”進行排序,壓縮并寫入磁盤以形成一個段。沒有內存表也意味著他僅僅追加數(shù)據(jù),并且不支持數(shù)據(jù)修改或刪除。當前刪除數(shù)據(jù)的唯一方法是按日歷月份刪除數(shù)據(jù),因為段不會與月份邊界重疊。ClickHouse團隊正在積極致力于使這個功能可配置。另一方面,這使得寫入和段合并無沖突,因此吞吐量與并行插入的數(shù)量成線性比例關系,直到I/O跑滿。但是,這也意味著它不適合小批量生產(chǎn),這就是為什么我們依靠Kafka和插入器服務進行緩沖的原因。ClickHouse在后臺不斷合并,所以很多段將被合并和寫多次(從而增加寫放大),太多未合并的段將觸發(fā)寫入限流,直到合并完成。我們發(fā)現(xiàn),每秒鐘每張表的插入一次效果最好。

表讀性能的關鍵是索引和數(shù)據(jù)在磁盤上的排列。無論處理速度有多快,當引擎需要從磁盤掃描太多數(shù)據(jù)時,這都需要大量時間。ClickHouse是一個列式存儲,因此每個段都包含每個列的文件,每行都有排序值。通過這種方式,可以跳過查詢中不存在的列,然后可以通過向量化執(zhí)行并行處理多個單元。為了避免完整的掃描,每個段也有一個稀疏的索引文件。鑒于所有列都按“主鍵”排序,索引文件僅包含每第N行的標記(捕獲行),以便即使對于非常大的表也可以將其保留在內存中。例如,默認設置是每隔8192行做一個標記。這種方式只需要122,070個標記來具有1萬億行的表格進行索引。在這里可以查看ClickHouse中的主鍵,深入了解它的工作原理。

使用主鍵列查詢時,索引返回考慮行的大致范圍。理想情況下,范圍應該是寬而連續(xù)的。例如,當?shù)湫陀梅ㄊ菫閱蝹€區(qū)域生成報告時,將區(qū)域放在主鍵的第一個位置將導致按每個區(qū)域進行排序,使得磁盤讀取單個區(qū)域連續(xù),而如果按主要時間戳排序則在生成報告是無法保證連續(xù)。行只能以一種方式排序,因此必須仔細選擇主鍵,并考慮典型的查詢負載。在我們的例子中,我們優(yōu)化了單個區(qū)域的讀取查詢,并為探索性查詢提供了一個帶有采樣數(shù)據(jù)的獨立表格。從中吸取的教訓是,我們不是試圖為了各種目的而優(yōu)化索引,而是分解差異并多加一些表。

這樣專有化設計的結果就是在區(qū)域上聚合的表格。由于沒有辦法過濾數(shù)據(jù),因此掃描所有行的查詢都要昂貴得多。這使得分析師在長時間計算基本聚合時不那么實際,所以我們決定使用物化視圖來增量計算預定義聚合,例如計數(shù)器,唯一鍵和分位數(shù)。物化視圖利用批量插入的排序階段來執(zhí)行生產(chǎn)性工作-計算聚合。因此,在新插入的段被排序之后,它也會生成一個表格,其中的行代表維度,而列代表聚合函數(shù)狀態(tài)。聚合狀態(tài)和最終結果之間的區(qū)別在于,我們可以使用任意時間分辨率生成報告,而無需實際存儲多個分辨率的預計算數(shù)據(jù)。在某些情況下,狀態(tài)和結果可能是相同的-例如基本計數(shù)器,每小時計數(shù)可以通過累計每分鐘計數(shù)來產(chǎn)生,但是對獨特的訪問者或延遲分位數(shù)求和是沒有意義的。這是聚合狀態(tài)更有用的時候,因為它允許有意義地合并更復雜的狀態(tài),如HyperLogLog(HLL)位圖,以便每小時聚合生成每小時獨立訪問者估計值。缺點是存儲狀態(tài)可能比存儲最終值要昂貴的多-上述HLL狀態(tài)在壓縮時大概有20-100字節(jié)/行,而計數(shù)器只有8字節(jié)(平均壓縮1個字節(jié))。使用這些表可以快速地將整個區(qū)域或站點的總體趨勢形象化,并且我們的API服務也使用它們做簡單查詢。在同一位置同時使用增量聚合和沒有聚合的數(shù)據(jù),我們可以通過流處理完全簡化體系結構。

基礎設施和數(shù)據(jù)整合

我們使用12個6TB磁盤做RAID-10,但在一次磁盤故障之后重新進行了評估。在第二次迭代中,我們遷移到了RAID-0,原因有兩個。首先,不能熱插拔有故障的磁盤,其次陣列重建花費了數(shù)十個小時,這降低了I/O性能。更換故障節(jié)點并使用內部復制通過網(wǎng)絡(2x10GbE)填充數(shù)據(jù)比等待陣列完成重建要快得多。為了彌補節(jié)點故障的可能性較高,我們切換到3路復制,并將每個分片的副本分配到不同的機架,并開始規(guī)劃復制到單獨的數(shù)據(jù)倉庫。

另一個磁盤故障突出了我們使用的文件系統(tǒng)的問題。最初我們使用XFS,但它在復制過程中開始在同一時間從2個對等點進行鎖定,從而在完成之前中斷了段復制。這個問題表現(xiàn)為大量I/O活動,由于損壞的部分被刪除,磁盤使用量增加很少,所以我們逐漸遷移到了ext4,該文件系統(tǒng)就沒有這個問題。

數(shù)據(jù)可視化

當時我們只依靠Pandas和ClickHouse的HTTP接口進行臨時分析,但是我們希望使分析和監(jiān)控更容易。因為我們知道Caravel(現(xiàn)在更名為Superset),我們就把它和ClickHouse進行了整合。

ia_12300000004.jpg

Superset是一個直觀的數(shù)據(jù)可視化平臺,它允許分析人員在不寫一行SQL的情況下交互地切片和切分數(shù)據(jù)。它最初是由AirBnB為Druid構建和開源的,但是隨著時間的推移,它已經(jīng)通過使用SQLAlchemy(一種抽象和ORM)為數(shù)十種不同的數(shù)據(jù)庫方言提供了基于SQL的后端的支持。所以我們編寫并開源了一個ClickHouse方言,并集成到Superset。

Superset為我們提供了特別的可視化服務,但是對于我們的監(jiān)控用例來說,它仍然不夠完善。在Cloudflare,我們大量使用Grafana來可視化所有指標,所以我們將它與Grafana集成并進行開源。

ia_12300000005.jpg

它使我們能夠用新的分析數(shù)據(jù)無縫地擴展我們現(xiàn)有的監(jiān)測儀表板。我們非常喜歡這個功能,因此我們希望能夠為用戶提供同樣的能力來查看分析數(shù)據(jù)。因此,我們構建了一個Grafana應用程序,以便可視化來自Cloudflare DNS Analytics的數(shù)據(jù)。最后,我們在您的Cloudflare儀表板分析中提供了它。隨著時間的推移,我們將添加新的數(shù)據(jù)源,維度和其他有用的方法來顯示Cloudflare中的數(shù)據(jù)。

版權聲明:本文為博主原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/weixin_34262482/article/details/86718219

立即登錄,閱讀全文
版權說明:
本文內容來自于CSDN,本站不擁有所有權,不承擔相關法律責任。文章內容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權,請聯(lián)系管理員(zzx@kchuhai.com)刪除!
掃碼登錄
打開掃一掃, 關注公眾號后即可登錄/注冊
加載中
二維碼已失效 請重試
刷新
賬號登錄/注冊
個人VIP
小程序
快出海小程序
公眾號
快出海公眾號
商務合作
商務合作
投稿采訪
投稿采訪
出海管家
出海管家