1. ElasticSearch快速入門
1.1. 基本介紹
-
ElasticSearch特色
Elasticsearch是實時的分布式搜索分析引擎,內部使用Lucene做索引與搜索
-
實時性:新增到 ES 中的資料在1秒后就可以被檢索到,這種新增資料對搜索的可見性稱為“準實時搜索”
-
分布式:意味著可以動態調整集群規模,彈性擴容
-
集群規模:可以擴展到上百臺服務器,處理PB級結構化或非結構化資料
-
各節點組成對等的網路結構,某些節點出現故障時會自動分配其他節點代替其進行作業
Lucene是Java語言撰寫的全文搜索框架,用于處理純文本的資料,但它只是一個庫,提供建立索引、執行搜索等介面,但不包含分布式服務,這些正是 ES 做的
-
-
ElasticSearch使用場景
ElasticSearch廣泛應用于各行業領域, 比如維基百科, GitHub的代碼搜索,電商網站的大資料日志統計分析, BI系統報表統計分析等,
-
提供分布式的搜索引擎和資料分析引擎
比如百度,網站的站內搜索,IT系統的檢索, 資料分析比如熱點詞統計, 電商網站商品TOP排名等,
-
全文檢索,結構化檢索,資料分析
支持全文檢索, 比如查找包含指定名稱的商品資訊; 支持結構檢索, 比如查找某個分類下的所有商品資訊;
還可以支持高級資料分析, 比如統計某個商品的點擊次數, 某個商品有多少用戶購買等等,
-
支持海量資料準實時的處理
采用分布式節點, 將資料分散到多臺服務器上去存盤和檢索, 實作海量資料的處理, 比如統計用戶的行為日志, 能夠在秒級別對資料進行檢索和分析,
-
-
ElasticSearch基本概念介紹
ElasticSearch Relational Database Index Database Type Table Document Row Field Column Mapping Schema Everything is indexed Index Query DSL SQL GET http://... SELECT * FROM table... PUT http://... UPDATE table SET... -
索引(Index)
相比傳統的關系型資料庫,索引相當于SQL中的一個【資料庫】,或者一個資料存盤方案(schema),
-
型別(Type)
一個索引內部可以定義一個或多個型別, 在傳統關系資料庫來說, 型別相當于【表】的概念,
-
檔案(Document)
檔案是Lucene索引和搜索的原子單位,它是包含了一個或多個域的容器,采用JSON格式表示,相當于傳統資料庫【行】概念
-
集群(Cluster)
集群是由一臺及以上主機節點組成并提供存盤及搜索服務, 多節點組成的集群擁有冗余能力,它可以在一個或幾個節點出現故障時保證服務的整體可用性,
-
節點(Node)
Node為集群中的單臺節點,其可以為master節點亦可為slave節點(節點屬性由集群內部選舉得出)并提供存盤相關資料的功能
-
切片(shards)
切片是把一個大檔案分割成多個小檔案然后分散存盤在集群中的多個節點上, 可以將其看作mysql的分庫分表概念, Shard有兩種型別:primary主片和replica副本,primary用于檔案存盤,每個新的索引會自動創建5個Primary shard;Replica shard是Primary Shard的副本,用于冗余資料及提高搜索性能,
-

注意: ES7之后Type被舍棄,只有Index(等同于資料庫+表定義)和Document(檔案,行記錄),
1.2 ElasticSearch安裝
-
下載ElasticSearch服務
下載最新版ElasticSearch7.10.2: https://www.elastic.co/cn/start
-
解壓安裝包
tar -xvf elasticsearch-7.10.2-linux-x86_64.tar.gz -
ElasticSearch不能以Root身份運行, 需要單獨創建一個用戶
1. groupadd elsearch 2. useradd elsearch -g elsearch -p elasticsearch 3. chown -R elsearch:elsearch /usr/local/elasticsearch-7.10.2執行以上命令,創建一個名為elsearch用戶, 并賦予目錄權限,
-
修改組態檔
vi config/elasticsearch.yml, 默認情況下會系結本機地址, 外網不能訪問, 這里要修改下:
# 外網訪問地址 network.host: 0.0.0.0 -
關閉防火墻
systemctl stop firewalld.service systemctl disable firewalld.service -
指定JDK版本
-
最新版的ElasticSearch需要JDK11版本, 下載JDK11壓縮包, 并進行解壓,
-
修改環境組態檔
vi bin/elasticsearch-env
參照以下位置, 追加一行, 設定JAVA_HOME, 指定JDK11路徑,
JAVA_HOME=/usr/local/jdk-11.0.11 # now set the path to java if [ ! -z "$JAVA_HOME" ]; then JAVA="$JAVA_HOME/bin/java" else if [ "$(uname -s)" = "Darwin" ]; then # OSX has a different structure JAVA="$ES_HOME/jdk/Contents/Home/bin/java" else JAVA="$ES_HOME/jdk/bin/java" fi fi
-
-
啟動ElasticSearch
-
切換用戶
su elsearch
-
以后臺常駐方式啟動
bin/elasticsearch -d
-
-
問題記錄
出現max virtual memory areas vm.max_map_count [65530] is too low, increase to at least 錯誤資訊
修改系統配置:
-
vi /etc/sysctl.conf
添加
vm.max_map_count=655360
執行生效
sysctl -p
-
vi /etc/security/limits.conf
在檔案末尾添加
* soft nofile 65536 * hard nofile 131072 * soft nproc 2048 * hard nproc 4096 elsearch soft nproc 125535 elsearch hard nproc 125535重新切換用戶即可:
su - elsearch
-
-
訪問驗證
訪問地址:http://192.168.116.140:9200/_cat/health

啟動狀態有green、yellow和red, green是代表啟動正常,
1.3 Kibana服務安裝
Kibana是一個針對Elasticsearch的開源分析及可視化平臺,用來搜索、查看互動存盤在Elasticsearch索引中的資料,
-
到官網下載, Kibana安裝包, 與之對應7.10.2版本, 選擇Linux 64位版本下載,并進行解壓,
tar -xvf kibana-7.10.2-linux-x86_64.tar.gz -
Kibana啟動不能使用root用戶, 使用上面創建的elsearch用戶, 進行賦權:
chown -R elsearch:elsearch kibana-7.10.2-linux-x86_64 -
修改組態檔
vi config/kibana.yml , 修改以下配置:
# 服務埠 server.port: 5601 # 服務地址 server.host: "0.0.0.0" # elasticsearch服務地址 elasticsearch.hosts: ["http://192.168.116.140:9200"] -
啟動kibana
./kibana -q看到以下日志, 代表啟動正常
log [01:40:00.143] [info][listening] Server running at http://0.0.0.0:5601如果出現啟動失敗的情況, 要檢查集群各節點的日志, 確保服務正常運行狀態,
-
訪問服務
http://192.168.116.140:5601/app/home#/
1.4 ES的基礎操作
-
進入Kibana管理后臺
地址: http://192.168.116.140:5601
進入"Dev Tools"欄:

在Console中輸入命令進行操作,
-
分片設定:
這里增加名為orders的索引, 因為是單節點, 如果副本數, 是會出現錯誤,
PUT orders { "settings": { "index": { "number_of_shards": 2, "number_of_replicas": 2 } } }查看索引資訊, 會出現yellow提示:

因為單節點模式, 只有主節點資訊:
洗掉重新創建:
PUT orders
{
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 0
}
}
}
將分片數設為0, 再次查看, 則顯示正常:

-
索引
3.1 新建索引orders
## 創建索引 PUT orders3.2 查詢索引orders
## 查詢索引 GET orders

通過查詢命令, 能查看到對應資訊, 默認分片數和副本數都為1:
"number_of_shards" : "1", ## 主分片數
"number_of_replicas" : "1", ## 副分片數

3.3 洗掉索引
## 洗掉索引
DELETE orders
3.4 索引的設定
## 設定索引
PUT orders
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
}
-
檔案
4.1 創建檔案
## 創建檔案,生成默認的檔案id POST orders/_doc { "name": "襪子1雙", "price": "200", "count": 1, "address": "北京市" } ## 創建檔案,生成自定義檔案id POST orders/_doc/1 { "name": "襪子1雙", "price": "2", "count": 1, "address": "北京市" }4.2 查詢檔案
## 根據指定的id查詢 GET orders/_doc/1 ## 根據指定條件查詢檔案 GET orders/_search { "query": { "match": { "address": "北京市" } } } ## 查詢全部檔案 GET orders/_search4.3 更新檔案
## 更新檔案 POST orders/_doc/1 { "price": "200" } ## 更新檔案 POST orders/_update/1 { "doc": { "price": "200" } }4.4 洗掉檔案
## 洗掉檔案 DELETE orders/_doc/1 -
域
對于映射,只能進行欄位添加,不能對欄位進行修改或洗掉,如有需要,則重新創建映射,
## 設定mapping資訊 PUT orders/_mappings { "properties":{ "price": { "type": "long" } } } ## 設定分片和映射 PUT orders { "settings": { "index": { "number_of_shards": 1, "number_of_replicas": 0 } }, "mappings": { "properties": { "name": { "type": "text" }, "price": { "type": "long" }, "count": { "type": "long" }, "address": { "type": "text" } } } }
1.5 ES資料型別
整體資料型別結構:

-
String 型別
主要分為text與keyword兩種型別,兩者區別主要在于能否分詞,
-
text型別
會進行分詞處理, 分詞器默認采用的是standard,
-
keyword型別
不會進行分詞處理,在ES的倒排索引中存盤的是完整的字串,
-
-
Date時間型別
資料庫里的日期型別需要規范具體的傳入格式, ES是可以控制,自適應處理,
傳遞不同的時間型別:
PUT my_date_index/_doc/1 { "date": "2021-01-01" } PUT my_date_index/_doc/2 { "date": "2021-01-01T12:10:30Z" } PUT my_date_index/_doc/3 { "date": 1520071600001 } ## 查看日期資料: GET my_date_index/_mapping

ES的Date型別允許可以使用的格式有:
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
epoch_millis(毫秒值)
-
復合型別
復雜型別主要有三種: Array、object、nested,
-
Array型別: 在Elasticsearch中,陣列不需要宣告專用的欄位資料型別,但是,在陣列中的所有值都必須具有相同的資料型別,舉例:
POST orders/_doc/1 { "goodsName":["足球","籃球","兵乓球", 3] } POST orders/_doc/1 { "goodsName":["足球","籃球","兵乓球"] } -
object型別: 用于存盤單個JSON物件, 類似于JAVA中的物件型別, 可以有多個值, 比如LIST
-
Nested型別
用于存盤多個JSON物件組成的陣列,
nested型別是object型別中的一個特例,可以讓物件陣列獨立索引和查詢,舉例:
創建nested型別的索引:
PUT my_index { "mappings": { "properties": { "users": { "type": "nested" } } } }發出查詢請求:
GET my_index/_search { "query": { "bool": { "must": [ { "nested": { "path": "users", "query": { "bool": { "must": [ { "match": { "users.name": "John" } }, { "match": { "users.age": "21" } } ] } } } } ] } } }采用以前的條件, 這個時候查不到任何結果, 將年齡改成22, 就可以找出對應的資料:
"hits" : [ { "_index" : "my_index", "_type" : "_doc", "_id" : "1", "_score" : 1.89712, "_source" : { "group" : "america", "users" : [ { "name" : "John", "age" : "22" }, { "name" : "Alice", "age" : "21" } ] } } ]
-
GEO地理位置型別
現在大部分APP都有基于位置搜索的功能, 比如交友、購物應用等,這些功能是基于GEO搜索實作的,
對于GEO地理位置型別,分為地理坐標型別:Geo-point, 和形狀:Geo-shape 兩種型別,
經緯度 英文 簡寫 正數 負數 維度 latitude lat 北緯 南緯 經度 longitude lon或lng 東經 西經 創建地理位置索引:
PUT my_locations { "mappings": { "properties": { "location": { "type": "geo_point" } } } }添加地理位置資料:
# 采用object物件型別 PUT my_locations/_doc/1 { "user": "張三", "text": "Geo-point as an object", "location": { "lat": 41.12, "lon": -71.34 } } # 采用string型別 PUT my_locations/_doc/2 { "user": "李四", "text": "Geo-point as a string", "location": "45.12,-75.34" } # 采用geohash型別(geohash演算法可以將多維資料映射為一串字符) PUT my_locations/_doc/3 { "user": "王二麻子", "text": "Geo-point as a geohash", "location": "drm3btev3e86" } # 采用array陣列型別 PUT my_locations/_doc/4 { "user": "木頭老七", "text": "Geo-point as an array", "location": [ -80.34, 51.12 ] }需求:搜索出距離我{"lat" : 40,"lon" : -70} 200km范圍內的人:
GET my_locations/_search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "geo_distance": { "distance": "200km", "location": { "lat": 40, "lon": -70 } } } } } }
-
2. ES高可用集群配置
2.1 ElasticSearch集群介紹
-
主節點(或候選主節點)
主節點負責創建索引、洗掉索引、分配分片、追蹤集群中的節點狀態等作業, 主節點負荷相對較輕, 客戶端請求可以直接發往任何節點, 由對應節點負責分發和回傳處理結果,
一個節點啟動之后, 采用 Zen Discovery機制去尋找集群中的其他節點, 并與之建立連接, 集群會從候選主節點中選舉出一個主節點, 并且一個集群只能選舉一個主節點, 在某些情況下, 由于網路通信丟包等問題, 一個集群可能會出現多個主節點, 稱為“腦裂現象”, 腦裂會存在丟失資料的可能, 因為主節點擁有最高權限, 它決定了什么時候可以創建索引, 分片如何移動等, 如果存在多個主節點, 就會產生沖突, 容易產生資料丟失,要盡量避免這個問題, 可以通過 discovery.zen.minimum_master_nodes 來設定最少可作業的候選主節點個數, 建議設定為(候選主節點/2) + 1 比如三個候選主節點,該配置項為 (3/2)+1 ,來保證集群中有半數以上的候選主節點, 沒有足夠的master候選節點, 就不會進行master節點選舉,減少腦裂的可能,
主節點的引數設定:
node.master = true node.data = https://www.cnblogs.com/jiagooushi/archive/2022/07/26/false -
資料節點
資料節點負責資料的存盤和CRUD等具體操作,資料節點對機器配置要求比較高、,首先需要有足夠的磁盤空間來存盤資料,其次資料操作對系統CPU、Memory和IO的性能消耗都很大,通常隨著集群的擴大,需要增加更多的資料節點來提高可用性,
資料節點的引數設定:
node.master = false node.data = https://www.cnblogs.com/jiagooushi/archive/2022/07/26/true -
客戶端節點
客戶端節點不做候選主節點, 也不做資料節點的節點,只負責請求的分發、匯總等等,增加客戶端節點型別更多是為了負載均衡的處理,
node.master = false node.data = https://www.cnblogs.com/jiagooushi/archive/2022/07/26/false -
提取節點(預處理節點)
能執行預處理管道,有自己獨立的任務要執行, 在索引資料之前可以先對資料做預處理操作, 不負責資料存盤也不負責集群相關的事務,
引數設定:
node.ingest = true -
協調節點
協調節點,是一種角色,而不是真實的Elasticsearch的節點,不能通過配置項來指定哪個節點為協調節點,集群中的任何節點,都可以充當協調節點的角色,當一個節點A收到用戶的查詢請求后,會把查詢子句分發到其它的節點,然后合并各個節點回傳的查詢結果,最后回傳一個完整的資料集給用戶,在這個程序中,節點A扮演的就是協調節點的角色,
ES的一次請求非常類似于Map-Reduce操作,在ES中對應的也是兩個階段,稱之為scatter-gather,客戶端發出一個請求到集群的任意一個節點,這個節點就是所謂的協調節點,它會把請求轉發給含有相關資料的節點(scatter階段),這些資料節點會在本地執行請求然后把結果回傳給協調節點,協調節點將這些結果匯總(reduce)成一個單一的全域結果集(gather階段) ,
-
部落節點
在多個集群之間充當聯合客戶端, 它是一個特殊的客戶端 , 可以連接多個集群,在所有連接的集群上執行搜索和其他操作, 部落節點從所有連接的集群中檢索集群狀態并將其合并成全域集群狀態, 掌握這一資訊,就可以對所有集群中的節點執行讀寫操作,就好像它們是本地的, 請注意,部落節點需要能夠連接到每個配置的集群中的每個單個節點,
2.2 ElasticSearch集群原理
2.2.1 集群分布式原理
ES集群可以根據節點數, 動態調整主分片與副本數, 做到整個集群有效均衡負載,
單節點狀態下:

兩個節點狀態下, 副本數為1:

三個節點狀態下, 副本數為1:

三個節點狀態下, 副本數為2:

2.2.2 分片處理機制
設定分片大小的時候, 需預先做好容量規劃, 如果節點數過多, 分片數過小, 那么新的節點將無法分片, 不能做到水平擴展, 并且單個分片資料量太大, 導致資料重新分配耗時過大,
假設一個集群中有一個主節點、兩個資料節點,orders索引的分片分布情況如下所示:
PUT orders
{
"settings":{
"number_of_shards":2, ## 主分片 2
"number_of_replicas":2 ## 副分片 4
}
}

整個集群中存在P0和P1兩個主分片, P0對應的兩個R0副本分片, P1對應的是兩個R1副本分片,
2.2.3 新建索引處理流程

-
寫入的請求會進入主節點, 如果是NODE2副本接收到寫請求, 會將它轉發至主節點,
-
主節點接收到請求后, 根據documentId做取模運算(外部沒有傳遞documentId,則會采用內部自增ID),
如果取模結果為P0,則會將寫請求轉發至NODE3處理,
-
NODE3節點寫請求處理完成之后, 采用異步方式, 將資料同步至NODE1和NODE2節點,
2.2.4 讀取索引處理流程

- 讀取的請求進入MASTER節點, 會根據取模結果, 將請求轉發至不同的節點,
- 如果取模結果為R0,內部還會有負載均衡處理機制,如果上一次的讀取請求是在NODE1的R0, 那么當前請求會轉發至NODE2的R0, 保障每個節點都能夠均衡的處理請求資料,
- 讀取的請求如果是直接落至副本節點, 副本節點會做判斷, 若有資料則回傳,沒有的話會轉發至其他節點處理,
2.3 ElasticSearch集群部署規劃
準備一臺虛擬機:
192.168.116.140: Node-1 (節點一), 埠:9200, 9300
192.168.116.140: Node-2 (節點二),埠:9201, 9301
192.168.116.140: Node-3 (節點三),埠:9202, 9302
2.4 ElasticSearch集群配置
-
解壓安裝包:
mkdir /usr/local/cluster cd /usr/local/cluster tar -xvf elasticsearch-7.10.2-linux-x86_64.tar.gz將安裝包解壓至/usr/local/cluster目錄,
-
修改集群組態檔:
vi /usr/local/cluster/elasticsearch-7.10.2-node1/config/elasticsearch.yml192.168.116.140, 第一臺節點配置內容:
# 集群名稱 cluster.name: my-application #節點名稱 node.name: node-1 # 系結IP地址 network.host: 192.168.116.140 # 指定服務訪問埠 http.port: 9200 # 指定API端戶端呼叫埠 transport.tcp.port: 9300 #集群通訊地址 discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #集群初始化能夠參選的節點資訊 cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #開啟跨域訪問支持,默認為false http.cors.enabled: true ##跨域訪問允許的域名, 允許所有域名 http.cors.allow-origin: "*"修改目錄權限:
chown -R elsearch:elsearch /usr/local/cluster/elasticsearch-7.10.2-node1 -
復制ElasticSearch安裝目錄:
復制其余兩個節點:
cd /usr/local/cluster cp -r elasticsearch-7.10.2-node1 elasticsearch-7.10.2-node2 cp -r elasticsearch-7.10.2-node1 elasticsearch-7.10.2-node3 -
修改其余節點的配置:
192.168.116.140 第二臺節點配置內容:
# 集群名稱 cluster.name: my-application #節點名稱 node.name: node-2 # 系結IP地址 network.host: 192.168.116.140 # 指定服務訪問埠 http.port: 9201 # 指定API端戶端呼叫埠 transport.tcp.port: 9301 #集群通訊地址 discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #集群初始化能夠參選的節點資訊 cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #開啟跨域訪問支持,默認為false http.cors.enabled: true ##跨域訪問允許的域名, 允許所有域名 http.cors.allow-origin: "*"192.168.116.140 第三臺節點配置內容:
# 集群名稱 cluster.name: my-application #節點名稱 node.name: node-3 # 系結IP地址 network.host: 192.168.116.140 # 指定服務訪問埠 http.port: 9202 # 指定API端戶端呼叫埠 transport.tcp.port: 9302 #集群通訊地址 discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #集群初始化能夠參選的節點資訊 cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"] #開啟跨域訪問支持,默認為false http.cors.enabled: true ##跨域訪問允許的域名, 允許所有域名 http.cors.allow-origin: "*" -
啟動集群節點
先切換elsearch用戶, 在三臺節點依次啟動服務:
su elsearch /usr/local/cluster/elasticsearch-7.10.2-node1/bin/elasticsearch -d /usr/local/cluster/elasticsearch-7.10.2-node2/bin/elasticsearch -d /usr/local/cluster/elasticsearch-7.10.2-node3/bin/elasticsearch -d注意: 如果啟動出現錯誤, 將各節點的data目錄清空, 再重啟服務,
-
集群狀態查看
集群安裝與啟動成功之后, 執行請求: http://192.168.116.140:9200/_cat/nodes?pretty
可以看到三個節點資訊,三個節點會自行選舉出主節點:

2.5 ElasticSearch集群分片測驗
修改kibana的組態檔,指向創建的集群節點:
elasticsearch.hosts: ["http://192.168.116.140:9200","http://192.168.116.140:9201","http://192.168.116.140:9202"]
重啟kibana服務, 進入控制臺:
http://192.168.116.140:5601/app/home#/
再次創建索引(副本數量范圍內):
PUT orders
{
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 2
}
}
}
可以看到, 這次結果是正常:

集群并非可以隨意增加副本數量, 創建索引(超出副本數量范圍):
PUT orders
{
"settings": {
"index": {
"number_of_shards": 2,
"number_of_replicas": 5
}
}
}
可以看到出現了yellow警告錯誤:

好了,至此ES集群搭建完畢,歡迎志同道合的小伙伴,一起交流學習成長,進階架構師,Fighting!!!
本文由傳智教育博學谷 - 狂野架構師教研團隊發布
如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支持是我堅持創作的動力
轉載請注明出處!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500362.html
標籤:其他
