【超詳細(xì)】手把手教你ElasticSearch集群搭建

1. ElasticSearch快速入門

1.1. 基本介紹

  • ElasticSearch特色

    Elasticsearch是實(shí)時(shí)的分布式搜索分析引擎,內(nèi)部使用Lucene做索引與搜索

    • 實(shí)時(shí)性:新增到 ES 中的數(shù)據(jù)在1秒后就可以被檢索到,這種新增數(shù)據(jù)對(duì)搜索的可見性稱為“準(zhǔn)實(shí)時(shí)搜索”

    • 分布式:意味著可以動(dòng)態(tài)調(diào)整集群規(guī)模,彈性擴(kuò)容

    • 集群規(guī)模:可以擴(kuò)展到上百臺(tái)服務(wù)器,處理PB級(jí)結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)

    • 各節(jié)點(diǎn)組成對(duì)等的網(wǎng)絡(luò)結(jié)構(gòu),某些節(jié)點(diǎn)出現(xiàn)故障時(shí)會(huì)自動(dòng)分配其他節(jié)點(diǎn)代替其進(jìn)行工作

Lucene是Java語言編寫的全文搜索框架,用于處理純文本的數(shù)據(jù),但它只是一個(gè)庫,提供建立索引、執(zhí)行搜索等接口,但不包含分布式服務(wù),這些正是 ES 做的

  • ElasticSearch使用場(chǎng)景

    ElasticSearch廣泛應(yīng)用于各行業(yè)領(lǐng)域, 比如維基百科, GitHub的代碼搜索,電商網(wǎng)站的大數(shù)據(jù)日志統(tǒng)計(jì)分析, BI系統(tǒng)報(bào)表統(tǒng)計(jì)分析等。

    • 提供分布式的搜索引擎和數(shù)據(jù)分析引擎

      比如百度,網(wǎng)站的站內(nèi)搜索,IT系統(tǒng)的檢索, 數(shù)據(jù)分析比如熱點(diǎn)詞統(tǒng)計(jì), 電商網(wǎng)站商品TOP排名等。

    • 全文檢索,結(jié)構(gòu)化檢索,數(shù)據(jù)分析

      支持全文檢索, 比如查找包含指定名稱的商品信息; 支持結(jié)構(gòu)檢索, 比如查找某個(gè)分類下的所有商品信息;

      還可以支持高級(jí)數(shù)據(jù)分析, 比如統(tǒng)計(jì)某個(gè)商品的點(diǎn)擊次數(shù), 某個(gè)商品有多少用戶購買等等。

    • 支持海量數(shù)據(jù)準(zhǔn)實(shí)時(shí)的處理

      采用分布式節(jié)點(diǎn), 將數(shù)據(jù)分散到多臺(tái)服務(wù)器上去存儲(chǔ)和檢索, 實(shí)現(xiàn)海量數(shù)據(jù)的處理, 比如統(tǒng)計(jì)用戶的行為日志, 能夠在秒級(jí)別對(duì)數(shù)據(jù)進(jìn)行檢索和分析。

  • 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)

      相比傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,索引相當(dāng)于SQL中的一個(gè)【數(shù)據(jù)庫】,或者一個(gè)數(shù)據(jù)存儲(chǔ)方案(schema)。

    • 類型(Type)

      一個(gè)索引內(nèi)部可以定義一個(gè)或多個(gè)類型, 在傳統(tǒng)關(guān)系數(shù)據(jù)庫來說, 類型相當(dāng)于【表】的概念。

    • 文檔(Document)

      文檔是Lucene索引和搜索的原子單位,它是包含了一個(gè)或多個(gè)域的容器,采用JSON格式表示。相當(dāng)于傳統(tǒng)數(shù)據(jù)庫【行】概念

    • 集群(Cluster)

      集群是由一臺(tái)及以上主機(jī)節(jié)點(diǎn)組成并提供存儲(chǔ)及搜索服務(wù), 多節(jié)點(diǎn)組成的集群擁有冗余能力,它可以在一個(gè)或幾個(gè)節(jié)點(diǎn)出現(xiàn)故障時(shí)保證服務(wù)的整體可用性。

    • 節(jié)點(diǎn)(Node)

      Node為集群中的單臺(tái)節(jié)點(diǎn),其可以為master節(jié)點(diǎn)亦可為slave節(jié)點(diǎn)(節(jié)點(diǎn)屬性由集群內(nèi)部選舉得出)并提供存儲(chǔ)相關(guān)數(shù)據(jù)的功能

    • 切片(shards)

      切片是把一個(gè)大文件分割成多個(gè)小文件然后分散存儲(chǔ)在集群中的多個(gè)節(jié)點(diǎn)上, 可以將其看作mysql的分庫分表概念。 Shard有兩種類型:primary主片和replica副本,primary用于文檔存儲(chǔ),每個(gè)新的索引會(huì)自動(dòng)創(chuàng)建5個(gè)Primary shard;Replica shard是Primary Shard的副本,用于冗余數(shù)據(jù)及提高搜索性能。

file

注意: ES7之后Type被舍棄,只有Index(等同于數(shù)據(jù)庫+表定義)和Document(文檔,行記錄)。

1.2 ElasticSearch安裝

  1. 下載ElasticSearch服務(wù)

    下載最新版ElasticSearch7.10.2: https://www.elastic.co/cn/start

  2. 解壓安裝包

    tar -xvf elasticsearch-7.10.2-linux-x86_64.tar.gz
    
  3. ElasticSearch不能以Root身份運(yùn)行, 需要單獨(dú)創(chuàng)建一個(gè)用戶

    1. groupadd elsearch
    2. useradd elsearch -g elsearch -p elasticsearch
    3. chown -R elsearch:elsearch  /usr/local/elasticsearch-7.10.2
    

    執(zhí)行以上命令,創(chuàng)建一個(gè)名為elsearch用戶, 并賦予目錄權(quán)限。

  4. 修改配置文件

    vi config/elasticsearch.yml, 默認(rèn)情況下會(huì)綁定本機(jī)地址, 外網(wǎng)不能訪問, 這里要修改下:

    # 外網(wǎng)訪問地址
    network.host: 0.0.0.0
    
  5. 關(guān)閉防火墻

    systemctl stop  firewalld.service
    systemctl disable  firewalld.service
    
  1. 指定JDK版本

    • 最新版的ElasticSearch需要JDK11版本, 下載JDK11壓縮包, 并進(jìn)行解壓。

    • 修改環(huán)境配置文件

      vi bin/elasticsearch-env

      參照以下位置, 追加一行, 設(shè)置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
      
  1. 啟動(dòng)ElasticSearch

    • 切換用戶

      su elsearch

    • 以后臺(tái)常駐方式啟動(dòng)

      bin/elasticsearch -d

  1. 問題記錄

    出現(xiàn)max virtual memory areas vm.max_map_count [65530] is too low, increase to at least 錯(cuò)誤信息

    修改系統(tǒng)配置:

    • vi /etc/sysctl.conf

      添加

      vm.max_map_count=655360

      執(zhí)行生效

      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

  2. 訪問驗(yàn)證

    訪問地址:http://192.168.116.140:9200/_cat/health

file

啟動(dòng)狀態(tài)有g(shù)reen、yellow和red。 green是代表啟動(dòng)正常。

1.3 Kibana服務(wù)安裝

Kibana是一個(gè)針對(duì)Elasticsearch的開源分析及可視化平臺(tái),用來搜索、查看交互存儲(chǔ)在Elasticsearch索引中的數(shù)據(jù)。

  1. 到官網(wǎng)下載, Kibana安裝包, 與之對(duì)應(yīng)7.10.2版本, 選擇Linux 64位版本下載,并進(jìn)行解壓。

    tar -xvf kibana-7.10.2-linux-x86_64.tar.gz
    
  2. Kibana啟動(dòng)不能使用root用戶, 使用上面創(chuàng)建的elsearch用戶, 進(jìn)行賦權(quán):

    chown -R elsearch:elsearch kibana-7.10.2-linux-x86_64
    
  3. 修改配置文件

    vi config/kibana.yml , 修改以下配置:

    # 服務(wù)端口
    server.port: 5601
    # 服務(wù)地址
    server.host: "0.0.0.0"
    # elasticsearch服務(wù)地址
    elasticsearch.hosts: ["http://192.168.116.140:9200"]
    
  4. 啟動(dòng)kibana

    ./kibana -q
    

    看到以下日志, 代表啟動(dòng)正常

    log   [01:40:00.143] [info][listening] Server running at http://0.0.0.0:5601
    

    如果出現(xiàn)啟動(dòng)失敗的情況, 要檢查集群各節(jié)點(diǎn)的日志, 確保服務(wù)正常運(yùn)行狀態(tài)。

  5. 訪問服務(wù)

    http://192.168.116.140:5601/app/home#/

1.4 ES的基礎(chǔ)操作

  1. 進(jìn)入Kibana管理后臺(tái)

    地址: http://192.168.116.140:5601

    進(jìn)入"Dev Tools"欄:

file

在Console中輸入命令進(jìn)行操作。

  1. 分片設(shè)置:

    這里增加名為orders的索引, 因?yàn)槭菃喂?jié)點(diǎn), 如果副本數(shù), 是會(huì)出現(xiàn)錯(cuò)誤。

    PUT orders
    {
        "settings": {
            "index": {
                "number_of_shards": 2,
                "number_of_replicas": 2
            }
        }
    }
    

    查看索引信息, 會(huì)出現(xiàn)yellow提示:

file

因?yàn)閱喂?jié)點(diǎn)模式, 只有主節(jié)點(diǎn)信息:

刪除重新創(chuàng)建:

PUT orders
{
    "settings": {
        "index": {
            "number_of_shards": 2,
            "number_of_replicas": 0
        }
    }
}

將分片數(shù)設(shè)為0, 再次查看, 則顯示正常:

file
  1. 索引

    3.1 新建索引orders

    ## 創(chuàng)建索引
    PUT orders
    

    3.2 查詢索引orders

    ## 查詢索引
    GET orders
    
file

通過查詢命令, 能查看到對(duì)應(yīng)信息, 默認(rèn)分片數(shù)和副本數(shù)都為1:

"number_of_shards" : "1", ## 主分片數(shù)
"number_of_replicas" : "1", ## 副分片數(shù)
file

3.3 刪除索引

## 刪除索引
DELETE orders

3.4 索引的設(shè)置

## 設(shè)置索引
PUT orders
{
  "settings": {
    "index": {
      "number_of_shards": 1, 
      "number_of_replicas": 0
    }
  }
}
  1. 文檔

    4.1 創(chuàng)建文檔

    ## 創(chuàng)建文檔,生成默認(rèn)的文檔id
    POST orders/_doc
    {
      "name": "襪子1雙",
      "price": "200",
      "count": 1,
      "address": "北京市"
    }
    ## 創(chuàng)建文檔,生成自定義文檔id
    POST orders/_doc/1
    {
      "name": "襪子1雙",
      "price": "2",
      "count": 1,
      "address": "北京市"
    }
    

    4.2 查詢文檔

    ## 根據(jù)指定的id查詢
    GET orders/_doc/1
    ## 根據(jù)指定條件查詢文檔
    GET orders/_search
    {
      "query": {
        "match": {
          "address": "北京市"
        }
      }
    }
    ## 查詢?nèi)课臋n
    GET orders/_search
    

    4.3 更新文檔

    ## 更新文檔
    POST orders/_doc/1
    {
      "price": "200"
    }
    ## 更新文檔
    POST orders/_update/1
    {
      "doc": {
        "price": "200"
      }
    }
    

    4.4 刪除文檔

    ## 刪除文檔
    DELETE orders/_doc/1
    
  2. 對(duì)于映射,只能進(jìn)行字段添加,不能對(duì)字段進(jìn)行修改或刪除,如有需要,則重新創(chuàng)建映射。

    ## 設(shè)置mapping信息
    PUT orders/_mappings
    {
      "properties":{
        "price": {
          "type": "long"
        }
      }
    }
    ## 設(shè)置分片和映射
    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數(shù)據(jù)類型

整體數(shù)據(jù)類型結(jié)構(gòu):

file
  1. String 類型

    主要分為text與keyword兩種類型。兩者區(qū)別主要在于能否分詞。

    • text類型

      會(huì)進(jìn)行分詞處理, 分詞器默認(rèn)采用的是standard。

    • keyword類型

      不會(huì)進(jìn)行分詞處理。在ES的倒排索引中存儲(chǔ)的是完整的字符串。

  2. Date時(shí)間類型

    數(shù)據(jù)庫里的日期類型需要規(guī)范具體的傳入格式, ES是可以控制,自適應(yīng)處理。

    傳遞不同的時(shí)間類型:

    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 } 
    
    
    ## 查看日期數(shù)據(jù):
    GET my_date_index/_mapping
    
file

ES的Date類型允許可以使用的格式有:

yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
epoch_millis(毫秒值)

  1. 復(fù)合類型

    復(fù)雜類型主要有三種: Array、object、nested。

    • Array類型: 在Elasticsearch中,數(shù)組不需要聲明專用的字段數(shù)據(jù)類型。但是,在數(shù)組中的所有值都必須具有相同的數(shù)據(jù)類型。舉例:

      POST orders/_doc/1
      {
        "goodsName":["足球","籃球","兵乓球", 3]
      }
      
      POST orders/_doc/1
      {
        "goodsName":["足球","籃球","兵乓球"]
      }
      
    • object類型: 用于存儲(chǔ)單個(gè)JSON對(duì)象, 類似于JAVA中的對(duì)象類型, 可以有多個(gè)值, 比如LIST<object>,可以包含多個(gè)對(duì)象。

      但是LIST<object>只能作為整體, 不能獨(dú)立的索引查詢。舉例:

      # 新增第一組數(shù)據(jù), 組別為美國,兩個(gè)人。
      POST my_index/_doc/1
      {  
        "group" : "america", 
        "users" : [  
          {  
            "name" : "John", 
            "age" :  "22"    
          }, 
          {  
            "name" : "Alice",    
            "age" :  "21"    
          }  
        ]    
      }  
      # 新增第二組數(shù)據(jù), 組別為英國, 兩個(gè)人。
      POST my_index/_doc/2
      {  
        "group" : "england", 
        "users" : [  
          {  
            "name" : "lucy", 
            "age" :  "21"    
          }, 
          {  
            "name" : "John", 
            "age" :  "32"    
          }  
        ]    
      }
      

      這兩組數(shù)據(jù)都包含了name為John,age為21的數(shù)據(jù),

      采用這個(gè)搜索條件, 實(shí)際結(jié)果:

      GET my_index/_search
      {
          "query": {
              "bool": {
                  "must": [
                      {
                          "match": {
                              "users.name": "John"
                          }
                      },
                      {
                          "match": {
                              "users.age": "21"
                          }
                      }
                  ]
              }
          }
      }
      

      結(jié)果可以看到, 這兩組數(shù)據(jù)都能找出,因?yàn)槊恳唤M數(shù)據(jù)都是作為一個(gè)整體進(jìn)行搜索匹配, 而非具體某一條數(shù)據(jù)。

    • Nested類型

      用于存儲(chǔ)多個(gè)JSON對(duì)象組成的數(shù)組,nested 類型是 object 類型中的一個(gè)特例,可以讓對(duì)象數(shù)組獨(dú)立索引和查詢。

      舉例:

      創(chuàng)建nested類型的索引:

      PUT my_index
      {  
        "mappings": {    
          "properties": {    
            "users": {   
              "type": "nested"   
            }    
          }  
        }    
      }
      

      發(fā)出查詢請(qǐng)求:

      GET my_index/_search
      {
          "query": {
              "bool": {
                  "must": [
                      {
                          "nested": {
                              "path": "users",
                              "query": {
                                  "bool": {
                                      "must": [
                                          {
                                              "match": {
                                                  "users.name": "John"
                                              }
                                          },
                                          {
                                              "match": {
                                                  "users.age": "21"
                                              }
                                          }
                                      ]
                                  }
                              }
                          }
                      }
                  ]
              }
          }
      }
      

      采用以前的條件, 這個(gè)時(shí)候查不到任何結(jié)果, 將年齡改成22, 就可以找出對(duì)應(yīng)的數(shù)據(jù):

      "hits" : [
            {
              "_index" : "my_index",
              "_type" : "_doc",
              "_id" : "1",
              "_score" : 1.89712,
              "_source" : {
                "group" : "america",
                "users" : [
                  {
                    "name" : "John",
                    "age" : "22"
                  },
                  {
                    "name" : "Alice",
                    "age" : "21"
                  }
                ]
              }
            }
          ]
      
  1. GEO地理位置類型

    現(xiàn)在大部分APP都有基于位置搜索的功能, 比如交友、購物應(yīng)用等。這些功能是基于GEO搜索實(shí)現(xiàn)的。

    對(duì)于GEO地理位置類型,分為地理坐標(biāo)類型:Geo-point, 和形狀:Geo-shape 兩種類型。

    經(jīng)緯度 英文 簡(jiǎn)寫 正數(shù) 負(fù)數(shù)
    維度 latitude lat 北緯 南緯
    經(jīng)度 longitude lon或lng 東經(jīng) 西經(jīng)

    創(chuàng)建地理位置索引:

    PUT my_locations
    {
      "mappings": {
        "properties": {
          "location": {
            "type": "geo_point"
          }
        }
      }
    }
    

    添加地理位置數(shù)據(jù):

    # 采用object對(duì)象類型
    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算法可以將多維數(shù)據(jù)映射為一串字符)
    PUT my_locations/_doc/3
    {
        "user": "王二麻子",
        "text": "Geo-point as a geohash",
        "location": "drm3btev3e86"
    }
    # 采用array數(shù)組類型
    PUT my_locations/_doc/4
    {
        "user": "木頭老七",
        "text": "Geo-point as an array",
        "location": [
            -80.34,
            51.12
        ]
    }
    

    需求:搜索出距離我{"lat" : 40,"lon" : -70} 200km范圍內(nèi)的人:

    GET my_locations/_search
    {
        "query": {
            "bool": {
                "must": {
                    "match_all": {}
                },
                "filter": {
                    "geo_distance": {
                        "distance": "200km",
                        "location": {
                            "lat": 40,
                            "lon": -70
                        }
                    }
                }
            }
        }
    }
    

2. ES高可用集群配置

2.1 ElasticSearch集群介紹

  • 主節(jié)點(diǎn)(或候選主節(jié)點(diǎn))

    主節(jié)點(diǎn)負(fù)責(zé)創(chuàng)建索引、刪除索引、分配分片、追蹤集群中的節(jié)點(diǎn)狀態(tài)等工作, 主節(jié)點(diǎn)負(fù)荷相對(duì)較輕, 客戶端請(qǐng)求可以直接發(fā)往任何節(jié)點(diǎn), 由對(duì)應(yīng)節(jié)點(diǎn)負(fù)責(zé)分發(fā)和返回處理結(jié)果。

    一個(gè)節(jié)點(diǎn)啟動(dòng)之后, 采用 Zen Discovery機(jī)制去尋找集群中的其他節(jié)點(diǎn), 并與之建立連接, 集群會(huì)從候選主節(jié)點(diǎn)中選舉出一個(gè)主節(jié)點(diǎn), 并且一個(gè)集群只能選舉一個(gè)主節(jié)點(diǎn), 在某些情況下, 由于網(wǎng)絡(luò)通信丟包等問題, 一個(gè)集群可能會(huì)出現(xiàn)多個(gè)主節(jié)點(diǎn), 稱為“腦裂現(xiàn)象”, 腦裂會(huì)存在丟失數(shù)據(jù)的可能, 因?yàn)橹鞴?jié)點(diǎn)擁有最高權(quán)限, 它決定了什么時(shí)候可以創(chuàng)建索引, 分片如何移動(dòng)等, 如果存在多個(gè)主節(jié)點(diǎn), 就會(huì)產(chǎn)生沖突, 容易產(chǎn)生數(shù)據(jù)丟失。要盡量避免這個(gè)問題, 可以通過 discovery.zen.minimum_master_nodes 來設(shè)置最少可工作的候選主節(jié)點(diǎn)個(gè)數(shù)。 建議設(shè)置為(候選主節(jié)點(diǎn)/2) + 1 比如三個(gè)候選主節(jié)點(diǎn),該配置項(xiàng)為 (3/2)+1 ,來保證集群中有半數(shù)以上的候選主節(jié)點(diǎn), 沒有足夠的master候選節(jié)點(diǎn), 就不會(huì)進(jìn)行master節(jié)點(diǎn)選舉,減少腦裂的可能。

    主節(jié)點(diǎn)的參數(shù)設(shè)置:

    node.master = true
    node.data = false
    
  • 數(shù)據(jù)節(jié)點(diǎn)

    數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和CRUD等具體操作,數(shù)據(jù)節(jié)點(diǎn)對(duì)機(jī)器配置要求比較高、,首先需要有足夠的磁盤空間來存儲(chǔ)數(shù)據(jù),其次數(shù)據(jù)操作對(duì)系統(tǒng)CPU、Memory和IO的性能消耗都很大。通常隨著集群的擴(kuò)大,需要增加更多的數(shù)據(jù)節(jié)點(diǎn)來提高可用性。

    數(shù)據(jù)節(jié)點(diǎn)的參數(shù)設(shè)置:

    node.master = false
    node.data = true
    
  • 客戶端節(jié)點(diǎn)

    客戶端節(jié)點(diǎn)不做候選主節(jié)點(diǎn), 也不做數(shù)據(jù)節(jié)點(diǎn)的節(jié)點(diǎn),只負(fù)責(zé)請(qǐng)求的分發(fā)、匯總等等,增加客戶端節(jié)點(diǎn)類型更多是為了負(fù)載均衡的處理。

    node.master = false
    node.data = false
    
  • 提取節(jié)點(diǎn)(預(yù)處理節(jié)點(diǎn))

    能執(zhí)行預(yù)處理管道,有自己獨(dú)立的任務(wù)要執(zhí)行, 在索引數(shù)據(jù)之前可以先對(duì)數(shù)據(jù)做預(yù)處理操作, 不負(fù)責(zé)數(shù)據(jù)存儲(chǔ)也不負(fù)責(zé)集群相關(guān)的事務(wù)。

    參數(shù)設(shè)置:

    node.ingest = true
    
  • 協(xié)調(diào)節(jié)點(diǎn)

    協(xié)調(diào)節(jié)點(diǎn),是一種角色,而不是真實(shí)的Elasticsearch的節(jié)點(diǎn),不能通過配置項(xiàng)來指定哪個(gè)節(jié)點(diǎn)為協(xié)調(diào)節(jié)點(diǎn)。集群中的任何節(jié)點(diǎn),都可以充當(dāng)協(xié)調(diào)節(jié)點(diǎn)的角色。當(dāng)一個(gè)節(jié)點(diǎn)A收到用戶的查詢請(qǐng)求后,會(huì)把查詢子句分發(fā)到其它的節(jié)點(diǎn),然后合并各個(gè)節(jié)點(diǎn)返回的查詢結(jié)果,最后返回一個(gè)完整的數(shù)據(jù)集給用戶。在這個(gè)過程中,節(jié)點(diǎn)A扮演的就是協(xié)調(diào)節(jié)點(diǎn)的角色。

    ES的一次請(qǐng)求非常類似于Map-Reduce操作。在ES中對(duì)應(yīng)的也是兩個(gè)階段,稱之為scatter-gather。客戶端發(fā)出一個(gè)請(qǐng)求到集群的任意一個(gè)節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)就是所謂的協(xié)調(diào)節(jié)點(diǎn),它會(huì)把請(qǐng)求轉(zhuǎn)發(fā)給含有相關(guān)數(shù)據(jù)的節(jié)點(diǎn)(scatter階段),這些數(shù)據(jù)節(jié)點(diǎn)會(huì)在本地執(zhí)行請(qǐng)求然后把結(jié)果返回給協(xié)調(diào)節(jié)點(diǎn)。協(xié)調(diào)節(jié)點(diǎn)將這些結(jié)果匯總(reduce)成一個(gè)單一的全局結(jié)果集(gather階段) 。

  • 部落節(jié)點(diǎn)

    在多個(gè)集群之間充當(dāng)聯(lián)合客戶端, 它是一個(gè)特殊的客戶端 , 可以連接多個(gè)集群,在所有連接的集群上執(zhí)行搜索和其他操作。 部落節(jié)點(diǎn)從所有連接的集群中檢索集群狀態(tài)并將其合并成全局集群狀態(tài)。 掌握這一信息,就可以對(duì)所有集群中的節(jié)點(diǎn)執(zhí)行讀寫操作,就好像它們是本地的。 請(qǐng)注意,部落節(jié)點(diǎn)需要能夠連接到每個(gè)配置的集群中的每個(gè)單個(gè)節(jié)點(diǎn)。

2.2 ElasticSearch集群原理

2.2.1 集群分布式原理

ES集群可以根據(jù)節(jié)點(diǎn)數(shù), 動(dòng)態(tài)調(diào)整主分片與副本數(shù), 做到整個(gè)集群有效均衡負(fù)載。

單節(jié)點(diǎn)狀態(tài)下:

file

兩個(gè)節(jié)點(diǎn)狀態(tài)下, 副本數(shù)為1:

file

三個(gè)節(jié)點(diǎn)狀態(tài)下, 副本數(shù)為1:

file

三個(gè)節(jié)點(diǎn)狀態(tài)下, 副本數(shù)為2:

file

2.2.2 分片處理機(jī)制

設(shè)置分片大小的時(shí)候, 需預(yù)先做好容量規(guī)劃, 如果節(jié)點(diǎn)數(shù)過多, 分片數(shù)過小, 那么新的節(jié)點(diǎn)將無法分片, 不能做到水平擴(kuò)展, 并且單個(gè)分片數(shù)據(jù)量太大, 導(dǎo)致數(shù)據(jù)重新分配耗時(shí)過大。

假設(shè)一個(gè)集群中有一個(gè)主節(jié)點(diǎn)、兩個(gè)數(shù)據(jù)節(jié)點(diǎn)。orders索引的分片分布情況如下所示:

PUT orders
{
    "settings":{
        "number_of_shards":2,  ## 主分片 2
        "number_of_replicas":2  ## 副分片 4
    }
}
file

整個(gè)集群中存在P0和P1兩個(gè)主分片, P0對(duì)應(yīng)的兩個(gè)R0副本分片, P1對(duì)應(yīng)的是兩個(gè)R1副本分片。

2.2.3 新建索引處理流程

file
  1. 寫入的請(qǐng)求會(huì)進(jìn)入主節(jié)點(diǎn), 如果是NODE2副本接收到寫請(qǐng)求, 會(huì)將它轉(zhuǎn)發(fā)至主節(jié)點(diǎn)。

  2. 主節(jié)點(diǎn)接收到請(qǐng)求后, 根據(jù)documentId做取模運(yùn)算(外部沒有傳遞documentId,則會(huì)采用內(nèi)部自增ID),

    如果取模結(jié)果為P0,則會(huì)將寫請(qǐng)求轉(zhuǎn)發(fā)至NODE3處理。

  3. NODE3節(jié)點(diǎn)寫請(qǐng)求處理完成之后, 采用異步方式, 將數(shù)據(jù)同步至NODE1和NODE2節(jié)點(diǎn)。

2.2.4 讀取索引處理流程

file
  1. 讀取的請(qǐng)求進(jìn)入MASTER節(jié)點(diǎn), 會(huì)根據(jù)取模結(jié)果, 將請(qǐng)求轉(zhuǎn)發(fā)至不同的節(jié)點(diǎn)。
  2. 如果取模結(jié)果為R0,內(nèi)部還會(huì)有負(fù)載均衡處理機(jī)制,如果上一次的讀取請(qǐng)求是在NODE1的R0, 那么當(dāng)前請(qǐng)求會(huì)轉(zhuǎn)發(fā)至NODE2的R0, 保障每個(gè)節(jié)點(diǎn)都能夠均衡的處理請(qǐng)求數(shù)據(jù)。
  3. 讀取的請(qǐng)求如果是直接落至副本節(jié)點(diǎn), 副本節(jié)點(diǎn)會(huì)做判斷, 若有數(shù)據(jù)則返回,沒有的話會(huì)轉(zhuǎn)發(fā)至其他節(jié)點(diǎn)處理。

2.3 ElasticSearch集群部署規(guī)劃

準(zhǔn)備一臺(tái)虛擬機(jī):

192.168.116.140: Node-1 (節(jié)點(diǎn)一), 端口:9200, 9300

192.168.116.140: Node-2 (節(jié)點(diǎn)二),端口:9201, 9301

192.168.116.140: Node-3 (節(jié)點(diǎn)三),端口:9202, 9302

2.4 ElasticSearch集群配置

  1. 解壓安裝包:

    mkdir /usr/local/cluster
    cd /usr/local/cluster
    tar -xvf elasticsearch-7.10.2-linux-x86_64.tar.gz
    

    將安裝包解壓至/usr/local/cluster目錄。

  2. 修改集群配置文件:

    vi /usr/local/cluster/elasticsearch-7.10.2-node1/config/elasticsearch.yml 
    

    192.168.116.140, 第一臺(tái)節(jié)點(diǎn)配置內(nèi)容:

    # 集群名稱
    cluster.name: my-application
    #節(jié)點(diǎn)名稱
    node.name: node-1
    # 綁定IP地址
    network.host: 192.168.116.140
    # 指定服務(wù)訪問端口
    http.port: 9200
    # 指定API端戶端調(diào)用端口
    transport.tcp.port: 9300
    #集群通訊地址
    discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #集群初始化能夠參選的節(jié)點(diǎn)信息
    cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #開啟跨域訪問支持,默認(rèn)為false
    http.cors.enabled: true
    ##跨域訪問允許的域名, 允許所有域名
    http.cors.allow-origin: "*"
    
    

    修改目錄權(quán)限:

    chown -R elsearch:elsearch /usr/local/cluster/elasticsearch-7.10.2-node1
    
  3. 復(fù)制ElasticSearch安裝目錄:

    復(fù)制其余兩個(gè)節(jié)點(diǎn):

    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
    
  4. 修改其余節(jié)點(diǎn)的配置:

    192.168.116.140 第二臺(tái)節(jié)點(diǎn)配置內(nèi)容:

    # 集群名稱
    cluster.name: my-application
    #節(jié)點(diǎn)名稱
    node.name: node-2
    # 綁定IP地址
    network.host: 192.168.116.140
    # 指定服務(wù)訪問端口
    http.port: 9201
    # 指定API端戶端調(diào)用端口
    transport.tcp.port: 9301
    #集群通訊地址
    discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #集群初始化能夠參選的節(jié)點(diǎn)信息
    cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #開啟跨域訪問支持,默認(rèn)為false
    http.cors.enabled: true
    ##跨域訪問允許的域名, 允許所有域名
    http.cors.allow-origin: "*"
    
    

    192.168.116.140 第三臺(tái)節(jié)點(diǎn)配置內(nèi)容:

    # 集群名稱
    cluster.name: my-application
    #節(jié)點(diǎn)名稱
    node.name: node-3
    # 綁定IP地址
    network.host: 192.168.116.140
    # 指定服務(wù)訪問端口
    http.port: 9202
    # 指定API端戶端調(diào)用端口
    transport.tcp.port: 9302
    #集群通訊地址
    discovery.seed_hosts: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #集群初始化能夠參選的節(jié)點(diǎn)信息
    cluster.initial_master_nodes: ["192.168.116.140:9300", "192.168.116.140:9301","192.168.116.140:9302"]
    #開啟跨域訪問支持,默認(rèn)為false
    http.cors.enabled: true
    ##跨域訪問允許的域名, 允許所有域名
    http.cors.allow-origin: "*"
    
    
  1. 啟動(dòng)集群節(jié)點(diǎn)

    先切換elsearch用戶, 在三臺(tái)節(jié)點(diǎn)依次啟動(dòng)服務(wù):

    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
    

    注意: 如果啟動(dòng)出現(xiàn)錯(cuò)誤, 將各節(jié)點(diǎn)的data目錄清空, 再重啟服務(wù)。

  2. 集群狀態(tài)查看

    集群安裝與啟動(dòng)成功之后, 執(zhí)行請(qǐng)求: http://192.168.116.140:9200/_cat/nodes?pretty

    可以看到三個(gè)節(jié)點(diǎn)信息,三個(gè)節(jié)點(diǎn)會(huì)自行選舉出主節(jié)點(diǎn):

file

2.5 ElasticSearch集群分片測(cè)試

修改kibana的配置文件,指向創(chuàng)建的集群節(jié)點(diǎn):

elasticsearch.hosts: ["http://192.168.116.140:9200","http://192.168.116.140:9201","http://192.168.116.140:9202"]

重啟kibana服務(wù), 進(jìn)入控制臺(tái):

http://192.168.116.140:5601/app/home#/

再次創(chuàng)建索引(副本數(shù)量范圍內(nèi)):

PUT orders
{
    "settings": {
        "index": {
            "number_of_shards": 2,
            "number_of_replicas": 2
        }
    }
}

可以看到, 這次結(jié)果是正常:

file

集群并非可以隨意增加副本數(shù)量, 創(chuàng)建索引(超出副本數(shù)量范圍):

PUT orders
{
    "settings": {
        "index": {
            "number_of_shards": 2,
            "number_of_replicas": 5
        }
    }
}

可以看到出現(xiàn)了yellow警告錯(cuò)誤:

file

好了,至此ES集群搭建完畢,歡迎志同道合的小伙伴,一起交流學(xué)習(xí)成長。進(jìn)階架構(gòu)師,F(xiàn)ighting!!!

本文由育博學(xué)谷狂野架構(gòu)師發(fā)布
如果本文對(duì)您有幫助,歡迎關(guān)注和點(diǎn)贊;如果您有任何建議也可留言評(píng)論或私信,您的支持是我堅(jiān)持創(chuàng)作的動(dòng)力
轉(zhuǎn)載請(qǐng)注明出處!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,115評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,234評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,621評(píng)論 1 326
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,822評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,380評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,128評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,319評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,548評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評(píng)論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,048評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,285評(píng)論 2 376

推薦閱讀更多精彩內(nèi)容