如何使用 AWS OpenSearch 每天處理 4000 萬(wàn)份文檔
語(yǔ)境
這個(gè)故事是關(guān)于一個(gè)托管在 AWS 上的 IoT 項(xiàng)目,該項(xiàng)目接收某些設(shè)備生成的數(shù)據(jù)。
該系統(tǒng)是一個(gè)分布式架構(gòu),在攝取階段之后,原始數(shù)據(jù)通過(guò)Amazon Kinesis Data Stream傳遞。
該流是一系列服務(wù)的來(lái)源,每個(gè)服務(wù)負(fù)責(zé)我們需要對(duì)數(shù)據(jù)執(zhí)行的不同處理。
Kinesis 是系統(tǒng)的關(guān)鍵點(diǎn),因?yàn)樗试S每個(gè)使用者讀取事件并以其速度處理它們,使每個(gè)處理管道獨(dú)立于其他處理管道。Kinesis 還可以吸收所有流量峰值,并允許在一個(gè)或多個(gè)處理管道因任何原因暫時(shí)禁用時(shí)繼續(xù)攝取。
Kinesis Data Stream 是所有處理管道的來(lái)源
交叉檢查的需要
在項(xiàng)目的發(fā)展過(guò)程中,驗(yàn)證對(duì)數(shù)據(jù)流執(zhí)行的處理變得很重要。我們的想法是找到一種方法來(lái)保存原始數(shù)據(jù),以便可以交叉檢查結(jié)果、快速排除故障并驗(yàn)證處理。
當(dāng)數(shù)據(jù)量巨大時(shí),您不能簡(jiǎn)單地將其保存在關(guān)系數(shù)據(jù)庫(kù)中并以當(dāng)前和未來(lái)所有可能的方式查詢它。但 OpenSearch(當(dāng)然還有ElasticSearch)可以做得很好,而且也是查詢和過(guò)濾數(shù)據(jù)、進(jìn)行高級(jí)聚合以及可視化結(jié)果的絕佳工具,幾乎在幾秒鐘內(nèi)完成,而無(wú)需進(jìn)行初步數(shù)據(jù)準(zhǔn)備。
因此,我們添加了一種嗅探器組件,在快速豐富/反規(guī)范化過(guò)程之后,它開(kāi)始使用 Kinesis 中的事件并將它們保存到 OpenSearch 中。
結(jié)果是包含來(lái)自所有設(shè)備的所有數(shù)據(jù)的索引,事實(shí)證明 OpenSearch 是滿足我們的故障排除需求的絕佳工具。
數(shù)據(jù)“嗅探”以對(duì)處理后的數(shù)據(jù)進(jìn)行交叉檢查
性能和成本考慮
OpenSearch 對(duì)于大數(shù)據(jù)量非常有用,但在我們的場(chǎng)景中,每個(gè)文檔約為 2KB,每天必須存儲(chǔ) 4000 萬(wàn)個(gè)文檔。
我們開(kāi)始使用每日指數(shù)。從性能角度來(lái)看,OpenSearch 運(yùn)行得非常好,但每個(gè)索引大約為22 GB ,這意味著每年大約8 TB的數(shù)據(jù)。對(duì)于一個(gè)服務(wù)來(lái)說(shuō)有點(diǎn)太多了,畢竟嚴(yán)格來(lái)說(shuō)它不是系統(tǒng)的一部分,而是類似于“數(shù)據(jù)觀察工具”的東西。
成本很快就開(kāi)始太高,我們看到的第一個(gè)選擇是刪除舊數(shù)據(jù)并僅保留尾部,例如最近兩三個(gè)月的數(shù)據(jù)。
這肯定是一個(gè)選擇,但有時(shí)對(duì)長(zhǎng)期數(shù)據(jù)執(zhí)行查詢可能會(huì)很有趣,例如僅來(lái)自單個(gè)設(shè)備的數(shù)據(jù),但在很長(zhǎng)一段時(shí)間內(nèi),例如一年,甚至更長(zhǎng)。
更好的替代方案是找到一種方法來(lái)聚合數(shù)據(jù),減少數(shù)據(jù)大小,從而通過(guò)支付類似的成本來(lái)保留更多數(shù)據(jù)。
匯總職位
更干凈的方法似乎是使用Index rollups,該功能通過(guò)以完全透明的方式進(jìn)行指標(biāo)聚合來(lái)自動(dòng)降低數(shù)據(jù)粒度。
經(jīng)過(guò)一些測(cè)試,我們注意到我們的數(shù)據(jù)存在一些錯(cuò)誤。可能與我們數(shù)據(jù)中的某些問(wèn)題有關(guān),或者可能是因?yàn)?OpenSearch 相對(duì)較年輕而存在錯(cuò)誤。我們沒(méi)有發(fā)現(xiàn)這些失敗背后的原因,我們沒(méi)有有用的日志,也沒(méi)有時(shí)間花在調(diào)查上。
除此之外,該解決方案在聚合類型方面受到限制,因?yàn)閰R總作業(yè)只能執(zhí)行All、Min、Max、Sum、Avg和Value Count。
在我們的場(chǎng)景中,它對(duì)我們?cè)诰酆线壿嫹矫鎿碛懈嘧杂煽赡芎苡杏?,例如,收集指?biāo)的分布。
因此我們探索了使用索引變換的選項(xiàng),通過(guò)這個(gè)功能我們終于達(dá)到了我們的目標(biāo)。,
轉(zhuǎn)變工作
該解決方案基于針對(duì)不同需求擁有兩組不同數(shù)據(jù)的想法:
· 未壓縮原始數(shù)據(jù)的滑動(dòng)窗口(在我們的例子中配置為最近 2 個(gè)月)
·
一組歷史壓縮數(shù)據(jù)
(盡可能久遠(yuǎn)地進(jìn)入過(guò)去)
時(shí)間線和兩個(gè)數(shù)據(jù)集
很快,該解決方案的工作原理如下:
· EventBridge規(guī)則計(jì)劃每天執(zhí)行并啟動(dòng) Lambda 函數(shù)
· lambda 創(chuàng)建每月索引及其壓縮數(shù)據(jù)的映射(在 OpenSearch 中這些操作是冪等的)
· lambda 刪除早于配置的滑動(dòng)窗口的未壓縮數(shù)據(jù)的每日索引(在我們的例子中,這意味著在執(zhí)行時(shí)間之前刪除第 61 個(gè)每日索引)
· lambda 創(chuàng)建每日轉(zhuǎn)換作業(yè),以便立即執(zhí)行
· 執(zhí)行轉(zhuǎn)換作業(yè),并處理前一天的數(shù)據(jù)
· 每個(gè)設(shè)備的數(shù)據(jù)以 1 小時(shí)為單位進(jìn)行聚合
· 一些指標(biāo)是使用可用的標(biāo)準(zhǔn)聚合(min、max、average等)進(jìn)行聚合的
· 其他指標(biāo)使用自定義scripted_metric 聚合進(jìn)行處理,并利用映射/組合/減少腳本的靈活性,在我們的示例中,數(shù)據(jù)被縮減為自定義分布報(bào)告
優(yōu)點(diǎn)和缺點(diǎn)
根據(jù)我們需要進(jìn)行的調(diào)查,我們可以決定是使用最新的原始數(shù)據(jù)還是使用歷史壓縮數(shù)據(jù)更好。
例如,如果需要檢查特定設(shè)備上周到底發(fā)送了什么,我們可以使用未壓縮原始數(shù)據(jù)的每日索引。
相反,如果需要研究去年的趨勢(shì),則壓縮的月度指數(shù)是正確的數(shù)據(jù)源。
該解決方案的一個(gè)缺點(diǎn)是,當(dāng)我們開(kāi)始進(jìn)行可視化時(shí),我們必須提前決定要使用兩個(gè)數(shù)據(jù)源中的哪一個(gè)。架構(gòu)不同,因此在每日索引上創(chuàng)建的可視化效果不適用于每月索引,反之亦然。
這實(shí)際上并不是一個(gè)主要問(wèn)題,因?yàn)橥ǔD芮宄裁磥?lái)源最適合特定需求。無(wú)論如何,從這個(gè)角度來(lái)看,索引匯總功能肯定更好,因?yàn)樗饕窍嗤?,并且您不必處理這個(gè)雙數(shù)據(jù)源。
一些快速計(jì)算
每日原始數(shù)據(jù)未壓縮索引
· 每個(gè) JSON 文檔大約 1.6 KB
· 每個(gè)索引平均包含 4000 萬(wàn)個(gè)文檔
· 每日索引大小平均為23 GB
· 1個(gè)月數(shù)據(jù)量約700GB
每月匯總指數(shù)
· 每個(gè) JSON 文檔大約 2.2 KB
· 每個(gè)索引平均包含 1500 萬(wàn)個(gè)文檔
· 索引每月大小平均為6 GB
最后的考慮因素
很容易看出,最終的壓縮比大約為100:1。
這意味著,即使為 1 個(gè)副本配置歷史索引并將其大小加倍,處理一個(gè)月原始數(shù)據(jù)所需的磁盤(pán)空間也允許我們存儲(chǔ)超過(guò)4 年的聚合數(shù)據(jù)。
除此之外,OpenSearch 查詢聚合索引的速度要快得多。
在實(shí)施此解決方案之前,我們已經(jīng)存儲(chǔ)了 1 年的原始數(shù)據(jù),但由于性能問(wèn)題,我們不得不將 OpenSearch 集群擴(kuò)展到 6 個(gè)節(jié)點(diǎn)。這產(chǎn)生了相當(dāng)大的計(jì)算和存儲(chǔ)資源成本。
借助這一自動(dòng)進(jìn)行數(shù)據(jù)聚合的無(wú)服務(wù)器解決方案,我們能夠?qū)?strong>集群大小減少到只有 3 個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)的存儲(chǔ)空間更小。
換句話說(shuō),在數(shù)據(jù)丟失量較小且可接受的情況下,今天我們花費(fèi)更少的錢(qián),同時(shí)我們有能力保留所有歷史數(shù)據(jù)。