1. 程式人生 > 資料庫 >Elasticsearch與關係性資料庫的界限

Elasticsearch與關係性資料庫的界限

轉自:銘毅天下

  1. 引言

    現在幾乎網上所有資料都說資料儲存在傳統資料庫,再在 es 中同步一份資料作為檢索使用,但是也都沒有很詳細的說明為什麼要這麼做,而且在 es 本身可以儲存資料的情況下,儲存兩份資料是不是沒有必要?還會引起別的問題。

    雖然收費而且支援的語法不完全,但是在現在 es 已經支援 sql 的情況下,我越來越搞不清楚 es 和資料庫之間的界限。

    es 不支援事務但是能夠確保單條資料的寫入,這樣事務可以通過程式碼實現。很難進行聯合查詢可以像其他 nosql 一樣用寬表實現。實時性可以通過配置調整,而在擴充套件效能和複雜統計上肯定 es 更優。

    基於以上疑問,請問現階段 es 與資料庫的區別或者說界限到底在哪?

    ——來自社群的提問

    其實拿傳統關係型資料庫和 Elasticsearch 直接來對比有些牽強,畢竟一個是資料庫,一個是搜尋引擎。

    如果硬要對比,我們剝繭抽絲,一點點探究一下 Elasticsearch 與傳統資料庫的不同。

     

  2. 使命不同

    Oracle 對關係型資料庫的定義:

    關係型資料庫,是指採用了關係模型來組織資料的資料庫,其以行和列的形式儲存資料,以便於使用者理解,關係型資料庫這一系列的行(包含唯一 key 的記錄)和列(儲存了屬性)被稱為表,一組表組成了資料庫。

    Elasticsearch 的官方定義:

    Elasticsearch 是一個分散式的開源搜尋和分析引擎,適用於所有型別的資料,包括文字、數字、地理空間、結構化和非結構化資料。Elasticsearch 在 Apache Lucene 的基礎上開發而成,由 Elasticsearch N.V.(即現在的 Elastic)於 2010 年首次釋出。Elasticsearch 以其簡單的 REST 風格 API、分散式特性、速度和可擴充套件性而聞名,是 Elastic Stack 的核心元件;Elastic Stack 是適用於資料採集、充實、儲存、分析和視覺化的一組開源工具。人們通常將 Elastic Stack 稱為 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列豐富的輕量型資料採集代理,這些代理統稱為 Beats,可用來向 Elasticsearch 傳送資料。

    A relational database can store data and also index it.

    A search engine can index data but also store it.

    如上可通俗解讀為:

    • 關係資料庫可以儲存資料併為其建立索引。
    • 搜尋引擎可以索引資料,但也可以儲存資料。
  3. 適用場景不同

    關係型資料庫更適合 OLTP(是一種以事務元作為資料處理的單位、人機互動的計算機應用系統,最大優點:最大優點是可以即時地處理輸入的資料,及時地回答)的業務場景;而 Elasticsearch不能當做純資料庫來使用。

    • 原因 1:不支援事務,

    • 原因 2:近實時而非準實時,由 refresh_interval 控制,最快 1s 資料寫入後可檢索。

    Elasticsearch 適合 OLAP的場景(它使分析人員能夠迅速、一致、互動地從各個方面觀察資訊,以達到深入理解資料的目的。側重分析)。

    舉例:

    • 海量日誌分析和檢索、

    • 海量大文字的全文檢索等。

  4. 儲存型別不同

    關係型資料庫一般只支援儲存結構化資料(pgsql 支援 json)。

    結構化資料的特點:

    • 由二維表結構來邏輯表達和實現的資料
    • 嚴格地遵循資料格式與長度規範。

    舉例:銀行交易資料、個人資訊資料等。

    而 Elasticsearch 支援關係型和非結構化資料,如:json 由 object 或者 nested 型別或者父子 Join 儲存。

    非結構化資料的特點:

    • 資料結構不規則或不完整;

    • 沒有預定義的資料模型,不方便用資料庫二維邏輯表來表現的資料。

    舉例:包括所有格式的辦公文件、文字、圖片、XML, HTML、各類報表、影象和音訊/視訊資訊等等。腦海中想一下:是不是實戰中遇到:資料結構不定、欄位個數不定、欄位型別不定、是否動態新增不定等多變的業務場景?
  5. 可擴充套件性不同

    關係型資料庫通病, 如:mysql 單表支援資料量有限,資料量大了就得分庫分表,再大了考慮分散式,原生分散式的瓶頸如下:

    • 分庫分表非常麻煩,
    • 業務依賴性高,
    • 複雜查詢會出現錯誤,
    • 更重要的是分散式事務無法有效處理。

    催生了很多第三方 NewSql 公司如:TIDB(開源+解決方案付費)。

    而 Elasticsearh 支援橫向擴充套件,天生支援多節點叢集部署,擴充套件能力強,甚至支援跨叢集檢索;能支援 PB+的資料。

    國內的:滴滴、攜程、順豐、今日頭條、bat 等很多核心資料業務都已經通過 Elasticsearch 實現。

  6. 解決問題不同

    關係型資料庫針對核心:增刪改查的業務場景,對於全文檢索會慢的要死(很多客戶遷移 Elasticsearch 就是這個原因,早期用 lucene 後用 solr,但發現 Elasticsearch 更好用);而 Elasticsearch 的倒排索引機制更適合全文檢索。

    實際業務中:

    • 如果資料量不大,建議使用簡單的關係資料庫結合簡單的 SQL 查詢就能解決問題。
    • 如果您對效能沒有問題,請保持架構簡單並使用單個數據庫儲存,必要時加些快取(如 redis)。
    • 如果您在搜尋中遇到效能問題,則可以將關係型資料庫和 Elasticsearch 結合使用。
  7. 資料模型不同

    關係型資料庫通常針對複雜業務會多表設計、不同表不同模型,多表通過 join 關聯或者檢視查詢。

    而 Elasticsearch 支援複雜業務資料,通常不建議多表關聯,確切說 Elasticsearch 倒排索引機制決定了它天然不適合多表關聯。複雜業務資料通常解決方案:

    • 1, 寬表(空間換時間);
    • 2, nested
    • 3, 父子關聯 join(針對頻繁更新場景)。

    對於聚合業務場景,的確大資料量(千萬級以上)多重巢狀全量聚合 es 會很慢,業務選型可以考慮其他輔助方案。

  8. 底層邏輯不同

    傳統資料庫的儲存引擎為 B+樹,包括 ES 的很多 NOSQL 資料庫使用的 LSM Tree,對寫操作支援更高效。

    為什麼 Elasticsearch/Lucene 檢索可以比 mysql 快?

    Mysq 的分詞詞典(term dictionary)是以 b-tree 排序的方式儲存在磁碟上的。檢索一個 term 需要若干次的隨機訪問磁碟操作。

    而 Lucene 在分詞詞典的基礎上添加了 term index(以 FST(finite state transducers)形式儲存,非常節省記憶體)來加速檢索,term index 以樹的形式快取在記憶體中。從 term index 查到對應的 term dictionary 的 block 位置之後,再去磁碟上找 term,大大減少了磁碟的隨機訪問次數。

  9. 小結

    所以,沒有最牛逼“一招先,吃遍天”的方案,只有最適合的方案。

    適合自己業務場景的才是最好的!

  10. 參考

           [1]  

           [2] 

[3] 

[4] 

[5]