包含一个或多个启动着的ES实例的机器群。通常一台机器起一个ES实例
同一网络下,集群名一样的多个ES实例自动组成集群,自动均衡分片等行为。默认集群名为“elasticsearch”
集群名通过配置文件修改,或者在命令行中 -E cluster.name=es-cluster进行设定
维护了一个集群中,必要的信息,包括:所有的节点信息,所有的索引和其相关的Mapping与Setting信息,分片的路由信息
Master节点负责维护并且更新Cluster State
GET /_cat/nodes?v #查看节点信息
GET /_cat/health?v #查看集群当前状态:红、黄、绿
GET /_cat/shards?v #查看各shard的详细情况
GET /_cat/shards/{index}?v #查看指定分片的详细情况
GET /_cat/master?v #查看master节点信息
GET /_cat/indices?v #查看集群中所有index的详细信息
GET /_cat/indices/{index}?v #查看集群中指定index的详细信息
每个ES实例称为一个节点。节点名自动分配,也可以手动配置
节点名称通过配置文件配置,或者启动时候 -E node.name=node1指定
每一个节点在启动之后,会分配一个UID,保存在data目录下
每个节点启动后,默认就是一个Master-eligible节点
可以设置node.master: false禁用
负责索引的创建与删除,决定分片被分配到哪个数据节点,维护并且更新Cluster State
当第一个节点启动的时候,它会将自己选举成Master节点
每个节点上都保存了集群的状态,只有Master节点才能修改集群的状态信息
Master节点非常重要要考虑解决单点的问题,为一个集群设置多个Master节点每个节点只承担Master的单一角色
可以保存数据的节点
ES实例默认就是数据节点,可以通过node.data: false来改变
负责接受Client的请求,将请求分发到合适的节点上,最终把结果汇集到一起返回
每个节点默认都是协调节点
数据前置处理转换节点,支持pipeline管道设置,可以使用ingest对数据进行过滤、转换等操作
不同硬件配置的Data Node,用来实现Hot&Warm架构,降低集群部署的成本
负责跑机器学习的Job,用来做异常检测
Index数据过大时,将Index里面的数据,分为多个Shard,分布式的存储在各个服务器上面。可以支持海量数据和高并发,提升性能和吞吐量,充分利用多台机器的CPU
PUT /blogs
{
settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
discovery.seed_providers: file
10.10.10.5
10.10.10.6:9305
10.10.10.5:10005
# an IPv6 address
[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:9301
# 指定集群名称3个节点必须一致
cluster.name: es‐cluster
# 指定节点名称,每个节点名字唯一
node.name: node‐1
# 是否有资格为master节点,默认为true
node.master: true
#是否为data节点,默认为true
node.data: true
# 绑定ip,开启远程访问,可以配置0.0.0.0
network.host: 0.0.0.0
#指定web端口
#http.port: 9200
#指定tcp端口
#transport.tcp.port: 9300
#用于节点发现
discovery.seed_hosts: ["es‐node1", "es‐node2", "es‐node3"]
#7.0新引入的配置项,初始仲裁,仅在整个集群首次启动时才需要初始仲裁。
#该选项配置为node.name的值,指定可以初始化集群节点的名称
cluster.initial_master_nodes: ["node‐1","node‐2","node‐3"]
#解决跨域问题
http.cors.enabled: true
http.cors.allow‐origin: "*"
version: "3.1"
services:
es01:
image: elasticsearch:7.6.2
container_name: es01
environment:
- node.name=es01 # 节点名称
- cluster.name=es-docker-cluster # 集群名称,只有在一个集群名称下才能形成一个集群
- discovery.seed_hosts=es02,es03 # 集群中另外节点的IP地址
- cluster.initial_master_nodes=es01,es02,es03 # 哪些节点可以参与选举,也就是候选主节点
- ES_JAVA_OPTS=-Xms512m -Xmx512m # ES最大最小内存
- bootstrap.memory_lock=true # 不知道干啥的可以不写
- http.cors.enabled=true # 允许跨域
- http.cors.allow-origin=* # 允许的源
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es01:/usr/share/elasticsearch # ES的目录
ports:
- 9200:9200 # ES访问端口
es02:
image: elasticsearch:7.6.2
container_name: es02
environment:
- node.name=es02 # 节点名称
- cluster.name=es-docker-cluster # 集群名称,只有在一个集群名称下才能形成一个集群
- discovery.seed_hosts=es01,es03 # 集群中另外节点的IP地址
- cluster.initial_master_nodes=es01,es02,es03 # 哪些节点可以参与选举,也就是候选主节点
- ES_JAVA_OPTS=-Xms512m -Xmx512m # ES最大最小内存
- bootstrap.memory_lock=true # 不知道干啥的可以不写
- http.cors.enabled=true # 允许跨域
- http.cors.allow-origin=* # 允许的源
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es02:/usr/share/elasticsearch # ES的目录
ports:
- 9201:9200 # ES访问端口
es03:
image: elasticsearch:7.6.2
container_name: es03
environment:
- node.name=es03 # 节点名称
- cluster.name=es-docker-cluster # 集群名称,只有在一个集群名称下才能形成一个集群
- discovery.seed_hosts=es01,es02 # 集群中另外节点的IP地址
- cluster.initial_master_nodes=es01,es02,es03 # 哪些节点可以参与选举,也就是候选主节点
- ES_JAVA_OPTS=-Xms512m -Xmx512m # ES最大最小内存
- bootstrap.memory_lock=true # 不知道干啥的可以不写
- http.cors.enabled=true # 允许跨域
- http.cors.allow-origin=* # 允许的源
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- ./es03:/usr/share/elasticsearch # ES的目录
ports:
- 9202:9200 # ES访问端口
networks:
default:
external:
name: elk
http://192.168.65.174:9200/_cat/nodes?pretty
主要是修改kibana.yml
# 主要是添加这一项
elasticsearch.hosts: ["http://192.168.65.174:9200","http://192.168.65.19
2:9200","http://192.168.65.204:9200"]
连接其中一个节点就行
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/configuring-stack-security.html
ElasticSearch集群内部的数据是通过9300进行传输的,如果不对数据加密,可能会造成数
据被抓包,敏感信息泄露
解决方案:为节点创建证书
省略…
在生产环境中建议建议设置单一角色的节点
# Master节点
node.master: true
node.ingest: false
node.data: false
# data节点
node.master: false
node.ingest: false
node.data: true
# ingest 节点
node.master: false
node.ingest: true
node.data: false
# coordinate节点
node.master: false
node.ingest: false
node.data: false
从高可用&避免脑裂的角度出发:
集群处在三个数据中心,数据三写,GTM分发读请求
GTM 是通过DNS将域名解析到多个IP地址,不同用户访问不同的IP地址,来实现应用服务流量的分配。同时通过健康检查动态更新DNS解析IP列表,实现故障隔离以及故障切换。最终用户的访问直接连接服务的IP地址,并不通过GTM。而 SLB 是通过代理用户访问请求的形式将用户访问请求实时分发到不同的服务器,最终用户的访问流量必须要经过SLB。 一般来说,相同Region使用SLB进行负载均衡,不同region的多个SLB地址时,则可以使用GTM进行负载均衡
ES 跨集群复制 (Cross-Cluster Replication)是ES 6.7的的一个全局高可用特性。CCR允许不同的索引复制到一个或多个ES 集群中
# 标记一个 Hot 节点
elasticsearch.bat ‐E node.name=hotnode ‐E cluster.name=tulingESCluster ‐E
http.port=9200 ‐E path.data=hot_data ‐E node.attr.my_node_type=hot
# 标记一个 warm 节点
elasticsearch.bat ‐E node.name=warmnode ‐E cluster.name=tulingESCluster ‐
E http.port=9201 ‐E path.data=warm_data ‐E node.attr.my_node_type=warm
# 查看节点
GET /_cat/nodeattrs?v
创建索引时候,指定将其创建在hot节点上
# 配置到 Hot节点
PUT /index‐2022‐05
{
"settings":{
"number_of_shards":2,
"number_of_replicas":0,
"index.routing.allocation.require.my_node_type":"hot"
}
}
Index.routing.allocation是一个索引级的dynamic setting,可以通过API在后期进行设定
# 配置到 warm 节点
PUT /index‐2022‐05/_settings
{
"index.routing.allocation.require.my_node_type":"warm"
}
一个集群总共需要多少个节点?一个索引需要设置几个分片?规划上需要保持一定的余量,当负载出现波动,节点出现丢失时,还能正常运行
默认情况下,每个节点都是master eligible节点,因此一旦master节点宕机,其它候选节点会选举一个成为主节点。当主节点与其他节点网络故障时,可能发生脑裂问题
为了避免脑裂,需要要求选票超过(eligible节点数量+1 )/2才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题
当新增文档时,应该保存到不同分片,保证数据均衡,那么coordinating node如何确定数据该存储到哪个分片呢?Elasticsearch会通过hash算法来计算文档应该存储到哪个分片:
# 1._routing默认是文档id
# 2.算法与分片数量有关,因此索引库一旦创建,分片数量不能修改
shard = hash(_routing) % number_of_shards
集群的Master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移