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

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


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

ia_12300000001.jpg

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

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

ia_12300000002.jpg

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

關(guān)于聚合

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

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

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

ia_12300000003.jpg

由于這些原因,我們首先在zone層次上匯總?cè)罩?,這對于趨勢分析來說已經(jīng)足夠,但是對于具體原因分析來說則太過粗糙。例如,我們正在調(diào)查其中一個(gè)數(shù)據(jù)中心的流量短暫爆發(fā)。具有未聚合的數(shù)據(jù)使我們能夠?qū)栴}縮小到特定DNS查詢,然后將查詢與錯(cuò)誤配置的防火墻規(guī)則相關(guān)聯(lián)。像這樣的情況下,只有匯總?cè)罩揪陀袉栴},因?yàn)樗痪酆弦恍〔糠终埱蟆?/span>

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

ClickHouse

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

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

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

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

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

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

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

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

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

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

當(dāng)時(shí)我們只依靠Pandas和ClickHouse的HTTP接口進(jìn)行臨時(shí)分析,但是我們希望使分析和監(jiān)控更容易。因?yàn)槲覀冎繡aravel(現(xiàn)在更名為Superset),我們就把它和ClickHouse進(jìn)行了整合。

ia_12300000004.jpg

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

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

ia_12300000005.jpg

它使我們能夠用新的分析數(shù)據(jù)無縫地?cái)U(kuò)展我們現(xiàn)有的監(jiān)測儀表板。我們非常喜歡這個(gè)功能,因此我們希望能夠?yàn)橛脩籼峁┩瑯拥哪芰聿榭捶治鰯?shù)據(jù)。因此,我們構(gòu)建了一個(gè)Grafana應(yīng)用程序,以便可視化來自Cloudflare DNS Analytics的數(shù)據(jù)。最后,我們在您的Cloudflare儀表板分析中提供了它。隨著時(shí)間的推移,我們將添加新的數(shù)據(jù)源,維度和其他有用的方法來顯示Cloudflare中的數(shù)據(jù)。

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

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

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