Elasticsearch是什么
Elasticsearch是一個基于Apache Lucene(TM)的一個分布式的開源搜索和分析引擎
Elasticsearch實現(xiàn)的功能
-
分布式的搜索引擎
Elasticsearch自動將海量數(shù)據(jù)分散到多臺服務(wù)器進(jìn)行存儲和檢索
-
全文檢索
Elasticsearch提供了模糊搜索等自動度很高的查詢方式,并進(jìn)行相關(guān)排名麻蹋,高亮等功能
-
數(shù)據(jù)分析
可以做分組聚合
-
對海量數(shù)據(jù)進(jìn)行實時處理
因為Elasticsearch是分布式架構(gòu)跛溉,可以采用大量的服務(wù)器進(jìn)行存儲和檢索數(shù)據(jù),可以實現(xiàn)秒級數(shù)據(jù)搜索和分析
使用場景
- 搜索類場景
- 日志分析 (經(jīng)典的ELK組合完成日志收集、存儲倒谷、分析蛛蒙、查詢功能)
- 數(shù)據(jù)預(yù)警、分析平臺(分析電商平臺評論數(shù)渤愁、訪問量牵祟、關(guān)注度等等)
- 商業(yè)BI系統(tǒng) (分析上一季度消費金額、年齡段抖格、訪問時間段的人數(shù)分布等等)
全文搜索方案對比
-
solr
Solr是一個有HTTP接口的基于Lucene的查詢服務(wù)器诺苹,封裝了很多Lucene細(xì)節(jié),自己的應(yīng)用可以直接利用諸如 .../solr?q=abc 這樣的HTTP GET/POST請求去查詢雹拄,維護(hù)修改索引收奔。
-
Elasticsearch
Elasticsearch也是一個建立在全文搜索引擎 Apache Lucene基礎(chǔ)上的搜索引擎。采用的策略是分布式實時文件存儲滓玖,并將每一個字段都編入索引坪哄,使其可以被搜索。
兩者者之間的一個聯(lián)系:solr和Elasticsearch都是基于Lucene實現(xiàn)的
區(qū)別:
- Solr 利用 Zookeeper 進(jìn)行分布式管理势篡,而 Elasticsearch 自身帶有分布式協(xié)調(diào)管理功能;
- Solr 支持更多格式的數(shù)據(jù)翩肌,而 Elasticsearch 僅支持json文件格式;
- Solr 官方提供的功能更多禁悠,而 Elasticsearch 本身更注重于核心功能念祭,高級功能多有第三方插件提供;
- Solr 在傳統(tǒng)的搜索應(yīng)用中表現(xiàn)好于 Elasticsearch碍侦,但在處理實時搜索應(yīng)用時效率明顯低于 Elasticsearch
核心概念
索引(index)
ElasticSearch將它的數(shù)據(jù)存儲在一個或多個索引(index)中粱坤。用SQL領(lǐng)域的術(shù)語來類比,索引就像數(shù)據(jù)庫瓷产,可以向索引寫入文檔或者從索引中讀取文檔站玄,并通過ElasticSearch內(nèi)部使用Lucene將數(shù)據(jù)寫入索引或從索引中檢索數(shù)據(jù)。
類型(type)
類型是模擬mysql中的table概念濒旦,一個索引庫下可以有不同類型的索引株旷,比如商品索引,訂單索引疤估,其數(shù)據(jù)格式不同灾常。不過這會導(dǎo)致索引庫混亂,因此未來版本中會移除這個概念
ES中每個大版本的type類型有很大區(qū)別
ES 5.x 中index可以又多種type
ES 6.x 中一個index只能有一個type
ES 7.x以后要逐漸移除這個概念
文檔(document)
文檔(document)是ElasticSearch中的主要實體铃拇。對所有使用ElasticSearch的案例來說钞瀑,他們最終都可以歸結(jié)為對文檔的搜索。文檔由字段構(gòu)成慷荔。
在一個index/type里面雕什,你可以存儲任意多的文檔。注意,盡管一個文檔贷岸,物理上存在于一個索引之中壹士,文檔必須被索引/賦予一個索引的type。
字段Field
相當(dāng)于是數(shù)據(jù)表的字段偿警,對文檔數(shù)據(jù)根據(jù)不同屬性進(jìn)行的分類標(biāo)識
映射 mapping
mapping就相當(dāng)于我們關(guān)系型數(shù)據(jù)庫中的表結(jié)構(gòu)躏救,是處理數(shù)據(jù)的方式和規(guī)則方面做一些限制,如某個字段的數(shù)據(jù)類型螟蒸、默認(rèn)值盒使、分析器、是否被索引等等七嫌,這些都是映射里面可以設(shè)置的少办,其它就是處理es里面數(shù)據(jù)的一些使用規(guī)則設(shè)置也叫做映射,按著最優(yōu)規(guī)則處理數(shù)據(jù)對性能提高很大诵原,因此才需要建立映射英妓,并且需要思考如何建立映射才能對性能更好。
集群 cluster
一個集群就是由一個或多個節(jié)點組織在一起绍赛,它們共同持有整個的數(shù)據(jù)蔓纠,并一起提供索引和搜索功能。一個集群由一個唯一的名字標(biāo)識惹资,這個名字默認(rèn)就是“elasticsearch”贺纲。這個名字是重要的航闺,因為一個節(jié)點只能通過指定某個集群的名字褪测,來加入這個集群
可以通過get請求查看集群狀態(tài):
http://es地址:9200/_cat/health?v
返回數(shù)據(jù):
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1645155625 11:40:25 sxjyes green 3 3 252 126 0 0 0 0 - 100.0%
參數(shù)說明:
cluster:集群名稱
status:集群狀態(tài) green代表健康;yellow代表分配了所有主分片潦刃,但至少缺少一個副本侮措,此時集群數(shù)據(jù)仍舊完整;red代表部分主分片不可用乖杠,可能已經(jīng)丟失數(shù)據(jù)分扎。
node.total:代表在線的節(jié)點總數(shù)量
node.data:代表在線的數(shù)據(jù)節(jié)點的數(shù)量
shards, active_shards: 存活的分片數(shù)量
pri胧洒,active_primary_shards: 存活的主分片數(shù)量 正常情況下 shards的數(shù)量是pri的兩倍畏吓。
relo, relocating_shards :遷移中的分片數(shù)量卫漫,正常情況為 0
init菲饼, initializing_shards: 初始化中的分片數(shù)量 正常情況為 0
unassign, unassigned_shards: 未分配的分片 正常情況為 0
pending_tasks:準(zhǔn)備中的任務(wù)列赎,任務(wù)指遷移分片等 正常情況為 0
max_task_wait_time:任務(wù)最長等待時間
active_shards_percent:正常分片百分比 正常情況為 100%
節(jié)點 node
一個節(jié)點是集群中的一個服務(wù)器宏悦,作為集群的一部分,它存儲數(shù)據(jù),參與集群的索引和搜索功能饼煞。和集群類似源葫,一個節(jié)點也是由一個名字來標(biāo)識的,默認(rèn)情況下砖瞧,這個名字是一個隨機的漫威漫畫角色的名字息堂,這個名字會在啟動的時候賦予節(jié)點。這個名字對于管理工作來說挺重要的块促,因為在這個管理過程中储矩,你會去確定網(wǎng)絡(luò)中的哪些服務(wù)器對應(yīng)于Elasticsearch集群中的哪些節(jié)點。
一個節(jié)點可以通過配置集群名稱的方式來加入一個指定的集群褂乍。默認(rèn)情況下持隧,每個節(jié)點都會被安排加入到一個叫做“elasticsearch”的集群中,這意味著逃片,如果你在你的網(wǎng)絡(luò)中啟動了若干個節(jié)點屡拨,并假定它們能夠相互發(fā)現(xiàn)彼此,它們將會自動地形成并加入到一個叫做“elasticsearch”的集群中褥实。
在一個集群里呀狼,只要你想,可以擁有任意多個節(jié)點损离。而且哥艇,如果當(dāng)前你的網(wǎng)絡(luò)中沒有運行任何Elasticsearch節(jié)點,這時啟動一個節(jié)點僻澎,會默認(rèn)創(chuàng)建并加入一個叫做“elasticsearch”的集群貌踏。
分片和復(fù)制 shards&replicas
一個索引可以存儲超出單個結(jié)點硬件限制的大量數(shù)據(jù)。比如窟勃,一個具有10億文檔的索引占據(jù)1TB的磁盤空間祖乳,而任一節(jié)點都沒有這樣大的磁盤空間;或者單個節(jié)點處理搜索請求秉氧,響應(yīng)太慢眷昆。為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力汁咏,這些份就叫做分片亚斋。當(dāng)你創(chuàng)建一個索引的時候,你可以指定你想要的分片的數(shù)量攘滩。每個分片本身也是一個功能完善并且獨立的“索引”帅刊,這個“索引”可以被放置到集群中的任何節(jié)點上。分片很重要轰驳,主要有兩方面的原因:
1)允許你水平分割/擴展你的內(nèi)容容量厚掷。
2)允許你在分片(潛在地弟灼,位于多個節(jié)點上)之上進(jìn)行分布式的、并行的操作冒黑,進(jìn)而提高性能/吞吐量田绑。
至于一個分片怎樣分布,它的文檔怎樣聚合回搜索請求抡爹,是完全由Elasticsearch管理的掩驱,對于作為用戶的你來說,這些都是透明的冬竟。
在一個網(wǎng)絡(luò)/云的環(huán)境里欧穴,失敗隨時都可能發(fā)生,在某個分片/節(jié)點不知怎么的就處于離線狀態(tài)泵殴,或者由于任何原因消失了涮帘,這種情況下,有一個故障轉(zhuǎn)移機制是非常有用并且是強烈推薦的笑诅。為此目的调缨,Elasticsearch允許你創(chuàng)建分片的一份或多份拷貝,這些拷貝叫做復(fù)制分片吆你,或者直接叫復(fù)制弦叶。
復(fù)制之所以重要,有兩個主要原因: 在分片/節(jié)點失敗的情況下妇多,提供了高可用性伤哺。因為這個原因,注意到復(fù)制分片從不與原/主要(original/primary)分片置于同一節(jié)點上是非常重要的者祖。擴展你的搜索量/吞吐量立莉,因為搜索可以在所有的復(fù)制上并行運行∠贪總之桃序,每個索引可以被分成多個分片杖虾。一個索引也可以被復(fù)制0次(意思是沒有復(fù)制)或多次烂瘫。一旦復(fù)制了,每個索引就有了主分片(作為復(fù)制源的原來的分片)和復(fù)制分片(主分片的拷貝)之別奇适。分片和復(fù)制的數(shù)量可以在索引創(chuàng)建的時候指定坟比。在索引創(chuàng)建之后,你可以在任何時候動態(tài)地改變復(fù)制的數(shù)量嚷往,但是你事后不能改變分片的數(shù)量葛账。
默認(rèn)情況下,Elasticsearch中的每個索引被分片5個主分片和1個復(fù)制皮仁,這意味著籍琳,如果你的集群中至少有兩個節(jié)點菲宴,你的索引將會有5個主分片和另外5個復(fù)制分片(1個完全拷貝),這樣的話每個索引總共就有10個分片趋急。
Elasticsearch概念和關(guān)系型數(shù)據(jù)庫的對比
關(guān)系型數(shù)據(jù)庫(如mysql) | Elasticsearch |
---|---|
數(shù)據(jù)庫 | 索引index |
表(table) | 索引index類型(原為type) |
數(shù)據(jù)行row | 文檔(document) |
數(shù)據(jù)列(column) | 字段Field |
約束 schema | 映射 mapping |
字段類型
字段類型分為基本類型和復(fù)合類型‘
基本類型
字符串類型
-
string
string類型在ElasticSearch 舊版本中使用較多喝峦,從ElasticSearch 5.x開始不再支持string箕母,由text和keyword類型替代诡蜓。
-
text
當(dāng)一個字段是要被全文搜索的,比如Email內(nèi)容垢乙、產(chǎn)品描述查近,應(yīng)該使用text類型眉踱。設(shè)置text類型以后,字段內(nèi)容會被分析霜威,在生成倒排索引以前谈喳,字符串會被分析器分成一個一個詞項。text類型的字段不用于排序戈泼,很少用于聚合叁执。
text會分詞,然后進(jìn)行索引矮冬,支持模糊谈宛、精確查詢,不支持聚合
-
keyword
這種類型適用于結(jié)構(gòu)化的字段胎署,例如標(biāo)簽吆录、email 地址、手機號碼等等琼牧,這種類型的字段可以用作過濾恢筝、排序、聚合等巨坊。這種字符串也稱之為 not-analyzed 字段撬槽。
keyword不進(jìn)行分詞,直接索引趾撵,支持模糊侄柔、精確查詢,支持聚合
數(shù)字類型
數(shù)字類型有l(wèi)ong占调、integer暂题、short、byte究珊、double薪者、float、half_float剿涮、scaled_float言津。
- 在滿足需求的情況下攻人,優(yōu)先使用范圍小的字段。字段長度越短悬槽,索引和搜索的效率越高贝椿。比如,某個字段的取值最大值不會超過100陷谱,那么選擇byte類型即可烙博。迄今為止吉尼斯記錄的人類的年齡的最大值為134歲,對于年齡字段烟逊,short足矣字段的長度越短渣窜,索引和搜索的效率越高。
- 浮點數(shù)宪躯,優(yōu)先考慮使用 scaled_float乔宿。
日期類型
由于 JSON 中沒有日期類型,所以 es 中的日期類型形式就比較多樣:2020-11-11 或者 2020-11-11 11:11:11访雪,一個從 1970.1.1 零點到現(xiàn)在的一個秒數(shù)或者毫秒數(shù)详瑞。es 內(nèi)部將時間轉(zhuǎn)為 UTC,然后將時間按照 millseconds-since-the-epoch 的長整型來存儲臣缀。
boolean類型
邏輯類型(布爾類型)可以接受true/false/”true”/”false”值
二進(jìn)制類型(binary)
二進(jìn)制字段是指用base64來表示索引中存儲的二進(jìn)制數(shù)據(jù)坝橡,可用來存儲二進(jìn)制形式的數(shù)據(jù),例如圖像精置。默認(rèn)情況下计寇,該類型的字段只存儲不索引。二進(jìn)制類型只支持index_name屬性脂倦。
范圍類型(range)
數(shù)據(jù)范圍類型番宁,一個字段表示一個范圍,具體包含以下類型:
- integer_range
- float_range
- double_range
- date_range
- ip_range
所謂的范圍類型赖阻,就是一個值自身就表明一個范圍蝶押,如:
PUT range_index
{
"mappings": {
"_doc": {
"properties": {
"expected_attendees": {
"type": "integer_range"
}
}
}
}
}
復(fù)合類型
數(shù)組類型(array)
es 中沒有專門的數(shù)組類型。默認(rèn)情況下火欧,任何字段都可以有一個或者多個值棋电。需要注意的是,數(shù)組中的元素必須是同一種類型布隔。添加數(shù)組是离陶,數(shù)組中的第一個元素決定了整個數(shù)組的類型。
對象類型(object)
由于 JSON 本身具有層級關(guān)系衅檀,所以文檔包含內(nèi)部對象。內(nèi)部對象中霎俩,還可以再包含內(nèi)部對象哀军。
IK分詞器
Elasticsearch自帶的標(biāo)準(zhǔn)分詞器是針對英文的沉眶,所以我們在日常開發(fā)中都是使用ik分詞器,它是一個針對中文的分詞器杉适。
從2016年12月推出1.0版本開始谎倔,IKAnalyzer已經(jīng)推出了三個大版本,最初他是以開源項目Lucene為應(yīng)用主題的猿推,結(jié)合詞典分詞和文法分析算法的中文分詞組件片习,新版的IKAnalyzer3.0則發(fā)展為面向java的公用分詞組件,獨立于Lucene項目蹬叭,同時提供了對Lucene的默認(rèn)優(yōu)化實現(xiàn)
IKAnalyzer3.0版本特性如下:
- 采用了特有的“正向迭代最細(xì)粒度切分算法“藕咏,具有50萬字/秒的高速處理能力。
- 采用了多子處理器分析模式秽五,支持:英文字母(IP地址孽查、Email、URL)坦喘、數(shù)字(日期盲再,常用中文數(shù)量詞,羅馬數(shù)字瓣铣,科學(xué)計數(shù)法)答朋,中文詞匯(姓名、地名處理)等分詞處理棠笑。
- 優(yōu)化的詞典存儲绿映,更小的內(nèi)存占用。支持用戶詞典擴展定義
- 針對Lucene全文檢索優(yōu)化的查詢分析器IKQueryParser腐晾;采用歧義分析算法優(yōu)化查詢關(guān)鍵字的搜索排列組合叉弦,能極大的提高Lucene檢索的命中率。
IK分詞器有兩種分詞模式:ik_max_word和ik_smart模式藻糖。
ik_max_word
會將文本做最細(xì)粒度的拆分淹冰,比如會將“中華人民共和國人民大會堂”拆分為“中華人民共和國、中華人民巨柒、中華樱拴、華人、人民共和國洋满、人民晶乔、共和國、大會堂牺勾、大會正罢、會堂等詞語。
ik_smart
會做最粗粒度的拆分驻民,比如會將“中華人民共和國人民大會堂”拆分為中華人民共和國翻具、人民大會堂履怯。
IK分詞器擴展詞典
停用詞擴展
- 1) 我們找到IK的配置文件,位于ik/config/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴展配置</comment>
<!--用戶可以在這里配置自己的擴展字典 -->
<entry key="ext_dict">ext_dic.dic</entry>
<!--用戶可以在這里配置自己的擴展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠(yuǎn)程擴展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用戶可以在這里配置遠(yuǎn)程擴展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
- 2)在配置文件中增加配置的停用詞文件的節(jié)點:
<entry key="ext_stopwords">my_ext_stopword.dic</entry>
3)在類目前下創(chuàng)建擴展停用詞文件my_ext_stopword.dic
4) 在文件my_ext_stopword.dic中添加詞,一行一個
擴展字典
- 1) 我們找到IK的配置文件,位于ik/config/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴展配置</comment>
<!--用戶可以在這里配置自己的擴展字典 -->
<entry key="ext_dict">ext_dic.dic</entry>
<!--用戶可以在這里配置自己的擴展停止詞字典-->
<entry key="ext_stopwords"></entry>
<!--用戶可以在這里配置遠(yuǎn)程擴展字典 -->
<!-- <entry key="remote_ext_dict">words_location</entry> -->
<!--用戶可以在這里配置遠(yuǎn)程擴展停止詞字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
- 2)在配置文件中增加配置的停用詞文件的節(jié)點:
<entry key="ext_dict">my_ext_dict.dic</entry>
3)在類目前下創(chuàng)建擴展停用詞文件my_ext_dict.dic
4) 在文件my_ext_dict.dic中添加詞裆泳,一行一個
同義詞詞典
Elasticsearch 自帶一個名為 synonym 的同義詞 filter叹洲。為了能讓 IK 和 synonym 同時工作,我們需要定義新的 analyzer工禾,用 IK 做 tokenizer运提,synonym 做 filter。
- 打開 /config/elasticsearch.yml 文件闻葵,加入以下配置:
index:
analysis:
analyzer:
ik_syno:
type: custom
tokenizer: ik_max_word
filter: [my_synonym_filter]
ik_syno_smart:
type: custom
tokenizer: ik_smart
filter: [my_synonym_filter]
filter:
my_synonym_filter:
type: synonym
synonyms_path: analysis/synonym.txt
以上配置定義了 ik_syno 和 ik_syno_smart 這兩個新的 analyzer民泵,分別對應(yīng) IK 的 ik_max_word 和 ik_smart 兩種分詞策略
創(chuàng)建/config/analysis/synonym.txt 文件,輸入一些同義詞并存為 utf-8 格式笙隙。例如
重啟es即可