1. 程式人生 > >Elasticsearch不支援事務及應用場景

Elasticsearch不支援事務及應用場景

1、問題

源自星球同學的提問:es如何與hive或mysql結合使用?es不支援事務有什麼好的彌補方案嗎?
2、事務的核心概念

如果一個數據庫聲稱支援事務的操作,那麼該資料庫必須要具備以下ACID四個特性:

    原子性(Atomicity)
    原子性是指事務包含的所有操作要麼全部成功,要麼全部失敗回滾,
    一致性(Consistency)
    一致性是指事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態。
    隔離性(Isolation)
    隔離性是當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離。
    永續性(Durability)
    永續性是指一個事務一旦被提交了,那麼對資料庫中的資料的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作。

為了更好地理解ACID,以銀行賬戶轉賬為例:

START TRANSACTION;
SELECT balance FROM checking WHERE customer_id = 10233276;
UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276;
UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276;
COMMIT;

    1
    2
    3
    4
    5

原子性:要麼完全提交(10233276的checking餘額減少200,savings 的餘額增加200),要麼完全回滾(兩個表的餘額都不發生變化)

一致性:這個例子的一致性體現在 200元不會因為資料庫系統執行到第3行之後,第4行之前時崩潰而不翼而飛,因為事務還沒有提交。

隔離性:允許在一個事務中的操作語句會與其他事務的語句隔離開,比如事務A執行到第3行之後,第4行之前,此時事務B去查詢checking餘額時,它仍然能夠看到在事務A中被減去的200元(賬戶錢不變),因為事務A和B是彼此隔離的。在事務A提交之前,事務B觀察不到資料的改變。

永續性:一個事務一旦commit,對資料的修改是持久的。
3、Elasticsearh不支援事務

一些支援ACID資料儲存的資料庫包括:Postgres, SQLite, Oracle, MySQL (with InnoDB), and MongoDB (4.0+),不包括Elasticsearch。

Elasticsearch的底層技術是Lucene,Lucene是追求速度而非冗餘的資訊檢索技術。Lucene具有完全不同的體系結構,可以提供極快的效能,但代價是更容易受到資料丟失的影響。

丟失資料有很多種方式,如果需要的話,你需要重新建立資料。 沒錯,Elasticsearch有一個快照/恢復功能,但是這個過程只會在資料丟失的情況下部分恢復。 除非您在其他系統對資料有額外的備份儲存,否則最新快照和中斷之間的更新將會丟失。 快照/恢復在分裂大腦的情況下也無濟於事,因為沒有用於協調每個分割槽的更新的機制。 更新將會丟失。
4、Elasticsearch支援的場景

    資料安全性場景:ElasticSearch的shard支援replication,一份資料可以儲存多份,如果某一臺機器掛掉了,資料在其他機器上還有,不用擔心丟失。
    訪問安全性場景:隨著x-pack開源,ElasticSearch支援驗證,不用擔心未授權的訪問。或者藉助第三方search-guard等。
    遷移特性:ElasticSearch支援眾多的外掛,在和其他開源系統之間匯入,匯出資料都很簡單。
    這裡寫圖片描述
    資料完整性:ElasticSearch支援儲存資料原文。

5、Elasticsearch不支援的場景

    不支援事務,如前所述。
    類似資料庫中通過外來鍵的複雜的多表關聯操作,Elasticsearch天生支援不足。
    讀寫有一定延時,寫入的資料,最快1s中能被檢索到。
    實時性的官網解讀:

    In Elasticsearch, this lightweight process of writing and opening a
    new segment is called a refresh. By default, every shard is refreshed
    automatically once every second. This is why we say that Elasticsearch
    has near real-time search: document changes are not visible to search
    immediately, but will become visible within 1 second.

預設的重新整理頻率設定是1秒,也就是說文件從Index請求到對外可見能夠被搜到,最少要1秒鐘,強制的,你的網路和CPU再快也不行。這麼做是Lucene為了提高寫操作的吞吐量而做出的延遲犧牲,當然這個設定是可以手動調整的,但是並不建議你去動它,會極大地影響搜尋效能。不同的應用對實時性的定義並不一樣,這取決於你的需求。

    ES不是關係資料庫,因此如果您的資料會受益於外來鍵等等,那麼ES不是您主要資料儲存的好選擇
    ES沒有任何內建的身份驗證或授權系統,需要藉助X-pack收費工具或者第三方search-guard,對於安全性要求高的選型考量因素之一。

6、系統設計資料庫選型考量

使用哪種產品作為資料倉庫或主資料庫儲存完全取決於具體的應用場景。

    如果資訊獲取及分析的能力是你的首要需求,那麼無疑Elasticsearch是一個好的選擇。
    如果你的資料並不頻繁的update操作,也沒有事務性操作,那麼完全可以用Elasticsearch替代其他儲存。
    實時性要求高的場景,需要結合ACID特性的資料庫和Elasticsearch結合使用。

選型核心思考問題如下:
這裡寫圖片描述
7、資料庫如何與Elasticsearch結合使用?

設計時候注意:

    建立的每個Elasticsearch索引都應該由符合ACID的資料儲存支援。
    資料庫應該是真實的最終來源,從中填充索引。
    如果異常情況發生(節點丟失,中斷或誤操作 )導致丟失了索引,您將能夠完全恢復它。
    一般的用法是另外的資料庫比如NOSQL裡面有一份,然後實時同步到ES,這樣一個用於鍵值查詢,一個用於各種其他查詢。 如果ES升級了之類的,比如資料結構變了,那麼老版本資料可以不要,直接NOSQL再匯入一份到新版本,還可以恢復。
    logstash的同步外掛如logstash_input_jdbc 不支援同步刪除操作,建議改為更新操作加標記flag,或者通過業務邏輯實現同步刪除操作。

核心操作:

    ES中只儲存檢索欄位,方便快速檢索、全文檢索。
    Mysql中儲存全部欄位,利用ACID事務特性。
    通過關聯欄位建立關聯,比如:news_id在ES和mysql中要有相同的值。
    核心資料先通過ES快速獲取Id(如news_id),再通過Mysql二次查詢。