使用ElasticSearch进行近实时索引
選擇索引策略很困難。 Elasticsearch 文檔的確有一些一般性建議 ,并且有其他公司的 一些技巧 ,但這也取決于特定的用例。 在典型情況下,您有一個數據庫作為事實的來源,并且有一個使事物可搜索的索引。 您可以采用以下策略:
- 隨著數據的到來而建立索引–您可以同時插入數據庫并建立索引。 如果沒有太多數據,這是有道理的。 否則索引將變得非常低效。
- 存儲在數據庫中,并與計劃的作業一起建立索引–這可能是最常見的方法,并且易于實現。 但是,如果要索引的數據很多,則可能會出現問題,因為必須使用數據庫中的(從,到)條件來精確地獲取該數據,并且索引落后于實際數據的秒數(或分鐘)在計劃的作業運行之間
- 推送到消息隊列并編寫索引使用方–您可以運行RabbitMQ之類的東西,并讓多個使用方輪詢數據并為其編制索引。 這不是容易實現的,因為您必須輪詢多個項目才能利用批處理索引,然后僅在成功執行批處理時將它們標記為已使用-有點交易行為。
- 對內存中的項目進行排隊并定期對其進行刷新–這可能是好的且高效的,但是如果節點死亡,則可能會丟失數據,因此您必須根據數據庫中的數據進行某種運行狀況檢查
- 混合-結合以上內容; 例如,如果需要在以后充實原始數據并更新索引,則可以在內存中對項目進行排隊,然后使用“存儲在數據庫中,具有計劃作業的索引”來更新索引并填寫任何缺失的項目。 或者,您可以在數據的某些部分出現時建立索引,并對更活躍的數據類型使用另一種策略
我們最近決定實施“內存中隊列”方法(與另一方法結合使用,因為無論如何我們都必須進行一些計劃的后處理)。 最初的嘗試是使用Elasticsearch客戶端提供的類BulkProcessor 。 邏輯很清晰–如果達到一定限制或以固定的時間間隔,將索引請求存儲在內存中并批量將其刷新到Elasticsearch。 因此,最多每隔X秒,最多每隔Y個記錄將有一個批處理索引請求。 這樣就可以實現近實時索引,而不會給Elasticsearch帶來太大的壓力。 根據Elasticsearch的建議,它還允許同時多個批量索引請求。
但是,我們使用了BulkProcessor不支持的REST API(通過Jest )。 我們試圖堵塞,而不是當前的本地一個REST索引邏輯,雖然它幾乎工作,在這個過程中,我們發現了一些令人擔憂-在internalAdd方法,該方法被調用每一個索引請求加入到大宗時間,是synchronized 。 這意味著線程將阻塞,等待彼此添加內容。 對于生產環境來說,這聽起來不太理想且有風險,因此我們進行了單獨的實施。 可以在這里看到– ESBulkProcessor 。
它允許多個線程同時刷新到Elasticsearch,但是只有一個線程(使用鎖)要從隊列中使用以形成批處理。 由于這是一項快速的操作,因此最好對其進行序列化。 并不是因為并發隊列無法處理從中讀取的多個線程,而是可以; 但是達到同時由多個線程形成批量的條件將導致幾個小批量而不是一個大批量,因此一次只需要一個消費者。 這不是一個大問題,因此可以將其刪除。 但重要的是要注意它沒有阻塞。
這已經生產了一段時間了,似乎沒有任何問題。 如果由于負載增加或邊緣情況而發生更改,我將報告任何更改。
如果這是唯一的索引邏輯,則必須重申該問題–您的應用程序節點可能會失敗,并且最終可能會導致Elasticsearch中的數據丟失。 我們不在那種情況下,我不確定哪種方法是最好的補救方法–是在服務器發生故障的情況下對近期數據進行部分重新索引,或者通過批處理檢查是否沒有數據庫和索引之間不匹配。 當然,我們還應該說您可能并不總是擁有一個數據庫–有時,Elasticsearch就是您用于數據存儲的全部,在這種情況下,需要某種隊列持久性。
最終目標是實現近乎實時的索引編制,因為用戶期望盡快看到他們的數據,同時又不影響Elasticsearch集群。
“什么是對數據建立索引的最佳方法”這一主題非常重要,我希望至少已經澄清了一點,并且我們的貢獻對于其他情況也很有意義。
翻譯自: https://www.javacodegeeks.com/2019/12/near-real-time-indexing-with-elasticsearch.html
總結
以上是生活随笔為你收集整理的使用ElasticSearch进行近实时索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓手机如何投屏到电脑上安卓如何投屏至电
- 下一篇: 2021年高性价比平板电脑推荐2021年