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
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: 有主分片没能正常运行。
分片
- 一个分片是一个底层的工作单元﹐它仅保存了全部数据中的一部分。我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。分片就认为是一个数据区
- 一个分片可以是主分片或者副本分片。索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。
- 在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改。
- 让我们在包含一个空节点的集群内创建名为 blogs 的索引。索引在默认情况下会被分配 5 个主分片,但是为了演示目的.我们将分配 3 个主分片和一份副本(每个主分片拥有一个副本分片):
PUT /blogs{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
此时集群的健康状况为 yellow 则表示全部主分片都正常运行(集群可以正常服务所有请求),但是副本分片没有全部处在正常状态。实际上,所有 3 个副本分片都是 unassigned —它们都没有被分配到任何节点。在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。
个人理解,此时 3 个分片是在同一节点上 master 节点与主分片不是一个意思, master 节点只需要一个。主分片可能存在多个,并有可能存在于不同节点上
新增节点
当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的 cluster.name 配置,它就会自动发现集群并加入到其中。但是在不同机器上启动节点的时候,为了加入到同一集群,你需要配置一个可连接到的单播主机列表。详细信息请查看最好使用单播代替组播
此时,cluster-health 现在展示的状态为 green,这表示所有 6 个分片(包括 3 个主分片和 3 个副本分片)都在正常运行。我们的集群现在不仅仅是正常运行的,并且还处于始终可用的状态。
重新分配
- 在第四步的基础上,继续水平扩容增加第三个节点,会重新自动分配
Node 1 和 Node 2上各有一个分片被迁移到了新的 Node 3 节点,现在每个节点上都拥有 2 个分片,而不是之前的 3 个。这表示每个节点的硬件资源(CPU,RAM.VO)将被更少的分片所共享,每个分片的性能将会得到提升。在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。让我们把副本数从默认的 1 增加到 2
如果调整每个分片拥有两个从分片
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
会自动调整为以下状态:
- 如果此时 Node1 宕机,会先选举一个主节点 Node2,此时查看集群状态将是 red,主分区 P1、P2 未正常工作
- 提升副本分区为主分区,集群状态变为 yellow
- 为什么是 yellow 而不是 green?因为每个主分区存在两个副本分区才是 green
脑裂现象
- 主节点:
创建索引、删除索引、分配分片、追踪集群中节点状态等工作【ZenDiscovery 机制选举出来,要成为主节点先成为候选节点】 - 候选主节点:
主节点宕机,选举一个候选主节点作为主节点。指定候选主节点的配置为 node.master:true - 脑裂现象
网路故障,出现两个集群两个主节点【集群中不同的节点对于 master 的选择出现了分歧,出现了多个 master 竞争,导致主分片和副本的识别也发生了分歧,对一些分歧中的分片标识为了坏片。】
- 解决方案:
-
角色分离:master 与 data 节点分离,限制角色
因为 data 节点如果既要负责 master 节点又要负责 data 节点,压力很大导致脑裂概率增加 -
增加判定宕机时间【减少误判】:主节点判定宕机时间加长【默认3秒】
discover.zen.ping_timeout: 5 -
设置选举触发互连节点最小数目:discover.zen.minimum_master_nodes:1(默认是1),该属性定义的是为了形成一个集群,有主节点资格并互相连接的节点的最小数目。建议设置成 (候选主节点数/2)+1
例:10个候选主节点互相连接,并且discover.zen.minimum_master_nodes:6,此时网络原因导致6个节点连接,其余4个节点连接,则其余4个节点不会形成一个新的集群。 -
数据节点
node.data:true
主节点和数据节点分开,主节点不存数据 -
客户端节点【分担主节点的请求分发、汇总(其实集群内任意节点都可以完成此任务)】
功能:为了负载均衡
node.master:false
node.data:false
-
集群搭建(节点+分片)
- 要求:
- 6 台物理机 6 个节点,3 个 master 节点 3 个 data 节点【角色分离,防止脑裂】
- 判定时间设为 10 秒
- 设置 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 网络:
- docker network ls:查看 docker 网络
- docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1 es-cluster
- docker network inspect es-cluster: 查看网络消息
- 创建容器带上 --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:查看所有节点,带*是主节点
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了