全球網路安全公司DataDome是如何做到每秒在Elasticsearch中儲存5000萬個事件?

banq發表於2019-10-23

DataDome是一家全球網路安全公司,提供SaaS解決方案,旨在保護客戶網站免受OWASP自動化威脅:憑據填充、第7層DDoS攻擊、SQL隱碼攻擊和密集式抓取。該解決方案通過尖端的人工智慧技術保護我們所有客戶的漏洞點(網路,移動應用和API),提供實時的自動程式檢測和自動阻止決策。

DataDome解決方案使用Apache Flink進行實時事件分析以檢測新威脅,並使用Elasticsearch儲存來自所有客戶訪問者的請求。我們從客戶的Web伺服器接收這些請求,並使用它們在使用者儀表板中提供漫遊器流量統計資訊,反饋迴圈,業務洞察力和漫遊器攻擊詳細資訊。

幾個數字:我們的叢集儲存了超過150 TB的資料,600億個文件中的15萬億個事件,分佈在80個節點上的3000個索引和1.5萬個分片。每個文件在單獨的欄位中儲存250個事件。

每天,在高峰期間,我們的Elasticsearch叢集每秒寫入超過20萬個文件,搜尋速度每秒超過2萬個請求。我們的索引是基於每天的,並且每個客戶都有一個索引,以便對資料進行邏輯分離。

分片策略挑戰

一年前,我們的叢集由30個專用伺服器組成,這些伺服器被拆分為一個hot-warm架構。我們的hot層由15臺伺服器組成,這些伺服器具有20個執行緒的CPU和RAID0中的5個SSD磁碟,而我們的warm層由15臺具有較低CPU的伺服器組成,以降低成本,因為對warm層內部的資料的要求較少。

我們為客戶提供長達30天的資料保留。前7天的資料儲存在熱層中,其餘的儲存在熱層中。

常見的最佳做法是將碎片大小保持在50GB左右。如上所述,我們為每個客戶都有專用的索引,但是我們所有的客戶都沒有相同的工作量。我們最大的客戶每秒寫入數萬個文件,而最小的客戶每秒寫入數百個。此外,我們必須不斷調整分片的數量以適應客戶流量的變化,以遵守每個分片50GB的最佳實踐。

為了解決此問題,我們引入了一項每天執行的作業,以更新對映模板並建立明天的索引,並根據客戶在前一天獲得的點選次數為您分配合適的分片數量。因為我們知道一個索引的文件重約1000個位元組,所以我們可以預測每個索引需要的分片數量,以便遵守每個分片50 GB的最佳實踐。

如果我們將文件放在不存在的索引中,則文件將觸發索引的建立。但是,由於我們設計了基於每日的索引,這可能給我們的叢集帶來一些麻煩(黃色狀態,未分配的分片……),因為我們有很多吞吐量,並且主節點需要在同一時間(午夜左右)將分片分配給從節點。

但是,由於我們的工作特點,我們可以提前(一天之前)建立索引並避免這些問題。

通過這種分片策略,我們為最大的客戶提供了將近72個分片,為較小的客戶提供了僅1個分片。

隨著使用我們解決方案的新客戶的不斷湧入,我們的叢集變得分崩離析,並且在讀取和寫入方面,效能都下降了。我們還看到資料節點上的平均負載顯著增加。

因此,我們對一些搜尋和寫入請求進行了基準測試,發現我們的分片在一天中增長得越多,我們的搜尋和寫入效能下降的幅度就越大。在傍晚,當我們的流量激增並且碎片比早上更大時,我們的Elasticsearch效能特別差。 

每當節點發生故障併發生故障時,我們的叢集就會遭受損失,因為重新定位一個大索引(72個50GB的分片)在寫入執行緒,io磁碟,CPU和頻寬上的開銷很大,尤其是在寫入期間。

我們的基準測試表明,考慮到我們的用例,文件大小,流量,索引對映和節點型別,對於我們來說,理想的分片大小約為20GB。超過此大小,效能(讀取和寫入)均開始下降。

那麼我們如何將碎片保持在20GB左右呢? 

  • 通過向索引新增更多分片,並使叢集更加分片?當然不是! 
  • 通過使用rollover

我們如何解決分片策略挑戰

多虧了rollover,我們將分片數量減少了三倍,還減少了節點上的負載和CPU消耗。rollover允許我們在寫入期間同時使用更少的分片(即減少平均負載和CPU使用率)。現在,最大索引在每個熱節點上最多有一個分片(因此總共有15個),而中小型索引可以根據其工作負載使用1到6個分片。

rollover還通過更有效地使用快取來幫助優化我們的讀取效能,因為對索引的每次寫入都會使整個快取無效。

此外,當節點崩潰且大量分片重定位時,我們會感到更自在,因為較小的分片意味著更少的恢復時間,更少的頻寬和更少的資源消耗。

您可以在此處找到rollover的官方文件:https : //www.elastic.co/guide/zh-cn/elasticsearch/reference/current/indices-rollover-index.html

簡而言之,rollover由別名alias 組成,該別名同時接收讀和寫請求。在別名的後面,我們有一個或多個索引。讀請求轉發到所有索引,而寫請求僅轉發到標誌“ is_write_index”設定為true的索引。 

最後但並非最不重要的一點是,我們應用了“ max_size”策略型別:每當索引達到400GB時,將觸發一個rollover並建立新索引。

全球網路安全公司DataDome是如何做到每秒在Elasticsearch中儲存5000萬個事件?

如您所見,寫入“ index_10_2019-01-01-000002”不會使“ index_10_2019-01-01-000001”的快取無效。而且,我們的索引比我們的碎片小。

結果,我們的分片不超過20GB,並且我們降低了平均負載並優化了讀寫效能。

熱點挑戰

這樣,我們是否能夠設計出完美的叢集?不幸的是沒有。

在幾周內我們的群集執行良好之後,一個熱節點發生故障後,它變得不穩定,我們將其恢復並放回群集中。 

發生了什麼? 

在將節點恢復到群集中的狀態後幾個小時,許多索引觸發了一個rollover,所有新的分片都到達了該節點。我們得到了一個不平衡的群集,其中只有一個節點接收幾乎所有的寫入流量。

為什麼? 

因為預設情況下,Elasticsearch會注意平衡同一層中每個節點的分片數量。結果,幾乎所有新碎片都被rollover了,即使是大索引中的14個碎片也是如此。

 讓我們看一個示例,該示例顯示我們的叢集如何變得不平衡。我們假設我們是2019年1月3日。我們在索引設定中設定了“副本0” –請記住,我們每天和每個客戶都有一個索引(10、20和30是我們的客戶ID)–在這種情況下平衡是完美的,因為寫入平均分佈在我們的節點上。每個節點有一個分片。

全球網路安全公司DataDome是如何做到每秒在Elasticsearch中儲存5000萬個事件?

現在,假設節點3發生故障,正如預期的那樣,所有來自節點3的碎片都移到了節點1和節點2。現在,如果節點3恢復工作並在幾秒鐘後觸發rollover會發生什麼?

全球網路安全公司DataDome是如何做到每秒在Elasticsearch中儲存5000萬個事件?

由於預設的Elasticsearch分片放置啟發法,我們現在將所有分片寫入節點3上!

如何解決呢?我們可以更改啟發式演算法https://www.elastic.co/guide/en/elasticsearch/reference/current/shards-allocation.html嗎? 

不幸的是,這對我們沒有幫助。就像我說的那樣,預設情況下,Elasticsearch嘗試平衡每個節點的分片數量。更改此設定可以幫助我們平衡每個索引和每個節點的分片數量,而不是每個節點的分片數量,但這隻會對每個節點具有一個分片的大索引有所幫助。對於其餘索引(其碎片數少於熱節點)(例如10個碎片),此設定不會阻止Elasticsearch僅將所有碎片放在前十個節點上。

即使我們嘗試按索引和按節點而不是僅按節點散佈碎片,我們也會發現叢集不平衡的情況。

在這裡,一種解決方案可以是將分片的數量設定為等於節點的數量,但是如上所述,分片具有成本。

我們如何解決熱點問題

在2019年4月,Elasticsearch釋出了7.0版,其中引入了一個新功能:索引生命週期管理(aka ILM)。 

由於有了這項新功能,我們現在可以將資料節點分為三層:hot,warm和cold。

索引生命週期管理功能的主要好處是,它使我們可以在索引翻轉後立即將碎片從hot移到warm。我們可以將熱層僅保留為寫入索引,將warm層的最後7天資料保留為只讀,將冷層的最後7天資料保留為只讀(或更多)。

因為寫操作佔我們活動的80%,所以我們希望有一個僅包含分片的熱層。這將使我們能夠保持平衡的叢集,並且我們不必擔心熱點問題。

如何設定ILM 

首先,制定策略:https : //www.elastic.co/guide/zh-CN/elasticsearch/reference/current/getting-started-index-lifecycle-management.html#ilm-gs-create-policy

接下來,將此政策連結到您的模板:https : //www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-index-lifecycle-management.html#ilm-gs-apply-policy

最後,以“ -000001”為字尾的過渡模式建立索引

讓我們為從hot節點到warm節點到熱節點的索引建立過程:

全球網路安全公司DataDome是如何做到每秒在Elasticsearch中儲存5000萬個事件?

結論

藉助rollover和索引生命週期管理功能,我們解決了Elasticsearch叢集的所有主要效能和穩定性問題。

改善監控使我們能夠更好地瞭解叢集內部正在發生的事情。

對於每個索引,無論其大小如何,我們現在都具有不超過25GB資料的碎片。具有較小的分片還可以在需要時實現更好的重新平衡和重定位。

我們避免了熱點問題,因為我們的熱層只在寫入中包含分片,並且熱,暖和冷的體系結構提高了讀取請求的快取利用率。

話雖如此,叢集仍然不是完美的。我們仍然需要:

  • 避免在warm層和cold層內部出現熱點(即使我們主要關注的是寫操作的可伸縮性) 
  • 密切監視我們的工作:建立rollover別名 
  • 在使用索引前一天建立索引。

下一個是什麼?不斷擴大規模!隨著越來越多的安全專業人員意識到對行為檢測和實時bot保護的需求,我們處理的請求量呈指數級增長。因此,我們的下一個里程碑是能夠每秒處理500.000個寫請求

點選標題見原文

相關文章