fbpx

Elasticsearch 介紹 – 基本概念篇

Elasticsearch 既是資料庫,也是搜尋引擎

Elasticsearch 不僅是一個強大的搜尋引擎,也是一個分散式資料庫。它同時具備數據搜索、數據分析、高可用和處理各類型數據的能力,多元的使用場景與豐富的開源社群,使它盤據 DB-Engines 的搜尋引擎第一名 (2022年)。本篇文章將介紹 Elasticsearch 的基本概念,讓大家從頭了解這個強大的軟體。

Elasticsearch 數據儲存類型

Elasticsearch 可以儲存結構化與非結構化等不同類型的數據。

結構化數據:

一般來說,可以整理成表單的資料就是結構化數據,它們通常具有固定欄位、固定格式與固定順序。舉個例子,若我們想要申請一張信用卡,就需要填寫結構化資料表:

姓名歐小威
性別
出生年月日98/08/18
聯絡電話02-25582656
地址台北市大同區

非結構化數據:

結構化數據以外的資料,皆可以視為非結構化數據,例如:聲音、圖片、影片等。它們缺乏可識別的架構、沒有固定的欄位及格式,無法被放入預定義的框架內。

在網路時代,非結構化資料量快速增長,有別於傳統的關聯式資料庫 (RDBMS) 如 Oracle, MS SQL 將資料轉為行列式的欄位進行儲存,Elasticsearch 是將數據以 JSON 格式儲存,因為不須預先定義格式,使用上更靈活,這也是能夠快速儲存、搜索與分析各類數據的 Elasticsearch 被廣泛使用的原因之一。

雖然 Elasticsearch 使用的術語和 SQL 不同,但本質上是差不多的,差異可參考下方術語對照表 [1]:

ElasticsearchMongoDBSQL
indexcollectiontable
documentdocumentrow
fieldfieldcolumn
Inverted indexindexindex

Elasticsearch 數據搜索方式

Elasticsearch 的搜尋方式,可以分為兩種:

  1. 全文檢索 (full-text search)
  2. 倒排索引 (Inverted index)

全文檢索

將非結構化的數據提取出來並重新組織,使其變得有一定結構,並對此結構的數據進行搜尋。因此先建立索引,再對索引進行搜尋的過程,叫做全文檢索。

舉例來說,有一筆資料如下:

id資料內容
1登入成功
2登入失敗
3異常連線

Elasticsearch 和傳統的 RDBMS 一樣,透過對 table 設定 primary key 將其設為索引,透過搜尋索引快速找到相關的資料內容。

但是,若想要針對關鍵字「登入」進行查詢,則會搜尋整個 table,因此資料量越大,效能就會越慢。因此,Elasticsearch 還使用了「倒排索引」來提升搜尋速度。

倒排索引

紀錄每個字詞出現在哪些文檔及文檔中的位置,藉由搜尋字詞,快速地定位到有包含這些字詞的文檔及其出現位置。

假設有一筆資料如下表:

id資料內容
1登入成功
2登入失敗
3異常連線

首先,我們可以對資料進行切分,至於要切分成多細,可自行規劃設定。例如:

keywordid
登入1,2
成功1
失敗2
異常3
連線3

若今天想要針對關鍵字「登入」進行查詢,可以知道 「id:1,2」內有此關鍵字。再藉由 id 找到對應的資料內容。因為不需要搜尋整張 table,因此查詢效率大大地提高。

近即時搜索 (Near Real-time, NRT)

近即時搜索是 Elasticsearch 的另一項重要特性,以往因為硬體所造成的效能瓶頸,導致每一筆新資料皆需等待 fsync 將 segment 寫入硬碟後,才能對 segment 進行檢索,從寫入到檢索往往會超過 1 分鐘。

傳統資料寫入流程如下:

  1. 一筆新資料寫入記憶體的 buffer 中
  2. 每隔一段時間,進行 commit:將 buffer 的資料寫入新的 segment
  3. 新 segment 寫入作業系統的快取區 (cache)
  4. 透過 fsync 將快取區的 segment 寫入硬碟,並清空 buffer
  5. 可對 segment 進行檢索

Elasticsearch 優化這項流程:

  1. 一筆新資料寫入記憶體的 buffer 中
  2. 每隔一段時間,buffer 的資料寫入新的 segment
  3. 新 segment 優先寫入作業系統的快取區
  4. 寫入至快取區的 segment,不須等到 commit,便可直接檢索

在 Elasticsearch 中,寫入和開啟新 segment 的過程,稱為 refresh,並且預設每 1 秒刷新一次,Elasticsearch 以此實現近即時搜索。

核心基本概念

節點 (Node)

一個 Elasticsearch node 代表在一台主機上安裝 Elasticsearch 引擎,我們也可稱其為一個 Elasticsearch instance。

節點負責的工作有:

  1. 傳遞數據
  2. 節點之間的通訊
  3. 網路 (HTTP) 的流量傳輸等

因應不同的工作任務,Elasticsearch 節點可以劃分出多個不同功能的角色 [2],常用的有:

節點角色全名說明
masterMaster-eligible node控制節點的角色,如:負責創建、刪除索引、分配分片
dataData node用於保存數據及處理數據,如:CRUD、搜尋、聚合等等
mlMachine learning node用於 machine learning,若有需要,最少設置一個

集群 (Cluster)

一般來說,集群通常都具備以下幾種特性:

  1. 高可用性 (HA)
  2. 易擴展性
  3. 負載平衡 (Load Balance)

一個 Elasticsearch 集群通常「至少」由 3 個到數個節點組成 (如下方架構圖),我們可以透過增加節點擴大集群規模,不僅可以提高整體效能、也能增加儲存空間。另外,Elasticsearch 會自動分配分片 (primary shard) 和副本 (replica shard) 至集群的各節點上,用來確保資料的安全性,也就是雞蛋不要放在同一個籃子的概念。

Elastic 集群架構

文檔 (Document)

  • Elasticsearch 最小數據單元
  • 通常以 json 格式表示
  • 資料使用 key:value 的形式
  • 可以是一條客戶數據、商品分類數據、訂單數據等。

一個 document 裡有多個 field,一個 field 為一個數據字串,document 的重要結構名詞解釋整理如下:

filed說明
_indexdocument 所屬的 index 名稱
_typedocument 類型
_iddocument ID 編號
_version版本訊息,每進行一次更新、刪除,都會增加 version 的值
_seq_no [3]sequence number 就是序列號,避免更新後的 document 被舊版本覆蓋,Elasticsearch 會藉由追蹤序列號來判斷 document 的新舊
_primary_term [3]當主分片有更動時,其值會增加
_source此 document 的原始 json 資料

索引 (Index)

  • Elasticsearch 的 index 就像是關聯式資料庫中的 database
  • index 在 Elasticsearch 中是用來儲存 document 的容器,而這些 document 數據皆具有相似結構
index 結構範例
  • index 重要結構名詞解釋整理如下 [4]:
mappings定義 document 和其 field,如何儲存和被搜尋
type: text代表以全文檢索方式搜尋
settings定義和控制所有與 index 相關的內容
number_of_shards定義主分片數量
number_of_replicas定義副本數量

類型 (Type)

⚠️ 注意:版本 7 已棄用 Mapping Type [5]

  • type 是 index 中,一個邏輯數據分類
  • 每個 index 裡,可以有一個或多個 type
  • 一個 type 下的 document,都有相同 field,例如:
    type:日常商品 type、電器商品 type、生鮮商品 type
    1. 日常商品 type:product_id, product_name, product_desc, category_id, category_name
    2. 電器商品 type:product_id, product_name, product_desc, category_id, category_name, service_period
    3. 生鮮商品 type:product_id, product_name, product_desc, category_id, category_name, eat_period

分片 (Shard)

Shard 全名為 primary shard,用於存放 index 數據。當資料量過大,單一節點無法儲存時,就需要利用 Shard 拆分資料來儲存。

舉例來說,我們有三個節點,每個節點有 500G 的硬碟空間,當資料量為 1TB 時,此時任一節點都無法承載。因此,透過切分 index 數據,使每個 Shard 皆包含一部分的 index,這樣便能將大量的資料分散並儲存在 Elasticsearch 集群的節點中,進而實現資料擴充以及效能提升。

Shard 可以實現:

  1. 在多台伺服器上分散式執行搜尋和分析等操作,以此提高性能和流量
  2. 快速橫向擴展 (scale),彈性滿足使用需求

補充:在建立 index 時,可以同時定義 primary_shard 數量,一旦設定完成並且建立 index 後,便無法再做修改。若無指定,預設的 shard 數量為 1。

副本 (Replica)

Replica 全名為 replica shard,是 shard 的副本,replica 數量可以隨時修改,預設一個 shard 最少配一個 replica (版本 7.0.0 開始,shard 和 replica 預設從 5 個改為 1 個)。

Replica 的目的有兩個:

  1. 高可用性
    是最主要的目的,防止服務器故障,造成 shard 數據丟失。為了避免一個節點掛掉實影響到整個集群運作,可以為每個 shard 建立多個 replica 確保資料安全性。shard 和 replica 絕對不會同時存在同一個 Elasticsearch 節點上,以保持高可用性,但「單節點模式」例外。
  2. 提升流量和性能
    由於查詢時會在所有的 replica shard 上執行,因此可以提高查詢效率。

參考網址


本文章由歐立威技術顧問撰寫而成,轉載請註明出處,內容若有侵權請來信告知

相關文章