4 – 基於ELK的ElasticSearch 7.8.x技術整理 – 高級篇( 續 ) – 更新完畢
0、前言
- 這裡面一些理論和前面的知識點掛鉤的,所以:建議看一下另外3篇知識內容
- 基礎篇://www.cnblogs.com/xiegongzi/p/15684307.html
- java操作篇://www.cnblogs.com/xiegongzi/p/15690534.html
- 高級篇1://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幹嘛,浪費性能而已,所以此時:你要的是查詢速度,而不是近實時搜索,因此:可以通過一個配置來進行改動,從而降低每個索引的刷新頻率
//ip:port/index_name/_settings # 請求方式:put
# 請求體內容
{
"settings": {
"refresh_interval": "60s"
}
}
- refresh_interval可以在既存索引上進行動態更新。在生產環境中,當你正在建立一個大的新索引時,可以先關閉自動刷新,待開始使用該索引時,再把它們調回來( 雖然有點麻煩,但是按照ES這個玩意兒來說,確實需要這麼做比較好 )
# 關閉自動刷新
//ip:port/users/_settings # 請求方式:put
# 請求體內容
{
"refresh_interval": -1
}
# 每一秒刷新
//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,官網地址如下:
- //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本身就提供得有漢化的功能,只需要改動一個配置即可 —— 就是一個i1bn配置而已
-
進入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分詞器
- //github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.8.0
- 注意:版本對應關係,還是和ES版本對應,//github.com/medcl/elasticsearch-analysis-ik 這個鏈接進去之後有詳細的版本對應
- 要是感覺github下載慢的話,我把阿里雲盤更新了一遍,那裡面放出來的包有7.8.0的版本,這裡面也有一些其他的東西,有興趣的下載即可,另外:在這裡面有一個chrome-plugin包,這裡面有一些chrome的插件,其中有一個fast-github,即:github下載加速器,可以集成到瀏覽器中,以後下載github的東西就不限速了,雲盤鏈接是://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測試,專業的人做專業的事,kibana才是我們後端玩的 )
-
1、創建索引
-
2、查看索引
-
3、創建文檔( 隨機id值,想要自定義id值,在後面加上即可 )
-
4、刪除索引
-
5、創建文檔( 自定義id )
-
6、查看文檔( 通過id查詢 )
-
7、修改文檔( 局部修改 )
- 驗證一下:
- 驗證一下:
-
8、建欄位類型
-
其他的也是差不多的玩法,在基礎篇中怎麼玩,稍微變一下就是kibana的玩法了
4.15、文檔控制( 了解即可 )
-
所謂的文檔控制就是:不斷更新的情況,試想:多進程不斷去更新文檔,會造成什麼情況?會把其他人更新過的文檔進行覆蓋更新了,而ES是怎麼解決這個問題的?
-
就是弄了一個鎖來實現的,和Redis一樣,也是用的樂觀鎖來實現的,這個其實沒什麼好說的,只需要看一下就知道了
-
上圖中·的三個欄位就和鎖掛鉤的,version,版本號嘛,每次更新都會有一個版本號,這樣就解決了多進程修改從而造成的文檔衝突了( 必須等到一個進程更新完了,另一個進程才可以更新 ),當然:需要注意舊版本的ES在請求中加上version即可,但是新版本的ES需要使用 if”_seq_no” 和”if_primary_term” 來達到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官方學習文檔中有,鏈接是://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