理解 ElasticSearch 的工作原理需要從索引、搜索、以及其背后的核心機制幾個方面來探討。
1. ElasticSearch 是什么?
ElasticSearch 是一個分布式搜索和分析引擎,適用于各種類型的數據,例如文本、數值、地理位置、結構化或非結構化數據。它基于 Apache Lucene 構建,提供高效的全文本搜索能力。
2. 數據的寫入與索引
(1) 數據寫入
- 文檔存儲: 數據以 JSON 格式的文檔寫入。
- 索引:
- 文檔屬于一個索引(類似于數據庫中的表)。
- 每個文檔由一個唯一的
_id
標識。
- 分片機制:
- 一個索引被劃分為多個分片(shards),每個分片可以分布在不同的節點上。
- 分片提供了水平擴展能力。
- 每個分片有主副本和副本分片,提供數據高可用性。
(2) 倒排索引
倒排索引是 ElasticSearch 的核心結構,用于快速查找包含某個詞的所有文檔:
- 文檔的每個字段被分詞器(Analyzer)拆分成單個的詞條(terms)。
- 構建詞條到文檔的映射。
- 例如:
- 文檔 1:
ElasticSearch is fast.
- 文檔 2:
Fast search with ElasticSearch.
- 倒排索引:
fast -> [1, 2] ElasticSearch -> [1, 2] search -> [2]
- 文檔 1:
3. 數據寫入流程
- 寫入內存緩沖區和事務日志(Translog):
- 數據先寫入內存中的緩沖區,同時寫入磁盤上的事務日志,用于故障恢復。
- 段(Segment)生成:
- 定期(默認 1 秒)刷新(refresh),將緩沖區的數據寫入段文件(不可變)。
- 每個段中包含倒排索引。
- 段合并:
- 為了減少小段的開銷,ElasticSearch 會定期合并小段為大段,釋放舊段占用的資源。
4. 數據的搜索
搜索使用分布式處理,流程如下:
- 路由到分片:
- 請求被路由到對應的分片(主分片或副本分片)。
- 分片內查詢:
- 每個分片查詢其本地的倒排索引,返回匹配結果。
- 合并結果:
- 主節點從各分片匯總結果,根據相關性或排序規則生成最終結果。
5. 核心特性
(1) 近實時搜索(NRT)
- 數據寫入后并非立即可搜索,而需要等待刷新。
- 刷新間隔(默認 1 秒)可通過
refresh_interval
配置。
(2) 分布式架構
- 分片與副本分布在不同節點,提供高可用性和擴展性。
(3) 分析功能
- ElasticSearch 不僅用于搜索,還支持聚合(aggregation)分析。
6. 優化與實踐
- 調整分片數: 根據數據規模和集群節點調整分片數。
- 調整刷新間隔: 根據業務需求調整
refresh_interval
。 - 使用批量操作: 批量寫入(bulk API)提高寫入效率。
- 設置合適的映射(Mapping): 為字段指定類型、分詞器,提升搜索性能。
通過這些機制和優化,ElasticSearch 能快速索引和搜索海量數據,適應各種業務場景需求。