1. 查找節(jié)點
- 主分片查找
當索引一個文檔的時候乳怎,文檔會被存儲到一個主分片中喳资。 Elasticsearch 如何知道一個文檔應該存放到哪個分片中呢?當我們創(chuàng)建文檔時缝呕,它如何決定這個文檔應當被存儲在分片 1 還是分片 2 中呢两曼?
首先這肯定不會是隨機的皂甘,否則將來要獲取文檔的時候我們就不知道從何處尋找了。實際上悼凑,這個過程是根據(jù)下面這個公式?jīng)Q定的:
shard = hash(routing) % number_of_primary_shards
routing 是一個可變值偿枕,默認是文檔的 _id ,也可以設(shè)置成一個自定義的值户辫。 routing 通過 hash 函數(shù)生成一個數(shù)字渐夸,然后這個數(shù)字再除以 number_of_primary_shards (主分片的數(shù)量)后得到 余數(shù) 。這個分布在 0 到 number_of_primary_shards-1 之間的余數(shù)寸莫,就是我們所尋求的文檔所在分片的位置捺萌。
這就解釋了為什么我們要在創(chuàng)建索引的時候就確定好主分片的數(shù)量 并且永遠不會改變這個數(shù)量:因為如果數(shù)量變化了档冬,那么所有之前路由的值都會無效膘茎,文檔也再也找不到了。
- 主副分片交互
我們可以發(fā)送請求到集群中的任一節(jié)點酷誓。 每個節(jié)點都有能力處理任意請求披坏。 每個節(jié)點都知道集群中任一文檔位置,所以可以直接將請求轉(zhuǎn)發(fā)到需要的節(jié)點上盐数。 在下面的例子中棒拂,將所有的請求發(fā)送到 Node 1 ,我們將其稱為 協(xié)調(diào)節(jié)點(coordinating node) -
新建玫氢、刪除帚屉、索引文檔
以下是在主副分片和任何副本分片上面 成功新建,索引和刪除文檔所需要的步驟順序:
1.客戶端向 Node 1 發(fā)送新建漾峡、索引或者刪除請求攻旦。
2.節(jié)點使用文檔的 _id 確定文檔屬于分片 0 。請求會被轉(zhuǎn)發(fā)到 Node 3生逸,因為分片 0 的主分片目前被分配在 Node 3 上牢屋。
3.Node 3 在主分片上面執(zhí)行請求。如果成功了槽袄,它將請求并行轉(zhuǎn)發(fā)到 Node 1 和 Node 2 的副本分片上烙无。一
旦所有的副本分片都報告成功, Node 3 將向協(xié)調(diào)節(jié)點報告成功,協(xié)調(diào)節(jié)點向客戶端報告成功遍尺。
在客戶端收到成功響應時截酷,文檔變更已經(jīng)在主分片和所有副本分片執(zhí)行完成,變更是安全的乾戏。
- 讀取一個文檔
以下是從主分片或者副本分片檢索文檔的步驟順序:
1合搅、客戶端向 Node 1 發(fā)送獲取請求多搀。
2、節(jié)點使用文檔的 _id 來確定文檔屬于分片 0 灾部。分片 0 的副本分片存在于所有的三個節(jié)點上康铭。 在這種情況下,它將請求轉(zhuǎn)發(fā)到 Node 2 赌髓。
3从藤、Node 2 將文檔返回給 Node 1 ,然后將文檔返回給客戶端锁蠕。
在處理讀取請求時夷野,協(xié)調(diào)結(jié)點在每次請求的時候都會通過輪詢所有的副本分片來達到負載均衡。
在文檔被檢索時荣倾,已經(jīng)被索引的文檔可能已經(jīng)存在于主分片上但是還沒有復制到副本分片悯搔。 在這種情況下,副本分片可能會報告文檔不存在舌仍,但是主分片可能成功返回文檔妒貌。 一旦索引請求成功返回給用戶,文檔在主分片和副本分片都是可用的铸豁。
-
更新一個文檔
以下是部分更新一個文檔的步驟:
客戶端向 Node 1 發(fā)送更新請求灌曙。
它將請求轉(zhuǎn)發(fā)到主分片所在的 Node 3 。
Node 3 從主分片檢索文檔节芥,修改 _source 字段中的 JSON 在刺,并且嘗試重新索引主分片的文檔。 如果文檔已經(jīng)被另一個進程修改头镊,它會重試步驟 3 蚣驼,超過 retry_on_conflict 次后放棄。
如果 Node 3 成功地更新文檔相艇,它將新版本的文檔并行轉(zhuǎn)發(fā)到 Node 1 和 Node 2 上的副本分片颖杏,重新建立索引。 一旦所有副本分片都返回成功厂捞, Node 3 向協(xié)調(diào)節(jié)點也返回成功输玷,協(xié)調(diào)節(jié)點向客戶端返回成功。
- 多文檔情況
協(xié)調(diào)節(jié)點知道每個文檔存在于哪個分片中靡馁。 它將整個多文檔請求分解成 每個分片 的多文檔請求欲鹏,并且將這些請求并行轉(zhuǎn)發(fā)到每個參與節(jié)點。
協(xié)調(diào)節(jié)點一旦收到來自每個節(jié)點的應答臭墨,就將每個節(jié)點的響應收集整理成單個響應赔嚎,返回給客戶端
2.分析器
分析器包含以下3個部分:
- 字符過濾器
首先字符串經(jīng)過字符過濾器(character filter),它們的工作是在標記化前處理字符串。字符過濾器能夠去除HTML標記尤误,或者轉(zhuǎn)換"&"為"and"侠畔。 - 分詞器
分詞器(tokenizer)被標記化成獨立的詞。一個簡單的分詞器(tokenizer)可以根據(jù)空格或逗號將單詞分開 - 標記過濾
最后损晤,每個詞都通過所有標記過濾(token filters)软棺,它可以修改詞(例如將"Quick"轉(zhuǎn)為小寫),去掉詞(例如停用詞像"a"尤勋、"and"喘落、"the"等等),或者增加詞(例如同義詞像"jump"和"leap")
Elasticsearch提供很多開箱即用的字符過濾器最冰,分詞器和標記過濾器瘦棋。這些可以組合來創(chuàng)建自定義的分析器以應對不同的需求。我們將在《自定義分析器》章節(jié)詳細討論
內(nèi)置分析器
標準分析器:它根據(jù)Unicode Consortium的定義的單詞邊界(word boundaries)來切分文本暖哨,然后去掉大部分標點符號赌朋。最后,把所有詞轉(zhuǎn)為小寫
簡單分析器:簡單分析器將非單個字母的文本切分篇裁,然后把每個詞轉(zhuǎn)為小寫
空格分析器:空格分析器依據(jù)空格切分文本沛慢。它不轉(zhuǎn)換小寫
語言分析器:特定語言分析器適用于很多語言。它們能夠考慮到特定語言的特性
3.倒排索引
Elasticsearch使用一種叫做倒排索引(inverted index)的結(jié)構(gòu)來做快速的全文搜索茴恰。倒排索引由在文檔中出現(xiàn)的唯一的單詞列表颠焦,以及對于每個單詞在文檔中的位置組成斩熊。
例如往枣,我們有兩個文檔,每個文檔content字段包含:
The quick brown fox jumped over the lazy dog
Quick brown foxes leap over lazy dogs in summer
為了創(chuàng)建倒排索引粉渠,我們首先切分每個文檔的content字段為單獨的單詞(我們把它們叫做詞(terms)或者表征(tokens))(譯者注:關(guān)于terms和tokens的翻譯比較生硬分冈,只需知道語句分詞后的個體叫做這兩個。)霸株,把所有的唯一詞放入列表并排序雕沉,結(jié)果是這個樣子的
現(xiàn)在,如果我們想搜索"quick brown"去件,我們只需要找到每個詞在哪個文檔中出現(xiàn)即可:
兩個文檔都匹配坡椒,但是第一個比第二個有更多的匹配項。 如果我們加入簡單的相似度算法(similarity algorithm)尤溜,計算匹配單詞的數(shù)目倔叼,這樣我們就可以說第一個文檔比第二個匹配度更高——對于我們的查詢具有更多相關(guān)性。