天天看點

全文搜尋之 Elasticsearch 初步介紹(1)

概述

Elasticsearch (ES)是一個基于 Lucene 的開源搜尋引擎,它不但穩定、可靠、快速,而且也具有良好的水準擴充能力,是專門為分布式環境設計的。

特性

安裝友善:沒有其他依賴,下載下傳後安裝非常友善;隻用修改幾個參數就可以搭建起來一個叢集

JSON:輸入/輸出格式為 JSON,意味着不需要定義 Schema,快捷友善

RESTful:基本所有操作(索引、查詢、甚至是配置)都可以通過 HTTP 接口進行

分布式:節點對外表現對等(每個節點都可以用來做入口);加入節點自動均衡

多租戶:可根據不同的用途分索引;可以同時操作多個索引

叢集

其中一個節點就是一個 ES 程序,多個節點組成一個叢集。一般每個節點都運作在不同的作業系統上,配置好叢集相關參數後 ES 會自動組成叢集(節點發現方式也可以配置)。叢集内部通過 ES 的選主算法選出主節點(目前版本 1.2 存在腦裂問題),而叢集外部則是可以通過任何節點進行操作,無主從節點之分(對外表現對等/去中心化,有利于用戶端程式設計,例如故障重連)。

索引
“索引”有兩個意思:
  • 作為動詞,它指的是把一個文檔“儲存”到 ES 中的過程,索引一個文檔後,我們就可以使用 ES 搜尋到這個文檔
  • 作為名詞,它是指儲存文檔的地方,相當于一個資料庫概念中的“庫”

    為了友善了解,我們可以将 ES 中的一些概念對應到我們熟悉的關系型資料庫上:

| ES | 索引| 類型| 文檔 |

|DB | 庫 | 表 | 行 |

分片

ES 是一個分布式系統,我們一開始就應該以叢集的方式來使用它。它儲存索引時會選擇适合的“主分片”(Primary Shard),把索引儲存到其中(我們可以把分片了解為一塊實體存儲區域)。分片的分法是固定的,而且是安裝時候就必須要決定好的(預設是 5),後面就不能改變了。

既然有主分片,那肯定是有“從”分片的,在 ES 裡稱之為“副本分片”(Replica Shard)。副本分片主要有兩個作用:

高可用:某分片節點挂了的話可走其他副本分片節點,節點恢複後上面的分片資料可通過其他節點恢複

負載均衡:ES 會自動根據負載情況控制搜尋路由,副本分片可以将負載均攤

多租戶

ES 的多租戶簡單的說就是通過多索引機制同時提供給多種業務使用,每種業務使用一個索引(關于多租戶的詳細定義與用途,可以參考這裡)。前面我們提到過可以把索引了解為關系型資料庫裡的庫,那多索引可以了解為一個資料庫系統建立多個庫給不同的業務使用。

在實際使用時,我們可以通過每個租戶一個索引的方式将他們的資料進行隔離,并且每個索引是可以單獨配置參數的(可對特定租戶進行調優),這在典型的多租戶場景下非常有用:例如我們的一個多租戶應用需要提供搜尋支援,這時可以通過 ES 根據租戶建立索引,這樣每個租戶就可以在自己的索引下搜尋相關内容了。

RESTful

這個特性非常友善,最關鍵的是 ES 的 HTTP 接口不隻是可以進行業務操作(索引/搜尋),還可以進行配置,甚至是關閉 ES 叢集。下面我們介紹幾個很常用的接口:

/_cat/nodes?v:查叢集狀态

/_cat/shards?v:檢視分片狀态

/ index/ {type}/_search:搜尋

v 是 verbose 的意思,這樣可以更可讀(有表頭,有對齊),_cat 是監測相關的 APIs,/_cat?help 來擷取所有接口。 index和 {type} 分别是具體的某一索引某一類型,是分層次的。我們也可以直接在所有索引所有類型上進行搜尋:/_search。

官方術語表

最後,來份官方的術語表翻譯,鞏固一下了解:

analysis 分析

分析是将文本(text)轉化為查詢詞(term)的過程。使用不同的分析器,這三種短語:FOO BAR,Foo-Bar,foo,bar 都有可能被分解成查詢詞 foo 與 bar。這些查詢詞實際上将被存儲在索引中。一次對 FoO:bAR 的全文查詢(不是查詢詞查詢)可能會被分析為為查詢詞 foo,bar,可以比對上儲存在索引中的查詢詞。這就是分析處理過程(包含了索引與搜尋),它使得 es 可以進行全文查詢。

cluster 叢集

一個或多個擁有同一個叢集名稱的節點組成了一個叢集。每個叢集都會自動選出一個主節點,如果該主節點故障,則叢集會自動選出新的主節點來替換故障節點。

document 文檔

一個文檔就是一個儲存在 es 中的 JSON 文本,可以把它了解為關系型資料庫表中的一行。每個文檔都是儲存在索引中的,擁有一種類型和 id。一個文檔是一個 JSON 對象(一些語言中的 hash / hashmap / associative array)包含了 0 或多個字段(鍵值對)。原始的 JSON 文本在索引後将被儲存在 _source 字段裡,搜尋完成後傳回值中預設是包含該字段的。

id

Id 是用于辨別文檔的,一個文檔的索引/類型/id 必須是唯一的。文檔 id 是自動生成的(如果不指定)。

field 字段

一個文檔包含了若幹字段,或稱之為鍵值對。字段的值可以是簡單(标量)值(例如字元串、整型、日期),也可以是嵌套結構,例如數組或對象。一個字段類似于關系型資料庫表中的一列。每個字段的映射都有一個字段類型(不要和文檔類型搞混了),它描述了這個字段可以儲存的值類型,例如整型、字元串、對象。映射還可以讓我們定義一個字段的值如何進行分析。

index 索引

一個索引類似關系型資料庫中的一個資料庫,它可以映射為多種類型。一個索引就是邏輯上的一個命名空間,對應到 1 或多個主分片上,可以擁有 0 個或多個副本分片。

mapping 映射

一個映射類似于關系型資料庫中的模式定義。每個索引都存在一個映射,它定義了該索引中的每一種類型,以及索引相關的配置。映射可以顯示定義,或者在文檔被索引時自動建立。

node 節點

一個節點是叢集中的一個 es 運作執行個體。測試時,多個節點可以同時啟在同一個伺服器上,生産環境一般是一個伺服器上一個節點。節點啟動時将使用單點傳播(或者是多點傳播)來發現和自己配置的叢集名稱相同的叢集,并嘗試加入到該叢集中。

primary shard 主分片

每個文檔都會被儲存在一個主分片上。當我們索引一個文檔時,它将在一個主分片上進行索引,然後才放到該主分片的各副本分片上。預設情況下,一個索引有 5 個主分片。我們可以指定更少或更多的主分片來伸縮索引可處理的文檔數。需要注意的是,一旦索引建立,就不能修改主分片個數。

replica shard 副本分片

每個主分片可以擁有 0 個或多個副本分片。一個副本分片是主分片的一份拷貝,這樣做有兩個主要原因:

故障轉移:當主分片失效時,一個副本分片會被提升為主分片

提高性能:擷取與搜尋請求可以被主分片或副本分片處理。預設情況下,每個主分片都有一個副本分片,副本分片的數量可以動态調整。在同一個節點上,副本分片和其主分片不會同時運作

routing 路由

當我們索引一個文檔時,它将被儲存在一個主分片上,分片的選擇是通過路由值哈希得到的。預設情況下,路由值來自于文檔 id,如果該文檔指定來了父文檔,則路由值來自于父文檔 id(這是為了確定子文檔和父文檔被儲存在相同的分片上)。該值可以在索引時指定,也可以通過映射路由字段來指定。

shard 分片

一個分片就是一個 Lucene 執行個體,它是 es 管理的底層“工作單元”。一個索引是邏輯上的一個命名空間,指向主分片和副本分片。索引的主分片和副本分片數量必須明确指定好,在應用代碼使用時隻需要處理和索引的互動,不會涉及到和分片的互動。Elasticsearch 會在叢集中的所有節點上設定好分片,但節點失效或加入新節點時會自動将移動節點分片。

source field 源字段

預設情況下,在擷取和搜尋請求傳回值中的 _source 字段儲存了源 JSON 文本,這使得我們可以直接在傳回結果中通路源資料,而不需要根據 id 再發一次檢索請求。注意:索引的 JSON 字元串将完整傳回,無論是否是一個合法的 JSON。該字段的内容也不會描述資料如何被索引。

term 查詢詞

一個查詢詞是一個被 es 索引的确切值。查詢詞 foo,Foo,FOO 是不同的。查詢詞可以使用查詢詞查詢接口進行擷取。

text 文本

文本(或稱之為全文)是普通的、非結構化的文本,例如本段話。預設情況下,文本将被分析為查詢詞,查詢詞将被儲存在索引中。為能夠進行全文搜尋,文本字段在索引時将被分析為查詢詞,查詢關鍵字在搜尋時也将被分析為查詢詞,通過對比查詢詞是否相同而完成全文搜尋。

type 類型

一種類型類似于關系型資料庫中的一張表。每種類型都有若幹字段,可以用于指定給該類型文檔。映射定義了該文檔中的每個字段如何進行分析。

繼續閱讀