ES是什么
- 基于 Lucene 的搜索引擎伺帘,Lucene 被認(rèn)為是迄今為止最先進(jìn)凑队、性能最好的则果、功能最全的搜索引擎庫。
- 分布式的實時文檔存儲漩氨,每個字段 可以被索引與搜索
- 隨時可用和按需擴(kuò)容(水平擴(kuò)容)
- 最受歡迎的企業(yè)搜索引擎西壮,其次是 Apache Solr
- 能勝任上百個服務(wù)節(jié)點(diǎn)的擴(kuò)展,并支持 PB 級別的結(jié)構(gòu)化或者非結(jié)構(gòu)化數(shù)據(jù)
- 對于使用者來說叫惊,不用擔(dān)心主副問題款青,天然分布式保證數(shù)據(jù)安全
- Java 開發(fā)
- 不支持事物
- 由于需要分詞、索引赋访、merge可都,寫速度慢
應(yīng)用企業(yè)
- 維基百科:全文搜索缓待,高亮關(guān)鍵字、搜索糾錯
- StackOverflow:全文搜索渠牲,地理位置旋炒、more-like-this
- Github:1300億行代碼檢索
應(yīng)用場景
- 在線商店
- 日志或者交易數(shù)據(jù) 分析和挖掘
- 報價系統(tǒng)、價格變更系統(tǒng):發(fā)生滿足條件的變更通知關(guān)注者
- 大數(shù)據(jù)分析需求: kibana 統(tǒng)計分析數(shù)據(jù)
原理
ES原理
Analysis (分析器)
通過執(zhí)行 analyzer 實現(xiàn)签杈,analyzer包含 Character filter
,Tokenizer
, Token filter
(有序經(jīng)過上述三步處理).
更多查看
Character filter (字符過濾器)
- 接收原始數(shù)據(jù)瘫镇,可在原始數(shù)據(jù)上增加/刪除/修改字符.
- 把結(jié)果輸出到
Tokenizer
. - 輸入是Text,輸出也是Text.
- 如把Text中的 (?????????????) 轉(zhuǎn)變成 (0123456789), 刪除 HTML 的標(biāo)簽(如<b>)
Tokenizer (分詞器)
- 對來自
Character filter
的輸入數(shù)據(jù)(Text)答姥,進(jìn)行分詞處理,輸出 Terms. - 輸入是Text, 輸出是Terms
Token filter (標(biāo)記過濾器)
Token filter 從 Tokenizer 獲得terms铣除,可對terms執(zhí)行的操作有,其操作對象是單個的term:
- 修改:如 大寫變小寫(Goods, goods)
- 刪除:如 刪除停頓符(stopwords)
- 添加:如 添加同義詞
- 輸入是 terms, 輸出是 terms
demo
POST _analyze
{
"tokenizer": "standard",
"text": "<p>I'm so <b>happy</b>!</p>"
}
POST _analyze
{
"tokenizer": "standard",
"char_filter": [
"html_strip"
],
"text": "<p>I'm so <b>happy</b>!</p>"
}
POST _analyze
{
"tokenizer": "keyword",
"char_filter": [
"html_strip"
],
"text": "<p>I'm so <b>happy</b>!</p>"
}
POST _analyze
{
"tokenizer": "letter",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
POST _analyze
{
"tokenizer": "standard",
"filter": [ "lowercase", "asciifolding" ],
"text": "Is This Déja vu?"
}
主要名詞介紹
Inverted index
:倒排索引鹦付,索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的地址尚粘。由于不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置敲长,因而稱為倒排索引(inverted index)郎嫁。帶有倒排索引的文件我們稱為倒排索引文件,簡稱倒排文件(inverted file)祈噪。倒排索引是ES中最核心的概念泽铛,是其可以進(jìn)行快速搜索的原因Cluster
: 集群,一個或者多個節(jié)點(diǎn)組成辑鲤,他們有相同的 cluster.nameNode
:節(jié)點(diǎn)盔腔,一個ES實例。集群中一個節(jié)點(diǎn)會被選為 主節(jié)點(diǎn)月褥。主節(jié)點(diǎn)只管理集群級別的事物弛随,不參與文檔級別的變更或者搜索。每個節(jié)點(diǎn)都知道文檔存在哪里
-
Shard
:分片吓坚,最小級別的工作單元撵幽,他只是保存了索引中所有數(shù)據(jù)的一部分,是一個數(shù)據(jù)的容器礁击。主分片決定了可存儲的索引的量。副本分片只是副本
逗载。分片是一個Lucene Index, 最大可存儲Document數(shù)為:2,147,483,519=Integer.MAX_VALUE - 128哆窿。-
Primary Shard
: 主分片, 簡稱Shard
- 數(shù)量在建索引時確定,不可修改
- 其不可修改原因:hash(routing) % number_of_shards, number_of_shards指主分片數(shù)
- 新建索引時厉斟,通過
index.number_of_shards
設(shè)置
-
Replica Shared
:副本分片, 簡稱Replica
- 新建時可設(shè)置挚躯,運(yùn)用期可修改
- 新建索引或運(yùn)行期間,通過
index.number_of_replicas
設(shè)置擦秽,表示每個主分片對應(yīng)的副本分片數(shù)
-
-
Index
:索引码荔,類似數(shù)據(jù)庫名(database)- 一個存儲關(guān)聯(lián)數(shù)據(jù)的地方
- 一個用來指向一個或者多個分片的邏輯命名空間
- 我們應(yīng)用程序直接和索引通信漩勤,不和分片通信
文檔的索引首先會存于主分片,然后存于復(fù)分片缩搅。成功后確保數(shù)據(jù)可在所有主復(fù)分片被檢索越败。
Type
:類型,類似數(shù)據(jù)庫表名.Deprecated in 6.0.0硼瓣,7.X已經(jīng)不支持了究飞,只能是 _doc
Id
:文檔id,可自定義或ES自動生成mapping
:映射堂鲤,定義字段type和相關(guān)設(shè)置-
CCR
:cross-cluster replication亿傅,跨集群復(fù)制,同網(wǎng)絡(luò)數(shù)據(jù)遷移非澄疗埽快速.單集群遇到災(zāi)難時葵擎,數(shù)據(jù)安全性沒法保障。為了應(yīng)對這個問題半哟,采用CCR坪蚁。CCR is active-passive,主集群負(fù)責(zé)讀镜沽、寫敏晤,復(fù)本集群只負(fù)責(zé)讀-
leader indices
:CCR跨集群復(fù)制的源索引。存在于遠(yuǎn)端缅茉,被復(fù)制到follower indices
-
follower index
:CCR跨集群復(fù)制的目標(biāo)索引嘴脾。存在于本地集群,復(fù)制leader indices
-
主要操作流程
選舉Master
寫操作
- 操作步驟
- routing(ID) -> 主分片
- 數(shù)據(jù)校驗(格式是否正確蔬墩,id是否合法...)译打,本地 indexing or deleting
- 通知 副分片 同步數(shù)據(jù)(
in-sync copies set
并行同步) - 所有副分片同步成功后,主分片告訴客戶端操作完成
- 出現(xiàn)問題場景
- 主分片出現(xiàn)問題拇颅,
Master
會收到通知奏司,Master
會選擇一個副分片作為主分片 - 如果副分片出現(xiàn)問題,會通知
Master
把該分片從in-sync copies set
中刪除樟插,然后再通知client
-
Master
會啟動新的分片韵洋,保證集群健康
- 主分片出現(xiàn)問題拇颅,
讀操作
- 讀操作
- 協(xié)調(diào)節(jié)點(diǎn)
coordinating node
收到讀請求, 解析請求,并把請求發(fā)送到相關(guān)的分片 - 從 分片副本集合
the shard replication group
里面選擇一個相關(guān)的分片獲取有效數(shù)據(jù), 采用 round robin算法(即輪詢算法) - 發(fā)送分片級別請求到選定復(fù)本
- 協(xié)調(diào)節(jié)點(diǎn)合并請求結(jié)果(通過ID獲取數(shù)據(jù)沒有這一步)
- 協(xié)調(diào)節(jié)點(diǎn)
- 讀操作失敾拼浮:會發(fā)送請求到另一個分片(來自
the shard replication group
的分片)搪缨。為了快速響應(yīng),Search
鸵熟、Multi Search
副编、Bulk
、Multi Get
分片失敗后流强,立馬返回(快速失敗痹届,不會把請求發(fā)送到另一個分片)
數(shù)據(jù)操作路邏輯
-
內(nèi)存緩存(不可檢索)
->未提交段(內(nèi)存索引呻待,可檢索)
->已提交段(內(nèi)存索引,可檢索)
- 內(nèi)存緩存 -> 未提交段:1s 會自動刷新一次队腐,也可手動刷新
_refresh
蚕捉。刷新后,內(nèi)存緩存會被清除香到,事務(wù)日志會保留 - 未提交段 -> 已提交段:每30min鱼冀,或事務(wù)日志過大,進(jìn)行一次 Flush 到硬盤操作
- 當(dāng)段較小時悠就,未提交的段和已提交段之間可能會進(jìn)行合并千绪。對應(yīng)命令:_optimize
- 內(nèi)存緩存 -> 未提交段:1s 會自動刷新一次队腐,也可手動刷新
- 索引和搜索一個文檔之間是有一定延遲的。新文檔會在1s后被搜索到梗脾。
- 事務(wù)日志:記錄所有沒有Flush到硬盤的操作
配置
- Xms Xmx 設(shè)置成相同的值, 如:
-e ES_JAVA_OPTS="-Xms16g -Xmx16g"
- Xmx不超過機(jī)器物理內(nèi)存 50%, 以便給內(nèi)核文件系統(tǒng)緩存留出足夠物理內(nèi)存
- 一般來講荸型,每個分片的大小在20GB-40GB
相關(guān)API
- update: 刪除舊文檔,索引新建文檔炸茧,并不是我們認(rèn)為的 update
- bulk: 單個操作失敗瑞妇,還是會執(zhí)行其他操作,整個請求結(jié)果正常返回梭冠,每個操作都會有對應(yīng)的操作結(jié)果(按請求排序)辕狰。如有需要,可判斷結(jié)果做后續(xù)處理.
易出問題的點(diǎn)
分頁問題
- 避免深度分頁
- 分頁邏輯:每次分頁需要獲得包括當(dāng)前頁及之前的所有數(shù)據(jù)控漠,一起排序
- 處理深度分頁方案:scan & scroll
由于lucene的原因蔓倍,所有數(shù)據(jù)會做扁平化出來
- 原始數(shù)據(jù)
{
"followers": [
{ "age": 35, "name": "Mary White"},
{ "age": 26, "name": "Alex Jones"},
{ "age": 19, "name": "Lisa Smith"}
]
}
- Lucene保存數(shù)據(jù)
{
"followers.age": [19, 26, 35],
"followers.name": [alex, jones, lisa, smith, mary, white]
}
ES和Lucene相關(guān)概念對比
- Lucene索引是ES分片
- ES索引是分片的集合,索引的數(shù)據(jù)會存于多個分片
加載測試數(shù)據(jù)
- accounts.json, 格式如下:
{"index":{"_id":"1"}}
{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
{"index":{"_id":"6"}}
{"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
{"index":{"_id":"13"}}
{"account_number":13,"balance":32838,"firstname":"Nanette","lastname":"Bates","age":28,"gender":"F","address":"789 Madison Street","employer":"Quility","email":"nanettebates@quility.com","city":"Nogal","state":"VA"}
- 導(dǎo)入數(shù)據(jù)
curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@accounts.json"
curl "localhost:9200/_cat/indices?v"
相關(guān)概念
- 并發(fā)控制
- 悲觀并發(fā)控制:認(rèn)為并發(fā)盐捷、沖突是大概率事件偶翅。要修改,先獲得鎖
- 樂觀并發(fā)控制:認(rèn)為并發(fā)碉渡、沖突是小概率事件聚谁。發(fā)生沖突,由業(yè)務(wù)自己決定如何處理
- ES中 所有更新和刪除文檔的請求都接受
version
參數(shù),它可以允許在你的代碼中增加樂觀鎖控制滞诺。
- TF/IDF
- TF : 詞頻率
- IDF : 反轉(zhuǎn)文檔率
- 當(dāng)根據(jù) TF/IDF 算法獲得得分跟實際得分有差距的原因:本地IDF和全局IDF有區(qū)別形导,數(shù)據(jù)越大,這個差距會越小铭段。避免這種問題有兩種方法(測試使用骤宣,實際場景數(shù)據(jù)量大,不需要):
- 為了避免這個問題序愚,可以創(chuàng)建只有一個主分片的索引,那么本地IDF就是全局IDF等限。
- 查詢加參數(shù) ?search_type=dfs_query_then_fetch
相關(guān)文檔
- ES原理
- https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
- https://www.elastic.co/cn/products/elasticsearch
- https://zh.wikipedia.org/wiki/Elasticsearch
- http://www.reibang.com/p/4e412f48e820 mysql爸吮、hbase芬膝、es對比
- https://my.oschina.net/galenz/blog/422189
- http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html