Docker 中安装 ElasticSearch

Docker 中安装 ElasticSearch

1、安装 ElasticSearch

Dokcer 中安装 ElasticSearch

(1)下载 ElasticSearch 和 Kibana

docker pull elasticsearch:7.6.2
docker pull kibana:7.6.2

(2)配置

sudo mkdir -p /mydata/elasticsearch/config
sudo mkdir -p /mydata/elasticsearch/data
sudo mkdir -p /mydata/elasticsearch/plugins
sudo mkdir -p /mydata/elasticsearch/logs
sudo echo "http.host: 0.0.0.0" >/mydata/elasticsearch/config/elasticsearch.yml	
# ES 可以被任何机器访问
sudo chmod -R 777 /mydata/elasticsearch/
	# sudo:是 linux 系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具。
	# -R:是指几连医用到目录里所有子目录和文件;
	# 777:是指所有用户都拥有的最高权限。

(3)启动 Elasticsearch

docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
--restart=always \
--privileged=true \
-m 512m \
--cpus=0.5 \
-e  "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx256m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-v /mydata/elasticsearch/logs:/usr/share/elasticsearch/logs \
--network=es-net \
-d elasticsearch:7.6.2 

# 9200 是 ES 节点与外部通讯使用的端口。它是 http 协议的 RESTful 接口(各种 CRUD 操作都是走的该端口,如查询:http://localhost:9200/user/_search)。
# 9300是 ES 节点之间通讯使用的端口。它是 tcp 通讯端口,集群间和 TCPclient 都走的它。(java 程序中使用 ES 时,在配置文件中要配置该端口)
# -e  "discovery.type=single-node":以单节点运行
# -e ES_JAVA_OPTS="-Xms64m -Xmx512m":设置 ES 的 JVM 堆大小,初始 64M,最大 512M

设置开机启动 ElasticSearch

docker update elasticsearch --restart=always

(4)启动 Kibana:

sudo mkdir -p /mydata/kibana/config
sudo mkdir -p /mydata/kibana/data
sudo mkdir -p /mydata/kibana/logs
sudo chmod -R 777 /mydata/kibana/

docker run --name tempKibana -p 5601:5601 -d kibana:7.6.2  # 用于生成 kibana.yml 文件并挂载本地

# 或者不挂载本地,直接进入下一步(5)
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://172.0.0.5:9200 -p 5601:5601 -d kibana:7.6.2
# ELASTICSEARCH_HOSTS 为 elasticsearch 的地址,如果不知道 ip 可用 localhost 代替 ip

复制 config 文件夹中的文件到宿主机上

docker cp tempKibana:/usr/share/kibana/config /mydata/kibana

删除临时容器

docker rm -f tempKibana

修改 kibana.yml 中的 elasticsearch.host
在 /mydata/kibana/config 下找到 kibana.yml 进行编辑,让 kibana 与启动的 es 连接,毕竟我们使用 kibana 就是为了可以类似 Navicat 那样能操作 MySQL。这里可以来修改 elasticsearch.host 改为自己的 ip。不知道 ip 地址可以用 localhost

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://localhost:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true

启动 Kibana

docker run --name kibana -p 5601:5601 \
-v /mydata/kibana/config:/usr/share/kibana/config \
-v /mydata/kibana/data:/usr/share/kibana/data \
-v /mydata/kibana/logs:/usr/share/kibana/logs \
--privileged=true \
--restart=always \
-d kibana:7.6.2

设置开机启动 Kibana

docker update kibana --restart=always

(5)测试

查看 elasticsearch 版本信息:

curl http://192.168.137.14:9200
{
  "name" : "caa9d6b4b0a2",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "e8JfxABLQFu1V4AKs4zgFA",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

显示 ElasticSearch 节点信息

curl http://192.168.137.14:9200/_cat/nodes 
127.0.0.1 16 96 1 0.05 0.03 0.05 dilm * e45f2a9790a8

访问 Kibana:http://192.168.137.14:5601/app/kibana
image-20200501192629304

Docker 集群设置

https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/distributed-cluster.html
elasticsearch 是天生支持集群的,他不需要依赖其他的服务发现和注册的组件,如 zookeeper 这些,因为他内置了一个名字叫 ZenDiscovery 的模块,是 elasticsearch ,自己实现的一套用于节点发现和选主等功能的组件,所以 elasticsearch 做起集群来非常简单,不需要太多额外的配置和安装额外的第三方组件。

解决 elasticsearch 启动错误 bootstrap checks failed

分析原因:bootstrap 校验失败

解决方法:将当前用户的软硬限制调大

  • 修改配置文件,/etc/security/limits.conf
cp -a /etc/security/limits.conf /etc/security/limits.conf.bak
vi /etc/security/limits.conf
# 在文件末尾追加下面内容
xzlawin soft nofile 65536
xzlawin hard nofile 65536
  • 修改配置文件,/etc/security/limits.d/90-nproc.conf
cp -a /etc/security/limits.d/90-nproc.conf /etc/security/limits.d/90-nproc.conf.bak
vi /etc/security/limits.d/90-nproc.conf
# 在文件末尾追加下面内容
xzlawin soft nofile 65536
xzlawin hard nofile 65536
* soft nproc 4096
* hard nproc 4096
# 注意:* 表示Linux所有用户名称
  • 修改配置文件,/etc/sysctl.conf
cp -a /etc/sysctl.conf /etc/sysctl.conf.bak
vi /etc/sysctl.conf
# 在文件末尾追加下面内容
vm.max_map_count=655360
  • 重新加载
sysctl -p

1. 集群原理

单节点

1. 主节点用于调控,维护各节点状态信息的
 2. 任何节点可以做主节点
 3. 客户端连上任意一个节点都可以完成操作
一个运行中的Elasticsearch实例称为一个节点,而集群是由一个或者多个拥有相同cluster.name配置的节点组成,它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
当一个节点被选举成为主节点时,它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以它同时也成为了主节点。
作为用户,我们可以将请求发送到集群中的任何节点,包括主节点。每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据.并将最终结果返回给客户端。Elasticsearch 对这一切的管理都是透明的。

集群健康

get /_cluster/health  

status: 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
green: 所有的主分片和副本分片都正常运行。
yellow: 所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red: 有主分片没能正常运行。

分片

  1. 一个分片是一个底层的工作单元﹐它仅保存了全部数据中的一部分。我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。分片就认为是一个数据区
  2. 一个分片可以是主分片或者副本分片。索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。
  3. 在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改。
  4. 让我们在包含一个空节点的集群内创建名为 blogs 的索引。索引在默认情况下会被分配 5 个主分片,但是为了演示目的.我们将分配 3 个主分片和一份副本(每个主分片拥有一个副本分片):
PUT /blogs{
	"settings" : {
		"number_of_shards" : 3,
		"number_of_replicas" : 1
	}
}

此时集群的健康状况为 yellow 则表示全部主分片都正常运行(集群可以正常服务所有请求),但是副本分片没有全部处在正常状态。实际上,所有 3 个副本分片都是 unassigned —它们都没有被分配到任何节点。在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。

个人理解,此时 3 个分片是在同一节点上 master 节点与主分片不是一个意思, master 节点只需要一个。主分片可能存在多个,并有可能存在于不同节点上
images/1659624957023.png

新增节点

当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的 cluster.name 配置,它就会自动发现集群并加入到其中。但是在不同机器上启动节点的时候,为了加入到同一集群,你需要配置一个可连接到的单播主机列表。详细信息请查看最好使用单播代替组播
1659625012856.png
此时,cluster-health 现在展示的状态为 green,这表示所有 6 个分片(包括 3 个主分片和 3 个副本分片)都在正常运行。我们的集群现在不仅仅是正常运行的,并且还处于始终可用的状态。

重新分配

1659625095183.png

  1. 在第四步的基础上,继续水平扩容增加第三个节点,会重新自动分配
    Node 1 和 Node 2上各有一个分片被迁移到了新的 Node 3 节点,现在每个节点上都拥有 2 个分片,而不是之前的 3 个。这表示每个节点的硬件资源(CPU,RAM.VO)将被更少的分片所共享,每个分片的性能将会得到提升。在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。让我们把副本数从默认的 1 增加到 2
    如果调整每个分片拥有两个从分片
PUT /blogs/_settings
{
	"number_of_replicas" : 2
}

会自动调整为以下状态:

  1. 如果此时 Node1 宕机,会先选举一个主节点 Node2,此时查看集群状态将是 red,主分区 P1、P2 未正常工作
  2. 提升副本分区为主分区,集群状态变为 yellow
  3. 为什么是 yellow 而不是 green?因为每个主分区存在两个副本分区才是 green

脑裂现象

  1. 主节点:
    创建索引、删除索引、分配分片、追踪集群中节点状态等工作【ZenDiscovery 机制选举出来,要成为主节点先成为候选节点】
  2. 候选主节点:
    主节点宕机,选举一个候选主节点作为主节点。指定候选主节点的配置为 node.master:true
  3. 脑裂现象
    网路故障,出现两个集群两个主节点【集群中不同的节点对于 master 的选择出现了分歧,出现了多个 master 竞争,导致主分片和副本的识别也发生了分歧,对一些分歧中的分片标识为了坏片。】
  • 解决方案:
    1. 角色分离:master 与 data 节点分离,限制角色
      因为 data 节点如果既要负责 master 节点又要负责 data 节点,压力很大导致脑裂概率增加

    2. 增加判定宕机时间【减少误判】:主节点判定宕机时间加长【默认3秒】
      discover.zen.ping_timeout: 5

    3. 设置选举触发互连节点最小数目:discover.zen.minimum_master_nodes:1(默认是1),该属性定义的是为了形成一个集群,有主节点资格并互相连接的节点的最小数目。建议设置成 (候选主节点数/2)+1
      例:10个候选主节点互相连接,并且discover.zen.minimum_master_nodes:6,此时网络原因导致6个节点连接,其余4个节点连接,则其余4个节点不会形成一个新的集群。

    4. 数据节点
      node.data:true
      主节点和数据节点分开,主节点不存数据

    5. 客户端节点【分担主节点的请求分发、汇总(其实集群内任意节点都可以完成此任务)】
      功能:为了负载均衡
      node.master:false
      node.data:false

集群搭建(节点+分片)

  • 要求:
    1. 6 台物理机 6 个节点,3 个 master 节点 3 个 data 节点【角色分离,防止脑裂】
    2. 判定时间设为 10 秒
    3. 设置 discover.zen.minimum_master_nodes=2,只要一个 master 宕机,另外两个就可以选举
      master 节点上
      node.master = true
      node.data = false
      discovery.zen.minimum_master_nodes = 2
      总结:只要集群名字是一样的,就会自动加入到同一个集群中

1. 先修改jvm线程数,防止启动es报错

sysctl -w vm.max_map_count=262144

2. 利用 docker 模拟 6 台物理机,创建每一个容器使用一个 ip

  • 准备 docker 网络:
    1. docker network ls:查看 docker 网络
    2. docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1 es-cluster
    3. docker network inspect es-cluster: 查看网络消息
    4. 创建容器带上 --network=es-cluster --ip 172.18.12.x 指定 ip

3. 创建节点

创建主节点:

for port in $(seq 1 3); \
do \
mkdir -p /mydata/elasticsearch/master-${port}/config
mkdir -p /mydata/elasticsearch/master-${port}/data
chmod -R 777 /mydata/elasticsearch/master-${port}
cat << EOF > /mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es  #集群的名称,同一个集群该值必须设置成相同的
node.name: es-master-${port}  #该节点的名字
node.master: true  #该节点有机会成为master节点
node.data: false #该节点可以存储数据
network.host: 0.0.0.0
http.host: 0.0.0.0   #所有http均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时ping连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301","172.18.12.22:9302","172.18.12.23:9303"]
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点,es7的新增配置
EOF
docker run --name elasticsearch-master-${port} \
-p 920${port}:920${port} -p 930${port}:930${port} \
--network=es-cluster --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m"  \
-v /mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml  \
-v /mydata/elasticsearch/master-${port}/data:/usr/share/elasticsearch/data  \
-v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins  \
--restart=always \
-d elasticsearch:7.6.2
done

创建数据节点:

for port in $(seq 4 6); \
do \
mkdir -p /mydata/elasticsearch/node-$[${port}-3]/config
mkdir -p /mydata/elasticsearch/node-$[${port}-3]/data
chmod -R 777 /mydata/elasticsearch/node-$[${port}-3]
cat << EOF > /mydata/elasticsearch/node-$[${port}-3]/config/elasticsearch.yml
cluster.name: my-es  #集群的名称,同一个集群该值必须设置成相同的
node.name: es-node-${port}  #该节点的名字
node.master: false  #该节点有机会成为 master 节点
node.data: true #该节点可以存储数据
network.host: 0.0.0.0
http.host: 0.0.0.0   #所有 http 均可访问
http.port: 920${port}
transport.tcp.port: 930${port}
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时 ping 连接的超时时间
discovery.seed_hosts: ["172.18.12.21:9301","172.18.12.22:9302","172.18.12.23:9303"]
cluster.initial_master_nodes: ["172.18.12.21"] #新集群初始时的候选主节点, es7 的新增配置
EOF
docker run --name elasticsearch-node-$[${port}-3] \
-p 920${port}:920${port} -p 930${port}:930${port} \
--network=es-cluster --ip 172.18.12.2${port} \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m"  \
-v /mydata/elasticsearch/node-$[${port}-3]/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml  \
-v /mydata/elasticsearch/node-$[${port}-3]/data:/usr/share/elasticsearch/data  \
-v /mydata/elasticsearch/node-$[${port}-3]/plugins:/usr/share/elasticsearch/plugins  \
--restart=always \
-d elasticsearch:7.6.2
done

部署 kibana

docker run --name kibana-cluster -p 5602:5601 \
-v /mydata/kibana/master/config:/usr/share/kibana/config \
--privileged=true \
--restart=always \
--network=es-cluster \
-d kibana:7.6.2

修改配置文件,有多少个 master 节点就写多少个

elasticsearch.hosts: [ "http://elasticsearch-master-1:9201","http://elasticsearch-master-2:9202","http://elasticsearch-master-3:9203" ]

4. 访问查看集群相关信息指令:

192.168.56.131/_cluster/health:查看健康状况
192.168.56.131/_cluster/status
192.168.56.131/_cat/health
192.168.56.131/_cat/nodes:查看所有节点,带*是主节点
posted @   Thousand_Mesh  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示