0、前言
- 變更原由:昨晚更新部落格之後,告知更新了,但是第一次出現有人看不到這篇部落格,有人有看得到,我也不知道我設定了什麼地方_,所以我把原部落格刪了,重新發布
另外:
- 這裡面一些理論和前面的知識點掛鉤的,所以:建議看一下另外3篇知識內容
- 基礎篇:https://www.cnblogs.com/xiegongzi/p/15684307.html
- java操作篇:https://www.cnblogs.com/xiegongzi/p/15690534.html
- 高階篇1:https://www.cnblogs.com/xiegongzi/p/15757337.html
4.12、文件搜尋
4.12.1、不可變的倒排索引
-
以前的全文檢索是將整個文件集合弄成一個倒排索引,然後存入磁碟中,當要建立新的索引時,只要新的索引準備就緒之後,舊的索引就會被替換掉,這樣最近的文件資料變化就可以被檢索到
-
而索引一旦被存入到磁碟就是不可變的( 永遠都不可以修改 ),而這樣做有如下的好處:
- 1、只要索引被讀入到記憶體中了,由於其不變性,所以就會一直留在記憶體中( 只要空間足夠 ),從而當我們做“讀操作”時,請求就會進入記憶體中去,而不會去磁碟中,這樣就減小開銷,提高效率了
- 2、索引放到記憶體中之後,是可以進行壓縮的,這樣做之後,也就可以節約空間了
- 3、放到記憶體中後,是不需要鎖的,如果自己的索引是長期不用更新的,那麼就不用怕多程式同時修改它的情況了
-
當然:這種不可變的倒排索引有好處,那就肯定有壞處了“
- 不可變,不可修改嘛,這就是最大的壞處,當要重定一個索引能夠被檢索時,就需要重新把整個索引構建一下,這樣的話,就會導致索引的資料量很大( 資料量大小有限制了 ),同時要更新索引,那麼這頻率就會降低了( 這就好比是什麼呢?關係型中的表,一張大表檢索資料、更新資料效率高不高?肯定不高,所以延伸出了:可變索引 )
4.12.2、可變的倒排索引
又想保留不可變性,又想能夠實現倒排索引的更新,咋辦?
- 就搞出了
補充索引
,所謂的補充索引:有點類似於日誌這個玩意兒,就是重建一個索引,然後用來記錄最近指定一段時間內的索引中文件資料的更新。這樣更新的索引資料就記錄在補充索引中了,然後檢索資料時,直接找補充索引即可,這樣檢索時不再重寫整個倒排索引了,這有點類似於關係型中的拆表,大表拆小表嘛,但是啊:每一份補充索引都是一份單獨的索引啊,這又和分片很像,可是:查詢時是對這些補充索引進行輪詢,然後再對結果進行合併,從而得到最終的結果,這和前面說過的讀流程中說明的協調節點掛上鉤了
這裡還需要了解一個配套的按段搜尋
,玩過 Lucene 的可能聽過。按段,每段也就可以理解為:補充索引,它的流程其實也很簡單:
-
1、新文件被收集到記憶體索引快取
-
2、不時地提交快取
- 2.1、一個新的段,一個追加的倒排索引,被寫入磁碟
- 2.2、一個新的包含新段名字的提交點被寫入磁碟
- 2.3、磁碟進行同步,所有在檔案系統快取中等待的寫入都重新整理到磁碟,以確保它們被寫入物理檔案
-
3、新的段被開啟,讓它包含的文件可見,以被搜尋
-
4、記憶體快取被清空,等待接收新的文件
-
一樣的,段在查詢的時候,也是輪詢的啊,然後把查詢結果合併從而得到的最終結果
-
另外就是涉及到刪除的事情,段本身也是不可變的, 既不能把文件從舊的段中移除,也不能修改舊的段來進行文件的更新,而刪除是因為:是段在每個提交點時有一個.del檔案,這個檔案就是一個刪除的標誌檔案,要刪除哪些資料,就對該資料做了一個標記,從而下一次查詢的時候就過濾掉被標記的這些段,從而就無法查到了,這叫邏輯刪除( 當然:這就會導致倒排索引越積越多,再查詢時。輪詢來查資料也會影響效率 ),所以也有物理刪除,它是把段進行合併,這樣就捨棄掉被刪除標記的段了,從而最後重新整理到磁碟中去的就是最新的資料( 就是去掉刪除之後的 ,別忘了前面整的段的流程啊,不是白寫的 )
4.13、近實時搜尋、文件重新整理、文件刷寫、文件合併
- ES的最大好處就是實時資料全文檢索,但是:ES這個玩意兒並不是真的實時的,而是近實時 / 準實時,原因就是:ES的資料搜尋是分段搜尋,最新的資料在最新的段中( 每一個段又是一個倒排索引 ),只有最新的段重新整理到磁碟中之後,ES才可以進行資料檢索,這樣的話,磁碟的IO效能就會極大的影響ES的查詢效率,而ES的目的就是為了:快速的、準確的獲取到我們想要的資料,因此:降低資料查詢處理的延遲就very 重要了,而ES對這方面做了什麼操作?
- 就是搞的一主多副的方式( 一個主分片,多個副本分片 ),這雖然就是一句話概括了,但是:裡面的門道卻不是那麼簡單的
首先來看一下主副操作
-
但是:這種去找尋節點的過程想都想得到會造成延時,而延時 = 主分片延時 + 主分片拷貝資料給副本的延時
-
而且並不是這樣就算完了,前面提到了N多次的分段、重新整理到磁碟還沒上堂呢,所以接著看
-
但是:在flush到磁碟中的時候,萬一斷電了呢?或者其他原因導致出問題了,那最後資料不就沒有flush到磁碟嗎。因此:其實還有一步操作,把資料儲存到另外一個檔案中去
-
資料放到磁碟中之後,translog中的資料就會清空
-
同時更新到磁碟之後,使用者就可以進行搜尋資料了
-
注意:這裡要區分一下,資料庫中是先更新到log中,然後再更新到記憶體中,而ES是反著的,是先更新到Segment( 可以直接認為是記憶體,因它本身就在記憶體中 ),再更新到log中
-
可是啊,還是有問題,flush刷寫到磁碟是很耗效能的,假如:不斷進行更新呢?這樣不斷進行IO操作,效能好嗎?也不行,因此:繼續改造( 在Java的JDBC中我說過的 ———— 沒有什麼是加一層解決不了的,一層不夠,那就再來一層 )
-
加入了快取之後,這快取裡面的資料是可以直接用來搜尋的,這樣就不用等到flush到磁碟之後,才可以搜尋了,這大大的提高了效能,而flush到磁碟,只要時間到了,讓它自個兒慢慢flush就可以了( 作業系統快取中的資料斷電不會丟失啊,只會在下一次啟動的時候,繼續執行而已 ),上面這個流程也叫:持久化 / 持久化變更
-
寫入和開啟一個新段的輕量的過程叫做refresh。預設情況下每個分片會每秒自動重新整理一次。這就是為什麼我們說 ES是近實時搜尋:文件的變化並不是立即對搜尋可見,但會在一秒之內變為可見
- 重新整理是1s以內完成的,這是有時間間隙的,因此會造成:搜尋一個文件時,可能並沒有搜尋到,因此:解決辦法就是使用refresh API重新整理一下即可
- 但是這樣也伴隨一個問題:雖然這種從記憶體重新整理到快取中看起來不錯,但是還是有效能開銷的。並不是所有的情況都需要refresh的,假如:是在索引日誌檔案呢?去refresh幹嘛,浪費效能而已,所以此時:你要的是查詢速度,而不是近實時搜尋,因此:可以通過一個配置來進行改動,從而降低每個索引的重新整理頻率
http://ip:port/index_name/_settings # 請求方式:put
# 請求體內容
{
"settings": {
"refresh_interval": "60s"
}
}
- refresh_interval可以在既存索引上進行動態更新。在生產環境中,當你正在建立一個大的新索引時,可以先關閉自動重新整理,待開始使用該索引時,再把它們調回來( 雖然有點麻煩,但是按照ES這個玩意兒來說,確實需要這麼做比較好 )
# 關閉自動重新整理
http://ip:port/users/_settings # 請求方式:put
# 請求體內容
{
"refresh_interval": -1
}
# 每一秒重新整理
http://ip:port/users/_settings # 請求方式:put
# 請求體內容
{
"refresh_interval": "1s"
}
- 另外:不斷進行更新就會導致很多的段出現( 在記憶體刷寫到磁碟哪裡,會造成很多的磁碟檔案 ),因此:在哪裡利用了文件合併的功能( 也就是段的能力,合併文件,從而讓刷寫到磁碟中的文件變成一份 )
- 經過上面的思路瞭解之後,要是面試官問你資料庫的優化可以怎麼弄?除了常見的,這個分段的思想、分片的思想就可以套上去了,當然再結合Redis的優化方式來回答,更beautiful,順帶還可以扯到Redis和ES來( 面試造飛機,上班擰螺絲嘛,或者就是一部署完就在辦公室坐著摳腳 ),這就變成你牽著面試官的鼻子走,而不是他問什麼,你去跟著它的思路回答,主動權在自己手上不香嗎,面試官面試一個人是有時間限制的,當然:要是不想扯到ES中來,直接根據情況大表拆小表也行
4.14、文件分析
-
試想:我們在瀏覽器中,輸入一條資訊,如:搜尋“部落格園紫邪情”,為什麼連“部落格園也搜尋出來了?我要的不是這個結果澀”
-
這就是全文檢索,就是ES乾的事情( 過濾資料、檢索嘛 ),但是:它做了哪些操作呢?
在ES中有一個文件分析的過程,文件分析的過程也很簡單:
-
將文字拆成適合於倒排索引的獨立的詞條,然後把這些詞條統一變為一個標準格式,從而使文字具有“可搜尋性”
-
而這個文件分析的過程在ES是由一個叫做“分析器 analyzer”的東西來做的,這個分析器裡面做了三個步驟
-
1、字元過濾器:就是用來處理一些字元的嘛,像什麼將 & 變為 and 啊、去掉HTML元素啊之類的。它是文字字串在經過分詞之前的一個步驟,文字字串是按文字順序經過每個字串過濾器從而處理字串的
-
2、分詞器:見名知意,就是用來分詞的,也就是將字串拆分成詞條( 字 / 片語 ),這一步和Java中String的split()一樣的,通過指定的要求,把內容進行拆分,如:空格、標點符號
-
3、Token過濾器:這個玩意兒的作用就是 詞條經過每個Token過濾器,從而對資料再次進行篩選,如:字母大寫變小寫、去掉一些不重要的詞條內容、新增一些詞條( 如:同義詞 )
-
-
上述的內容不理解沒事,待會兒會用IK中文分詞器來演示,從而能夠更直觀的看到效果
在ES中,有提供好的內建分析器、我們也可以自定義、當然還有就是前面說的IK分詞器也可以做到( 而重點需要了解的就是IK中文分詞器 ,寫到這裡了,就突然想到一個事兒,牢騷一下:
- 就是有人私聊,說我部落格廢話太多了,有些不需要的東西寫出來幹什麼?他只想快速上手,其他不相關的濾過比較好,所以我在想:不把事情的前因後果瞭解到,就直接開幹好嗎?反正現在的我不把東西整明白,學東西都總感覺缺點什麼,從而導致學的東西不是我想要的,這樣讓我學起來很不爽,雖然理論確實整起來煩得很,我曾經開始接觸Java的時候也是這麼想的,就想著步子邁大一點,只管技術怎麼用就行,理論哪些廢話我不想聽,可是後來步子邁大了,扯到了胯,後面研究另外一些深一點的東西時,我總覺得少了一些東西,邊研究邊百度,但是知識點是散的,那不是我想要的知識體系,這種更不爽( 我個人偏向於:自己腦海有知識體系才好,但那時候學是散的,自己一邊整一邊摸索的 )。你敢相信我當初才用ES時,快速上手到什麼地步?就瞭解了一些基礎理論、在linux中用docker-conpose.yml編寫了ES和kibana的安裝方式( ES和Kibana都在一個yml檔案中,就是我第三篇ES —— 高階篇部落格中玩linux單機ES時說的那個yml安裝方式 )、還有就是Java API各種常用的查詢方式,然後就沒了,結果後面自己吃了大虧,後面我是把Java重學了一遍,所以別相信什麼所謂的“鍵盤不稀爛、程式碼不停幹”,只擼程式碼,會處理人際關係那有個鳥用,理論是築起高樓的地基,好了言歸正傳吧!!!
在演示在前,先玩kibana吧,原本打算放在後面的,但是越早熟悉越好嘛,所以先把kibana說明了
4.14.1、kibana
-
準備工作:去Elastic官網下載kibana,官網地址如下:
- https://www.elastic.co/cn/downloads/?elektra=home&storm=hero
- 這網站進去會很慢,進入之後就可以在首頁看到一個kibana了,但是需要注意:kibana的版本必須和ES的版本一致,在Java篇中已經說明過了,個人建議:把Windows版和linux版都下載了,玩的時候用Windows版的,linux版後續自己可能會用到
-
下載好了kibana之後,解壓到自己想要的目錄( 注:解壓會有點久,因為是用Vue寫的,裡面有模組module 要是解壓快的話,可能還下錯了 ),然後點選bin/kibana.bat即可啟動kibana
-
啟動之後就是上圖中的樣子,然後訪問圖中的地址即可,第一次進去會有一個選擇頁面,try / explore,選擇explore就可以了,進去之後就是如下介面
-
這是英文版,要是沒玩過大資料的話,那麼裡面的一些專業名詞根據英文來看根本不知道,所以:漢化吧,kibana本身就提供得有漢化的功能,只需要改動一個配置即可 —— 就是一個i18n配置而已
-
進入config/kibana.yml,滑到最底部
-
加上上面的資訊,然後重啟kibana就可以了( 但是:個人建議,先漢化一段時間,等熟悉哪些名詞了,然後再轉成英文 ,總之最後建議用英文,一是增加英文詞彙量,二是熟悉英文專業詞 ,反正目前搞程式設計任何東西用英文比用漢語有優勢,因為好多東西都是歪果仁的 )
-
漢化成功
-
kibana遵循的是rest風格( get、put、delete、post..... ),具體用法接下來玩分析器和後面都會慢慢熟悉
4.14.2、內建分析器
4.14.2.1、標準分析器 standard
-
這是根據Unicode定義的單詞邊界來劃分文字,將字母轉成小寫,去掉大部分的標點符號,從而得到的各種語言的最常用文字選擇,另外:這是ES的預設分析器,接下來演示一下
-
啟動ES( 這是用的單機,即重新解壓啟動的那種,另外方式也可以玩,但沒演示 )和kibana,開啟控制檯
-
編寫指令
GET _analyze
{
"analyzer": "standard", # analyzer 分析器 standard 標準分析器
"text": "my name is ZiXieQing" # text 文字標識 my name is ZiXieQing 自定義的文字內容
}
# 響應內容
{
"tokens" : [
{
"token" : "my", # 分詞之後的詞條
"start_offset" : 0,
"end_offset" : 2, # start和end叫偏移量
"type" : "<ALPHANUM>",
"position" : 0 # 當前詞條在整個文字中所處的位置
},
{
"token" : "name",
"start_offset" : 3,
"end_offset" : 7,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "is",
"start_offset" : 8,
"end_offset" : 10,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "zixieqing",
"start_offset" : 11,
"end_offset" : 20,
"type" : "<ALPHANUM>",
"position" : 3
}
]
}
- 從上圖可以看出:所謂標準分析器是將文字通過標點符號來分詞的( 空格、逗號... ,不信可以自行利用這些標點測試一下,觀察右邊分詞的結果 ),同時大寫轉小寫
4.14.2.2、簡單分析器 simple
- 簡單分析器是“按非字母的字元分詞,例如:數字、標點符號、特殊字元等,會去掉非字母的詞,大寫字母統一轉換成小寫”
4.14.2.3、空格分析器 whitespace
- 是簡單按照空格進行分詞,相當於按照空格split了一下,大寫字母不會轉換成小寫
4.14.2.4、去詞分析器 stop
- 會去掉無意義的詞( 此無意義是指語氣助詞等修飾性詞,補語文:語氣詞是疑問語氣、祈使語氣、感嘆語氣、肯定語氣和停頓語氣 ),例如:the、a、an 、this等,大寫字母統一轉換成小寫
4.14.2.5、不拆分分析器 keyword
- 就是將整個文字當作一個詞
4.14.3、IK中文分詞器
-
來個實驗
-
它把我的名字進行拆分了,這不是我想要的,我想要的“紫邪情”應該是一個完整的詞,同樣道理:想要特定的詞彙,如:ID號、使用者名稱....,這些不應該拆分,而ES內建分析器並不能做到,所以需要IK中文分詞器( 專門用來處理中文的 )
-
1、下載IK分詞器
- https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.8.0
- 注意:版本對應關係,還是和ES版本對應,https://github.com/medcl/elasticsearch-analysis-ik 這個連結進去之後有詳細的版本對應
- 要是感覺github下載慢的話,我把阿里雲盤更新了一遍,那裡面放出來的包有7.8.0的版本,這裡面也有一些其他的東西,有興趣的下載即可,另外:在這裡面有一個chrome-plugin包,這裡面有一些chrome的外掛,其中有一個fast-github,即:github下載加速器,可以整合到瀏覽器中,以後下載github的東西就不限速了,雲盤連結是:https://www.aliyundrive.com/s/oVC6WWthpUb
-
fast-github整合到goole之後如下:
-
這樣以後下載github的東西時,就有一個加速下載了,點選即可快速下載,如:
-
2、把IK解壓到ES/plugins中去,如我的:
-
3、重啟ES即可( kibana開著的話,也要關了重啟 ),注意觀察:重啟時會有一個IK載入過程
-
經過如上的操作之後,IK中文分詞器就配置成功了,接下來就來體驗一下( 啟動ES和kibana ),主要是為了瞭解IK中的另外兩種分詞方式:ik_max_word和ik_smart
-
ik_max_word是細粒度的分詞,就是:窮盡詞彙的各種組成
-
ik_smart是粗粒度的分詞
-
回到前面的問題,“紫邪情”是名字,我不想讓它分詞,怎麼做?上面哪些分詞都是在一個“詞典”中,所以我們自己搞一個詞典即可
-
1、建立一個.dic檔案 dic就是dictionary詞典的簡寫
-
2、在建立的dic檔案中新增不分詞的片語,儲存
-
3、把自定義的詞典放到ik中去,儲存
-
4、重啟ES和kibana
-
5、測試
-
可見,現在就把“紫邪情”組成片語不拆分了,前面玩的kibana漢化是怎麼做的?和這個的原理差不多
4.14.4、自定義分析器
- 這裡還有一個自定義分析器的知識點,這個不瞭解也罷,有興趣的自行百度百科瞭解一下
4.14.5、多玩幾次kibana
-
在第一篇高階篇中我便說過:kibana重要,只是經過前面這些介紹了使用之後,並不算熟悉,因此:多玩幾次吧
-
另外:就是前面說的kibana遵循rest風格,在ES中是怎麼玩的?總結下來其實就下面這些,要上手簡單得很,但理論卻是一直弄到現在
-
現在用kibana來演示幾個,其他的內容在在postman中怎麼弄,換一下即可( 其實不建議用postman測試,但是:前面用的一直是postman,專業的人做專業的事,kibana才是我們後端玩的 )
-
1、建立索引
-
2、檢視索引
-
3、刪除索引
-
4、建立文件( 自定義id )
-
5、檢視文件( 通過id查詢 )
-
6、修改文件( 區域性修改 )
- 驗證一下:
- 驗證一下:
-
7、建欄位型別
-
其他的也是差不多的玩法,在基礎篇中怎麼玩,稍微變一下就是kibana的玩法了
4.15、文件控制( 瞭解即可 )
-
所謂的文件控制就是:不斷更新的情況,試想:多程式不斷去更新文件,會造成什麼情況?會把其他人更新過的文件進行覆蓋更新了,而ES是怎麼解決這個問題的?
-
就是弄了一個鎖來實現的,和Redis一樣,也是用的樂觀鎖來實現的,這個其實沒什麼好說的,只需要看一下就知道了
-
上圖中的三個欄位就和鎖掛鉤的,version,版本號嘛,每次更新都會有一個版本號,這樣就解決了多程式修改從而造成的文件衝突了( 必須等到一個程式更新完了,另一個程式才可以更新,才可以拿到版本號嘛 ),當然:需要注意舊版本的ES在請求中加上version即可,但是新版本的ES需要使用 "if_seq_no=value" & "if_primary_term" =value來達到version的效果( 這兩個欄位一樣的放在請求路徑中即可 )
4.16、ES的優化
-
ES的所有索引和文件資料都是儲存在本地的磁碟中的,所以:磁碟能處理的吞吐量越大,節點就越穩定
-
要修改的話,是在config/elasticsearch.yml中改動
4.16.1、硬體方面
-
1、選用固態硬碟( 即:SSD ),它比機械硬碟好是因為:機械硬碟是通過旋轉馬達的驅動來進行的,所以這就會造成發熱、磨損,就會影響ES的效率,而SSD是使用晶片式的快閃記憶體來儲存資料的,效能比機械硬碟好得多
-
2、使用RAID 0 ( 獨立磁碟冗餘陣列 ),它是把連續的資料分散到多個磁碟上存取,這樣,系統有資料請求就可以被多個磁碟並行的執行,每個磁碟執行屬於它自己的那部分資料請求。這種資料上的並行操作可以充分利用匯流排的頻寬,顯著提高磁碟整體存取性( 不瞭解匯流排和頻寬的,真的有必要去學一下:計算機組成原理,這個知識在計算機組成原理的資料匯流排那裡有 , 當然:面向百度簡單瞭解一下也行 )
-
3、由上面的RAID 0可以聯想到另外一個解決方式:使用多塊硬碟,也就可以達到同樣的效果了( 有錢就行 ),是通過path data目錄配置把資料條分配到這些磁碟上面
-
4、不要把ES掛載到遠端上去儲存
4.16.2、分片策略
- 分片和副本不是亂分配的!分片處在不同節點還可以( 前提是節點中存的資料多 ),這樣就類似於關係型中分表,確實可以算做是優化,但是:如果一個節點中有多個分片了,那麼就會造成分片之間的資源競爭,也就會導致效能降低
所以分片和副本遵循下面的原則就可以了
-
1、每個分片佔用的磁碟容量不得超過ES的JVM的堆空間設定( 一般最大為32G ),假如:索引容量為1024G,那麼節點數量為:1024 / 32 = 32左右
-
2、分片數不超過節點數的3倍,就是為了預防一個節點上有多個分片的情況,萬一當前節點死了,那麼就算做了副本,也很容易導致叢集丟失資料
-
3、節點數 <= 主節點數 * ( 副本數 + 1 )
-
4、推遲分片分配
- 有可能一個節點宕掉了,但是後面它又恢復了,而這個節點原有資料是還在的,所以:推遲分片分配,從而減少ES的開銷,具體做法如下:
PUT /_all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}
- 可以全域性修改,也可以在建索引時修改
4.16.3、帶路由查詢
-
前面說過:路由計算公式
shard = hash( routing ) % number_of_primary_shards
-
而routing預設值就是文件id,所以查詢時把文件id帶上,如:前面玩kibana做的操作
-
不帶路由就會把分片和副本都查出來,然後進行輪詢,這效率想都想得到會慢一點嘛
4.16.4、記憶體優化
-
修改es的config/jvm.options
-
把上面的數字改了,Xms 表示堆的初始大小, Xmx 表示可分配的最大記憶體,ES預設是1G,這個數字在現實中是遠遠不夠了,改它的目的是:為了能夠在 Java 垃圾回收機制清理完堆記憶體後不需要重新分隔計算堆記憶體的大小而浪費資源,可以減輕伸縮堆大小帶來的壓力,但是也需要注意:改這兩個數值,需要確保 Xmx 和 Xms 的大小是相同的,另外就是:這兩個數值別超過32G啊,前面已經講過了
4.17、附上一些配置說明
引數名 | 引數值 | 說明 |
---|---|---|
cluster.name | elasticsearch | 配置 ES 的叢集名稱,預設值是 ES,建議改成與所存資料相關的名稱, ES 會自動發現在同一網段下的 叢集名稱相同的節點 |
node.name | node-1001 | 叢集中的節點名,在同一個叢集中不能重複。節點 的名稱一旦設定,就不能再改變了。當然,也可以 設 置 成 服 務 器 的 主 機 名 稱 , 例 如 node.name: ${hostname} |
node.master | true | 指定該節點是否有資格被選舉成為 Master 節點,默 認是 True,如果被設定為 True,則只是有資格成為 Master 節點,具體能否成為 Master 節點,需要通過選舉產生 |
node.data | true | 指定該節點是否儲存索引資料,預設為 True。資料的增、刪、改、查都是在 Data 節點完成的 |
index.number_of_shards | 1 | 設定索引分片個數,預設是 1 片。也可以在建立索引時設定該值,具體設定為多大值要根據資料量的大小來定。如果資料量不大,則設定成 1 時效率最高 |
index.number_of_replicas | 1 | 設定預設的索引副本個數,預設為 1 個。副本數越多,叢集的可用性越好,但是寫索引時需要同步的資料越多 |
transport.tcp.compress | true | 設定在節點間傳輸資料時是否壓縮,預設為 False |
discovery.zen.minimum_master_nodes | 1 | 設定在選舉 Master 節點時需要參與的最少的候選主節點數,預設為 1。如果使用預設值,則當網路不穩定時有可能會出現腦裂。 合理的 數 值 為 ( master_eligible_nodes / 2 )+1 , 其 中 master_eligible_nodes 表示叢集中的候選主節點數 |
discovery.zen.ping.timeout | 3s | 設定在叢集中自動發現其他節點時 Ping 連線的超時時間,同時也是選主節點的延遲時間,預設為 3 秒。 在較差的網路環境下需要設定得大一點,防止因誤判該節點的存活狀態而導致分片的轉移 |
4.18、SpringBoot整合ES
- ES官方學習文件中有,連結是:https://www.elastic.co/guide/index.html
- 然後點選other version,選擇對應的版本,如:我的是7.8
- 這裡面樣都有,點選:getting started看一下
- 選擇maven
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
-
建議:有時間去研究一下官網
4.19、說一些另外的理論吧
4.19.1、ES的master主節點選舉流程
-
1、首先選主是由ZenDiscovery來完成的( 它做了兩件事:一個是Ping過程 ———— 發現節點嘛 、二是Unicast過程 ———— 控制哪些節點需要Ping通 )
-
2、對所有可以成為master的節點( 檔案中設定的node.master: true )根據nodeId字典排序,每次“選舉節點( 即:參與投票選舉主節點的那個節點 )”都把自己知道的節點排一次序,就是把排好序的第一個節點( 第0位 )認為是主節點( 投一票 )
-
3、當某個節點的投票數達到一個值時( ( 可以成為master節點數n / 2 ) + 1 ),而該節點也投自己,那麼這個節點就是master節點,否則重新開始,直到選出master
-
另外注意:master節點的職責主要包括叢集、節點和索引的管理,不負責文件級別的管理;data節點可以關閉http功能
4.19.2、ES的叢集腦裂問題
導致的原因:
- 網路問題:叢集間的網路延遲導致一些節點訪問不到master, 認為master 掛掉了從而選舉出新的master,並對master上的分片和副本標紅,分配新的主分片
- 節點負載:主節點的角色既為master又為data,訪問量較大時可能會導致ES停止響應造成大面積延遲,此時其他節點得不到主節點的響應認為主節點掛掉了,會重新選取主節點
- 記憶體回收:data 節點上的ES程式佔用的記憶體較大,引發JVM的大規模記憶體回收,造成ES程式失去響應
腦裂問題解決方案:
-
減少誤判:discovery.zen ping_ timeout 節點狀態的響應時間,預設為3s,可以適當調大,如果master在該響應時間的範圍內沒有做出響應應答,判斷該節點已經掛掉了。調大引數( 如6s,discovery.zen.ping_timeout:6 ),可適當減少誤判
-
選舉觸發:discovery.zen.minimum. master nodes:1,該引數是用於控制選舉行為發生的最小叢集主節點數量。當備選主節點的個數大於等於該引數的值,且備選主節點中有該引數個節點認為主節點掛了,進行選舉。官方建議為(n / 2) +1, n為主節點個數(即有資格成為主節點的節點個數)
-
角色分離:即master節點與data節點分離,限制角色
- 主節點配置為:node master: true,node data: false
- 從節點置為:node master: false,node data: true
4.20、最後的最後
-
1、讓我弄知識點的哪些人,可能會讓你們失望了,原本我的打算是後續集合SpringBoot+Redis+ES做一個小Demo,但是:最近沒時間弄了,我需要去做另外一件重要的事情,因此:你們想鞏固ES知識的,去網上找ES實操專案吧
-
2、你們這些人,看完了我部落格的全系列ES知識、把實操專案弄了之後,記得再搜一下:ES面試題
- 我在阿里雲盤中上傳了一些面試題,Java全系列的,那裡面也有資料獲取地的公眾號二維碼,今後要最新的面試題就去哪裡找吧,但是有些問題答案沒有,所以需要自己總結一些東西,但是:我個人認為,那上面的面試題確實算弄到點上的
- 雲盤連結:https://www.aliyundrive.com/s/V6pPCAFZWnD