新聞中心
??

創(chuàng)新互聯(lián)主要為客戶提供服務(wù)項(xiàng)目涵蓋了網(wǎng)頁視覺設(shè)計(jì)、VI標(biāo)志設(shè)計(jì)、全網(wǎng)營銷推廣、網(wǎng)站程序開發(fā)、HTML5響應(yīng)式成都網(wǎng)站建設(shè)、手機(jī)網(wǎng)站制作、微商城、網(wǎng)站托管及成都網(wǎng)站維護(hù)、WEB系統(tǒng)開發(fā)、域名注冊、國內(nèi)外服務(wù)器租用、視頻、平面設(shè)計(jì)、SEO優(yōu)化排名。設(shè)計(jì)、前端、后端三個(gè)建站步驟的完善服務(wù)體系。一人跟蹤測試的建站服務(wù)標(biāo)準(zhǔn)。已經(jīng)為隧道混凝土攪拌車行業(yè)客戶提供了網(wǎng)站維護(hù)服務(wù)。
引言
Elasticsearch(以下簡稱ES)是我想寫想了很久的一個(gè)系列,因?yàn)樗俏以诶蠔|家離職前剛接觸的最后一個(gè)新技術(shù),當(dāng)時(shí)就是對某子業(yè)務(wù)的商品搜索做改造,從MySQL遷移商品數(shù)據(jù)到ES中。
我先說一下當(dāng)時(shí)為什么會有場景需要引用到ES,上面我說到是一個(gè)商品庫的搜索改造,在之前這個(gè)子業(yè)務(wù)體量很小使用的人不多,使用場景也比較單一,所以我們就覺得放在數(shù)據(jù)庫里也沒什么,因?yàn)檎P枨笠彩强梢詽M足的。
在數(shù)據(jù)庫我們需要搜索的時(shí)候簡單,直接模糊查詢就好了 select id from item where itemName like %xxx%
但是如果你搜索的關(guān)鍵詞有一點(diǎn)不對,就可能匹配不上這個(gè)商品,比如商品叫:“煩死了,打不掉” 而你搜索的關(guān)鍵詞是:“煩了” 就匹配不上了,但是他們其實(shí)在意思上是有一點(diǎn)關(guān)聯(lián)的對吧?搜出來用戶也是能接受的。
而且隨著你業(yè)務(wù)的發(fā)展,可能需要你搜索出商品名稱帶這個(gè)關(guān)鍵詞且描述里面也帶的,這個(gè)場景其實(shí)多寫點(diǎn)業(yè)務(wù)代碼也能滿足,但是條件越來越多的時(shí)候呢?
還有就是業(yè)務(wù)發(fā)展往往是指數(shù)級別的,當(dāng)時(shí)我們從幾十萬到百萬用了一年,但是百萬到億就用了幾個(gè)月,而且數(shù)據(jù)量級還在不斷增長,這個(gè)時(shí)候放在數(shù)據(jù)庫就不光是業(yè)務(wù)條件不能滿足了,性能也不是加個(gè)索引能搞定的了。
正文
我先介紹一下目前主流的幾種數(shù)據(jù)庫存儲方式 :
行存儲:同一行的數(shù)據(jù)被物理的存儲在一起
常見的行式數(shù)據(jù)庫系統(tǒng)有:MySQL、Postgres和MS SQL Server。
存儲結(jié)構(gòu):
??
某些場景下行存儲數(shù)據(jù)庫的查詢效率:
列存儲 :來自不同列的值被單獨(dú)存儲,來自同一列的數(shù)據(jù)被存儲在一起
常見的列式數(shù)據(jù)庫有:Vertica、 Paraccel (Actian Matrix,Amazon Redshift)、 Sybase IQ、 Exasol、 Infobright、 InfiniDB、 MonetDB (VectorWise, Actian Vector)、 LucidDB、 SAP HANA、 Google Dremel、 Google PowerDrill、 Druid、 kdb+、Hbase、clickhouse。
??
某些場景下列存儲數(shù)據(jù)庫的查詢效率:
最近我在接觸Clickhouse他就是列式存儲,他之所以這么快,主要是以下三點(diǎn)原因:
- 輸入/輸出
- 針對分析類查詢,通常只需要讀取表的一小部分列。在列式數(shù)據(jù)庫中你可以只讀取你需要的數(shù)據(jù)。例如,如果只需要讀取100列中的5列,這將幫助你最少減少20倍的I/O消耗。
- 由于數(shù)據(jù)總是打包成批量讀取的,所以壓縮是非常容易的。同時(shí)數(shù)據(jù)按列分別存儲這也更容易壓縮。這進(jìn)一步降低了I/O的體積。
- 由于I/O的降低,這將幫助更多的數(shù)據(jù)被系統(tǒng)緩存。
注:這里列出這兩個(gè)只是對比一些特殊場景的效率差,也是為后面es的快和數(shù)據(jù)結(jié)構(gòu)做鋪墊而已,事實(shí)上Clickhouse這樣的數(shù)據(jù)庫也只適合某些場景,大部分場景還得行式數(shù)據(jù)庫。
大家感興趣我后面可以來點(diǎn)Clickhouse的分享(雖然我也還在看)
接下來就說另外一種存儲結(jié)構(gòu)了:
文檔
實(shí)際上 es在某種程度上是和列式文檔有一定的相似之處的,大家往后面看就知道了
{
"name": "name"
"size": 24
"sex': "male"
}上面我介紹了幾種常見的存儲結(jié)構(gòu)其實(shí)是為了說明一下es的場景,以及es的一些優(yōu)勢,我們都知道數(shù)據(jù)庫是有索引的,而且也挺快的,那es又是怎么存儲數(shù)據(jù),他的索引又是咋樣的呢?
倒排索引
倒排顧名思義就是通過Value去找key,跟我們傳統(tǒng)意義的根據(jù)key找value還不太一樣。
舉個(gè)例子,還是上面的數(shù)據(jù),我們可以看到es會建立以下的索引:
Name 倒排索引
??
Size倒排索引
??
Sex倒排索引
??
大家可以看到所有的倒排所有都有Term和Posting List這兩個(gè)概念,Posting list就是一個(gè)int的數(shù)組,存儲了所有符合某個(gè)term的文檔id。
怎么根據(jù)value找key呢?就比如我要找所有性別是男生的人,Sex的倒排索引的Posting list可以告訴我是id為1和3的人,那再通過Name的term我可以看到1的是人aobing,3的人是雞蛋,依次類推找到所有信息。
Es的查詢速度是非??斓?,但是目前看來如果只是以Term的樣子去查找并不快呀?是為什么呢?
這里就會引出接下來的兩個(gè)概念,Term Dictionary和Term Index。
Term Dictionary:這個(gè)很好理解,我上面說過都是各種Term組成的,那為了查找Term方便,es把所有的Term都排序了,是二分法查找的。
??
Trem Index:這是為了優(yōu)化Term Dictionary而存在的,大家想呀這么多Term光是排序了肯定也不行,想要快就得放到內(nèi)存,但是es數(shù)據(jù)量級往往是很大的,那放在磁盤?磁盤的尋址又會很慢,那怎么去減少磁盤上的尋址開銷呢?Term Index
其實(shí)就是跟新華字典一樣,每個(gè)字母開頭的是哪些,再按照拼音去排序。
??
這就是三者的關(guān)系,是一張很經(jīng)典的圖了,基本上所有學(xué)es的人都應(yīng)該看到過。
Term Index就存了一些前綴和映射關(guān)系,這樣可以大大減少磁盤的隨機(jī)讀次數(shù)了。
巧妙壓縮
大家是不是發(fā)現(xiàn)這個(gè)設(shè)計(jì)是很巧妙的?而且es的檢索速度比MySQL是快很多的,大家在使用MySQL的時(shí)候可以發(fā)現(xiàn)其實(shí)索引跟Trem Dictionary是一樣的,但是es多了一個(gè)Index 多了一層篩選,少了一些隨機(jī)次數(shù)。
還有一點(diǎn)我很想提一下,就是Term index 在磁盤的存儲結(jié)構(gòu),這個(gè)在我歷史文章有寫過,而且當(dāng)時(shí)我還踩過他的坑,今天鑒于篇幅,我就簡單介紹一下。
FST大家可以理解為一種壓縮技術(shù),最簡單化通過壓縮字節(jié)的方式,上面我說了Term index放到內(nèi)存都放不下,但是壓縮一下呢?
??
細(xì)節(jié)我就不展開了,下面這個(gè)文章解釋的特別詳細(xì),因?yàn)檫@是一篇大概科普的,后面我會專門出文章介紹集群和他壓縮的細(xì)節(jié)。
??
鏈接:https://cs.nyu.edu/~mohri/pub/fla.pdf
接下來再介紹一些es里面我覺得很重要的概念吧:
接近實(shí)時(shí)(NRT)
ES寫入的數(shù)據(jù)會先寫到一個(gè)內(nèi)存bufferr中去(在buffer里的時(shí)候數(shù)據(jù)是搜索不到的),然后每隔默認(rèn)是一秒會刷到os cache。
操作系統(tǒng)里面,磁盤文件其實(shí)都有一個(gè)東西,叫做os cache,操作系統(tǒng)緩存,就是說數(shù)據(jù)寫入磁盤文件之前,會先進(jìn)入os cache,先進(jìn)入操作系統(tǒng)級別的一個(gè)內(nèi)存緩存中去。
只要buffer中的數(shù)據(jù)被refresh操作,刷入os cache中,就代表這個(gè)數(shù)據(jù)就可以被搜索到了。默認(rèn)是每隔1秒refresh一次的,所以es是準(zhǔn)實(shí)時(shí)的,因?yàn)閷懭氲臄?shù)據(jù)1秒之后才能被看到。
為什么要這么設(shè)計(jì)呢?
簡單我們看一下不這么設(shè)計(jì)會怎么樣:
??
如果寫入緩存之后直接刷到硬盤,其實(shí)是十分消耗資源的,而且寫了馬上去硬盤讀取,并發(fā)量很難上去,你可以想象上萬QPS寫入的時(shí)候,還去查詢磁盤,是怎樣一個(gè)災(zāi)難級別的現(xiàn)場。
那es怎么做的呢?
??
數(shù)據(jù)寫入到buffer,然后再每秒刷到cache,這個(gè)時(shí)候就可以被搜到了,所以說準(zhǔn)實(shí)時(shí),而不是實(shí)時(shí)就是這一秒的差距,這樣設(shè)計(jì)可以讓磁盤壓力減少不說,寫入和查詢都不會受到影響,并發(fā)也就上去了。
分詞文本分析(Analysis)是把全文本轉(zhuǎn)換一系列單詞(term/token)的過程,也稱為分詞。
當(dāng)一個(gè)文檔被索引時(shí),每個(gè)Term都可能會創(chuàng)建一個(gè)倒排索引。倒排索引的過程就是將文檔通過分詞器(Analyzer)分成一個(gè)一個(gè)的Term,每一個(gè)Term都指向包含這個(gè)Term的文檔集合。
分詞
是es比較核心的功能,但是他默認(rèn)的分詞其實(shí)對中文并不友好,比如我搜中國,那可能會把帶中和帶國的都搜出來,但是中國就是一個(gè)詞匯不應(yīng)該這樣分。
現(xiàn)在都是可以采用機(jī)器學(xué)習(xí)算法來分詞,還有一些中文分詞插件,比如ik分詞器。
他內(nèi)置分詞器的在英文場景是比較好用的。
腦裂
腦裂問題其實(shí)在集群部署的機(jī)器上都是會存在的,假設(shè)現(xiàn)在es集群有兩個(gè)節(jié)點(diǎn),節(jié)點(diǎn)1是主節(jié)點(diǎn)對外提供服務(wù),節(jié)點(diǎn)2是副本分片節(jié)點(diǎn)。
??
現(xiàn)在兩個(gè)節(jié)點(diǎn)因?yàn)榫W(wǎng)絡(luò)原因斷聯(lián)了,會發(fā)現(xiàn)什么?主節(jié)點(diǎn)發(fā)現(xiàn)自己是主節(jié)點(diǎn)繼續(xù)對外提供服務(wù),副本節(jié)點(diǎn)發(fā)現(xiàn)沒有主節(jié)點(diǎn)了,選舉自己是主節(jié)點(diǎn),也對外提供服務(wù)了,因?yàn)橹鞴?jié)點(diǎn)不可用他也是被迫當(dāng)主節(jié)點(diǎn)的(狗頭)。
??
??
對于調(diào)用者來說,這是很難發(fā)現(xiàn)差別的,除非去對比數(shù)據(jù),而我之前在生產(chǎn)環(huán)境就發(fā)生過腦裂的情況,還是用戶反饋的,因?yàn)樗阉饕粋€(gè)詞匯他有時(shí)候能搜出那個(gè)商品,有時(shí)候不能,因?yàn)檎埱蟠蛟诓煌墓?jié)點(diǎn)上了。
那正常我們會怎么解決呢?elasticsearch.yml中有個(gè)配置:discovery.zen.minimum_master_nodes 這個(gè)參數(shù)決定了在選主過程中需要有多少個(gè)節(jié)點(diǎn)通信,默認(rèn)是1,設(shè)置的原則就是設(shè)置為 集群節(jié)點(diǎn)數(shù)量/2+1個(gè)。
如果你的集群是三個(gè)節(jié)點(diǎn),那這個(gè)參數(shù)就設(shè)置為3/2+1=2個(gè),那掛了一個(gè),另外兩個(gè)可以通信,所以可以選出一個(gè)主的,如果你集群是三個(gè)節(jié)點(diǎn),參數(shù)還是2,但是你發(fā)現(xiàn)掛了一個(gè)只有一個(gè)節(jié)點(diǎn)自己跟自己通信,就不會選主了。
但是這樣也有弊端只有2個(gè)節(jié)點(diǎn)的時(shí)候,掛一個(gè)就相當(dāng)于服務(wù)不可用了,所以大家要保證集群是三個(gè)以上是最好的。
- Elasticsearch的選舉算法基于 Bully 選舉算法,簡單的說,在 Bully 算法中,每個(gè)節(jié)點(diǎn)都有一個(gè)編號,只有編號最大的存活節(jié)點(diǎn)才能成為 master 節(jié)點(diǎn)。Bully算法的具體過程為:
- 當(dāng)任何一個(gè)進(jìn)程P發(fā)現(xiàn) master 不響應(yīng)請求時(shí),它發(fā)起一次選舉,選舉過程如下:
- (1)P進(jìn)程向所有編號比它大的進(jìn)程發(fā)送一個(gè) election 消息;
- (2)如果無人響應(yīng),則P獲勝,成為 master;
- (3)如果編號比它大的進(jìn)程響應(yīng),則由響應(yīng)者接管選舉工作,P的工作完成。
- 任何一個(gè)時(shí)刻,一個(gè)進(jìn)程只能從編號比它小的進(jìn)程接受 election 消息,當(dāng)消息到達(dá)時(shí),接受者發(fā)送一個(gè) OK 消息給發(fā)送者,表明它在運(yùn)行,接管工作。
- 最終除了一個(gè)進(jìn)程外,其他進(jìn)程都放棄,那個(gè)進(jìn)程就是新的協(xié)調(diào)者,隨后協(xié)調(diào)者將獲勝消息發(fā)送給其他所有進(jìn)程,通知它們新的協(xié)調(diào)者誕生了。
ELK
其實(shí)提到ES往往都是ELK三兄弟一起提到的,最后在收尾的地方,我就說一下另外兩個(gè)兄弟吧。
L是Logstash,Logstash是一個(gè)開源數(shù)據(jù)收集引擎,具有實(shí)時(shí)管道功能。Logstash可以動(dòng)態(tài)地將來自不同數(shù)據(jù)源的數(shù)據(jù)統(tǒng)一起來,并將數(shù)據(jù)標(biāo)準(zhǔn)化到你所選擇的目的地。
Logstash管道有兩個(gè)必需的元素:輸入和輸出,以及一個(gè)可選元素:過濾器。輸入插件從數(shù)據(jù)源那里消費(fèi)數(shù)據(jù),過濾器插件根據(jù)你的期望修改數(shù)據(jù),輸出插件將數(shù)據(jù)寫入目的地。
K就是Kibana,Kibana是一個(gè)針對Elasticsearch的開源分析及可視化平臺,用來搜索、查看交互存儲在Elasticsearch索引中的數(shù)據(jù)。使用Kibana,可以通過各種圖表進(jìn)行高級數(shù)據(jù)分析及展示。
Kibana讓海量數(shù)據(jù)更容易理解。它操作簡單,基于瀏覽器的用戶界面可以快速創(chuàng)建儀表板(dashboard)實(shí)時(shí)顯示Elasticsearch查詢動(dòng)態(tài)。
設(shè)置Kibana非常簡單,無需編碼或者額外的基礎(chǔ)架構(gòu),幾分鐘內(nèi)就可以完成Kibana安裝并啟動(dòng)Elasticsearch索引監(jiān)測。
??
總結(jié)
這只是簡單的介紹一下es的一些基礎(chǔ)只是,他的壓縮算法,還有集群,分片,副本復(fù)制等等我都沒聊,下篇文章我會介紹的,
文章名稱:帶給你一篇Elasticsearch入門文章
地址分享:http://m.fisionsoft.com.cn/article/djjdeho.html


咨詢
建站咨詢
