使用 Docker 快速部署 Elasticsearch 集羣

本文將使用Docker容器(使用docker-compose編排)快速部署Elasticsearch 集羣,可用於開發環境(單機多實例)或生產環境部署。html

注意,6.x版本已經不能經過 -Epath.config 參數去指定配置文件的加載位置,文檔說明:node

For the archive distributions, the config directory location defaults to $ES_HOME/config. The location of the >config directory can be changed via the ES_PATH_CONF environment variable as follows:
ES_PATH_CONF=/path/to/my/config ./bin/elasticsearch
Alternatively, you can export the ES_PATH_CONF environment variable via the command line or via your shell profile.

即交給環境變量 ES_PATH_CONF 來設定了(官方文檔),單機部署多個實例且不使用容器的同窗多多注意。git

準備工做

安裝 docker & docker-compose

這裏推動使用 daocloud 作個加速安裝:github

#docker
curl -sSL https://get.daocloud.io/docker | sh

#docker-compose
curl -L \
https://get.daocloud.io/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` \
> /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

#查看安裝結果
docker-compose -v

數據目錄

#建立數據/日誌目錄 這裏咱們部署3個節點
mkdir /opt/elasticsearch/data/{node0,node1,node2} -p
mkdir /opt/elasticsearch/logs/{node0,node1,node2} -p
cd /opt/elasticsearch
#權限我也很懵逼啦 給了 privileged 也不行 索性0777好了
chmod 0777 data/* -R && chmod 0777 logs/* -R

#防止JVM報錯
echo vm.max_map_count=262144 >> /etc/sysctl.conf
sysctl -p

docker-compse 編排服務

建立編排文件

vim docker-compose.ymldocker


參數說明

- cluster.name=elasticsearch-cluster
集羣名稱shell

- node.name=node0
- node.master=true
- node.data=true
節點名稱、是否可做爲主節點、是否存儲數據npm

- bootstrap.memory_lock=true
鎖定進程的物理內存地址避免交換(swapped)來提升性能json

- http.cors.enabled=true
- http.cors.allow-origin=*
開啓cors以便使用Head插件bootstrap

- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
JVM內存大小配置vim

- "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
- "discovery.zen.minimum_master_nodes=2"
因爲5.2.1後的版本是不支持多播的,因此須要手動指定集羣各節點的tcp數據交互地址,用於集羣的節點發現failover,默認缺省9300端口,如設定了其它端口需另行指定,這裏咱們直接藉助容器通訊,也能夠將各節點的9300映射至宿主機,經過網絡端口通訊。
設定failover選取的quorum = nodes/2 + 1

固然,也能夠掛載本身的配置文件,ES鏡像的配置文件是/usr/share/elasticsearch/config/elasticsearch.yml,掛載以下:

volumes:
  - path/to/local/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro

docker-compose.yml

version: '3'
services:
  elasticsearch_n0:
    image: elasticsearch:6.6.2
    container_name: elasticsearch_n0
    privileged: true
    environment:
      - cluster.name=elasticsearch-cluster
      - node.name=node0
      - node.master=true
      - node.data=true
      - bootstrap.memory_lock=true
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
      - "discovery.zen.minimum_master_nodes=2"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./data/node0:/usr/share/elasticsearch/data
      - ./logs/node0:/usr/share/elasticsearch/logs
    ports:
      - 9200:9200
  elasticsearch_n1:
    image: elasticsearch:6.6.2
    container_name: elasticsearch_n1
    privileged: true
    environment:
      - cluster.name=elasticsearch-cluster
      - node.name=node1
      - node.master=true
      - node.data=true
      - bootstrap.memory_lock=true
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
      - "discovery.zen.minimum_master_nodes=2"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./data/node1:/usr/share/elasticsearch/data
      - ./logs/node1:/usr/share/elasticsearch/logs
    ports:
      - 9201:9200
  elasticsearch_n2:
    image: elasticsearch:6.6.2
    container_name: elasticsearch_n2
    privileged: true
    environment:
      - cluster.name=elasticsearch-cluster
      - node.name=node2
      - node.master=true
      - node.data=true
      - bootstrap.memory_lock=true
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
      - "discovery.zen.minimum_master_nodes=2"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - ./data/node2:/usr/share/elasticsearch/data
      - ./logs/node2:/usr/share/elasticsearch/logs
    ports:
      - 9202:9200

這裏咱們分別爲node0/node1/node2開放宿主機的9200/9201/9202做爲http服務端口,各實例的tcp數據傳輸用默認的9300經過容器管理通訊。

若是須要多機部署,則將EStransport.tcp.port: 9300端口映射至宿主機xxxx端口,discovery.zen.ping.unicast.hosts填寫各主機代理的地址便可:

#好比其中一臺宿主機爲192.168.1.100
    ...
    - "discovery.zen.ping.unicast.hosts=192.168.1.100:9300,192.168.1.101:9300,192.168.1.102:9300"
    ...
ports:
  ...
  - 9300:9300

建立並啓動服務

[root@localhost elasticsearch]# docker-compose up -d
[root@localhost elasticsearch]# docker-compose ps
      Name                    Command               State                Ports              
--------------------------------------------------------------------------------------------
elasticsearch_n0   /usr/local/bin/docker-entr ...   Up      0.0.0.0:9200->9200/tcp, 9300/tcp
elasticsearch_n1   /usr/local/bin/docker-entr ...   Up      0.0.0.0:9201->9200/tcp, 9300/tcp
elasticsearch_n2   /usr/local/bin/docker-entr ...   Up      0.0.0.0:9202->9200/tcp, 9300/tcp

#啓動失敗查看錯誤
[root@localhost elasticsearch]# docker-compose logs
#最可能是一些訪問權限/JVM vm.max_map_count 的設置問題

查看集羣狀態

192.168.20.6 是個人服務器地址

訪問http://192.168.20.6:9200/_cat/nodes?v便可查看集羣狀態:

ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.25.0.3           36          98  79    3.43    0.88     0.54 mdi       *      node0
172.25.0.2           48          98  79    3.43    0.88     0.54 mdi       -      node2
172.25.0.4           42          98  51    3.43    0.88     0.54 mdi       -      node1

驗證 Failover

經過集羣接口查看狀態

模擬主節點下線,集羣開始選舉新的主節點,並對數據進行遷移,從新分片。

[root@localhost elasticsearch]# docker-compose stop elasticsearch_n0
Stopping elasticsearch_n0 ... done

集羣狀態(注意換個http端口 原主節點下線了),down掉的節點還在集羣中,等待一段時間仍未恢復後就會被剔出

ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.25.0.2           57          84   5    0.46    0.65     0.50 mdi       -      node2
172.25.0.4           49          84   5    0.46    0.65     0.50 mdi       *      node1
172.25.0.3                                                       mdi       -      node0

等待一段時間

ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.25.0.2           44          84   1    0.10    0.33     0.40 mdi       -      node2
172.25.0.4           34          84   1    0.10    0.33     0.40 mdi       *      node1

恢復節點 node0

[root@localhost elasticsearch]# docker-compose start elasticsearch_n0
Starting elasticsearch_n0 ... done

等待一段時間

ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.25.0.2           52          98  25    0.67    0.43     0.43 mdi       -      node2
172.25.0.4           43          98  25    0.67    0.43     0.43 mdi       *      node1
172.25.0.3           40          98  46    0.67    0.43     0.43 mdi       -      node0

配合 Head 插件觀察

git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start

集羣狀態圖示更容易看出數據自動遷移的過程

一、集羣正常 數據安全分佈在3個節點上

clipboard.png

二、下線 node1 主節點 集羣開始遷移數據

遷移中
clipboard.png

遷移完成
clipboard.png

三、恢復 node1 節點

clipboard.png

安裝IK分詞器

analysis-ik:https://github.com/medcl/elas... 注意對應版本,這裏咱們部署的ES爲 6.6.2。

在集羣每個節點上執行安裝

docker exec -it elasticsearch_n0 bash
# 使用 elasticsearch-plugin 安裝
elasticsearch-plugin install \
https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.6.2/elasticsearch-analysis-ik-6.6.2.zip

重啓服務

docker-compose restart

驗證分詞

默認使用standard分詞器只能處理英文,中文會被拆分紅一個個的漢字,沒有語義。

GET /_analyze
{
    "text": "我愛祖國"
}
# reponse
{
    "tokens": [
        {
            "token": "我",
            "start_offset": 0,
            "end_offset": 1,
            "type": "<IDEOGRAPHIC>",
            "position": 0
        },
        {
            "token": "愛",
            "start_offset": 1,
            "end_offset": 2,
            "type": "<IDEOGRAPHIC>",
            "position": 1
        },
        {
            "token": "祖",
            "start_offset": 2,
            "end_offset": 3,
            "type": "<IDEOGRAPHIC>",
            "position": 2
        },
        {
            "token": "國",
            "start_offset": 3,
            "end_offset": 4,
            "type": "<IDEOGRAPHIC>",
            "position": 3
        }
    ]
}

使用ik分詞器

GET /_analyze
{
    "analyzer": "ik_smart",
    "text": "我愛祖國"
}
# reponse
{
    "tokens": [
        {
            "token": "我",
            "start_offset": 0,
            "end_offset": 1,
            "type": "CN_CHAR",
            "position": 0
        },
        {
            "token": "愛祖國",
            "start_offset": 1,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

分詞模式有 ik_smart/ ik_max_word兩種方式,可自行根據業務需求選擇。

設定默認分詞器

若是咱們的業務中不少字段都是中文,那在字段定義是都要去指定analyzer是個很繁瑣的工做,咱們能夠設定默認的分詞器爲ik,這樣中英文都能作分詞處理了。

PUT /index
{
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_smart"
        }
    }
}

注意:5.x版本後已沒法在 elasticsearch.yaml中設定分詞器配置,只能經過 restApi設定:

*************************************************************************************
Found index level settings on node level configuration.

Since elasticsearch 5.x index level settings can NOT be set on the nodes 
configuration like the elasticsearch.yaml, in system properties or command line 
arguments.In order to upgrade all indices the settings must be updated via the 
/${index}/_settings API. Unless all settings are dynamic all indices must be closed 
in order to apply the upgradeIndices created in the future should use index templates 
to set default values. 

Please ensure all required values are updated on all indices by executing: 

curl -XPUT 'http://localhost:9200/_all/_settings?preserve_existing=true' -d '{
  "index.analysis.analyzer.default.type" : "ik_smart"
}'
*************************************************************************************
index.analysis.analyzer.default.type: ik_smart #默認索引/檢索分詞器
index.analysis.analyzer.default_index.type: ik_smart #默認索引分詞器
index.analysis.analyzer.default_search.type: ik_smart #默認檢索分詞器

問題小記

  1. elasticsearch watermark
    部署完後建立索引起現有些分片處於 Unsigned 狀態,是因爲 elasticsearch watermark:low,high,flood_stage的限定形成的,默認硬盤使用率高於85%就會告警,開發嘛,手動關掉好了,數據會分片到各節點,生產自行決斷。

    curl -X PUT http://192.168.20.6:9201/_cluster/settings \
    -H 'Content-type':'application/json' \
    -d '{"transient":{"cluster.routing.allocation.disk.threshold_enabled": false}}'

相關文章
相關標籤/搜索