Elasticsearch 使用誤區之將 Elasticsearch 視為關系數據庫!
Elasticsearch 是一個強大的工具,尤其在全文檢索、實時分析、機器學習、地理數據應用、日志和事件數據分析、安全信息和事件管理等場景有大量的應用。
然而,Elastic Stack 技術棧的選型及應用效能取決于正確的使用方式。選型錯誤或者誤用 Elasticsearch 可能會導致擴展性問題、性能問題(如為解決一個問題使用非常復雜的腳本導致性能極差)等,從而使整體體驗感變差。所以,本文區別于之前的正向講解的方式,更多的講解反例或者負面應用案例。“以史為鑒”,以便于大家更好地使用 Elasticsearch。
本系列文章會有 10 幾篇左右,一篇一個知識點講解 Elasticsearch 使用誤區解讀,敬請期待!
誤區1:將 Elasticsearch 視為關系數據庫
Elasticsearch 常被誤解為 MySQL 或者 PostgreSQL 等關系數據庫的直接替代品,用戶除了直接替代使用外更看其全文搜索和快速聚合的能力。
然而,咱們必須清晰的認知:Elasticsearch 設計初衷不是處理復雜事務和關系數據模型的。
我們從下面幾個維度逐一展開討論:
1、該不該選型 Elasticsearch ?
個人建議先了解 Elasticsearch 的適用場景以及不適用場景,這樣能清楚 Elastic Stack 技術棧更適合哪些業務需求。
例如,咱們文章之前圖解的六大應用場景是非常適合的。然而,對于需要處理復雜事務、多表聯查操作和高一致性要求的應用,如銀行系統的交易處理和ERP系統等,Elasticsearch 則不太適合。
圖片
Elasticsearch 更適用場景:
圖片
圖片
通過對比這些場景,反觀自己的業務需求,就能判斷是否應該選型 Elasticsearch 甚至 Elastic Stack 作為技術棧。
2、理解 Elasticsearch 的設計
圖片來自官方博客
Elasticsearch 是一種面向文檔的搜索引擎,專為快速搜索大量數據而設計。
Elasticsearch 基于 Apache Lucene 構建,提供了強大的全文搜索、分析和數據聚合功能。
以下是 Elasticsearch 的主要特點:
- 全文搜索:Elasticsearch 提供了高效的全文搜索功能,能夠快速檢索和匹配大規模文本數據。
- 分布式架構:Elasticsearch 采用分布式架構,能夠水平橫向擴展,處理海量數據(PB級甚至以上都不是問題)和高并發請求。
- 數據分析:Elasticsearch 支持復雜的聚合查詢,可以做多維度的快速統計和分析數據,但聚合、去重等結果不是精準的。有精準需求的企業場景也要評估和掂量一下。
- ......
圖片來自官方博客
如前所述,Elasticsearch 并不是設計用來處理關系數據和事務的。它的主要優勢在于分析和搜索能力,而不是數據關系的嚴格維護。
3、理解 Elasticsearch 與關系數據庫的比較
關系數據庫(如 MySQL、Oracle 及 PostgreSQL 等)和 Elasticsearch 之間有幾個關鍵區別:
3.1 數據模型比較
- 關系數據庫使用結構化的表和行來存儲數據,并通過外鍵和約束來維護數據的一致性。
- Elasticsearch 則使用文檔(document,本質是 JSON 格式)來存儲數據,每個文檔可以包含不同的字段和數據類型。
特性 | 關系數據庫 | Elasticsearch |
數據存儲結構 | 結構化的表和行 | 文檔 |
數據類型 | 每個表的字段類型固定 | 每個文檔可以包含不同的字段和數據類型 |
數據一致性 | 通過外鍵和約束來維護數據的一致性 | 不提供數據一致性保障 |
查詢能力 | 支持復雜的 SQL 查詢、事務和聯接操作 | 主要用于全文搜索和數據聚合 |
事務支持 | 完整的事務支持 | 不支持事務 |
性能優化 | 索引、緩存和查詢優化 | 分片、索引和緩存 |
主要優勢 | 關系數據處理和數據一致性維護 | 快速搜索和高效的數據聚合 |
3.2 查詢能力比較
- 關系數據庫支持復雜的 SQL 查詢、事務和多表關聯操作,以保證數據的一致性和完整性。
- Elasticsearch 主要側重于全文搜索和數據聚合,不支持復雜的事務和多表關聯操作。
在關系數據庫中,我們可以使用復雜的 SQL 查詢、事務和多表關聯操作來保證數據的一致性和完整性。例如:
BEGIN TRANSACTION;
-- 更新訂單狀態
UPDATE orders
SET status = 'shipped'
WHERE order_id = 123;
-- 減少庫存
UPDATE products
SET stock = stock - 1
WHERE product_id = 456;
-- 記錄客戶活動
INSERT INTO customer_activity (customer_id, activity)
VALUES (789, 'Order 123 shipped');
COMMIT;
圖片
上述事務示例能確保所有相關操作(更新訂單狀態、減少庫存和記錄客戶活動)要么全部成功,要么全部失敗,從而保證數據的一致性(事務的本質)。
在 Elasticsearch 中,我們主要側重于全文搜索和數據聚合分析,而不支持復雜的事務和多表關聯操作。
比如:用戶需求如下:
“想請教下大佬們,假設 es 中 有兩個表,一個會員表,一個訂單表,如果想關聯查詢,例如查詢24年注冊的所有的會員的訂單總數,通過什么方式能快速查詢?”
咱們文章做過剖析,Elasticsearch 不是一丁點也不支持多表關聯,只是支持的力度有限,支持的形式核心有如下幾種:
- 自己業務層面實現
- Nested 嵌套數據類型
- Join 父子文檔類型
- 寬表冗余存儲
- Enrich processor 預處理方式