1、ElasticSearch
1.1、概念
1.1.1、分片(shard)
1、分片
在ES中所有数据的文件块,也是数据的最小单元块,整个ES集群的核心就是对所有分片的分布、索引、负载、路由等达到惊人的速度。
实列场景:
假设 IndexA 有2个分片,向 IndexA 中插入10条数据 (10个文档),那么这10条数据会尽可能平均的分为5条存储在第一个分片,剩下的5条会存储在另一个分片中。
2、分片的重要性
ES中所有数据均衡的存储在集群中各个节点的分片中,会影响ES的性能、安全和稳定性。
3、分片的作用
- 水平分割/扩展内容容量
- 在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量
4、分片个数(数据节点计算)
分片个数是越多越好,还是越少越好了?根据整个索引的数据量来判断。
实列场景:
如果 IndexA 所有数据文件大小是300G,改怎么定制方案了?(可以通过Head插件来查看)
建议(供参考):
- 每一个分片数据文件小于30-50GB;机械硬盘,不建议大于50G,SSD,可以大点,如100G
- 每一个索引中的一个分片对应一个节点
- 节点数大于等于分片数
- 从高可用/高并发的角度出发,官方建议,shard为节点的平方数
根据建议,至少需要 10 个分片。
结果: 建10个节点 (Node),Mapping 指定分片数为 10,满足每一个节点一个分片,每一个分片数据带下在30G左右。
SN(分片数) = IS(索引大小) / 30
NN(节点数) = SN(分片数) + MNN(主节点数[无数据]) + NNN(负载节点数)
5、分片设置
创建 IndexName 索引时候,在 Mapping 中可以如下设置分片 (curl)
PUT IndexName
{
"settings": {
"number_of_shards": 5
}
}
6、分片查询
可以指定es去具体的分片查询从而进一步的实现es极速查询。
- randomizeacross shards
随机选择分片查询数据,es的默认方式 - _local
优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。数据量是完整的。 - _primary
只在主分片中查询不去副本查,一般数据完整。 - _primary_first
优先在主分片中查,如果主分片挂了则去副本查,一般数据完整。 - _only_node
只在指定id的节点中的分片中查询,数据可能不完整。 - _prefer_node
优先在指定节点中查询,一般数据完整。 - _shards
在指定分片中查询,数据可能不完整。 - _only_nodes
可以自定义去指定的多个节点查询,es不提供此方式需要改源码。
7、shard&replica机制梳理
- index包含多个shard
- 每个shard都是一个最小工作单元,承载部分数据
- 增减节点时,shard会自动在nodes中负载均衡
- primary shard和replica shard
- replica shard是primary shard的副本,负责容错,以及承担读请求负载
- primary shard的默认数量是1,replica默认是1
- primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
- primary shard不能和自己的replica shard放在同一个节点上
8、单node创建index
- 单node环境下,创建一个index,有3个primary shard,3个replica shard,此时集群status是yellow,只会将3个primary shard分配到仅有的一个node上去,另外3个replica shard是无法分配的
- 集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求
9、两个node节点下replica shard分配
- 一台机器,这一台机器上就会有3个primary shard,3个replica shard ,此时集群状态为yellow
- 新加入了一台机器,会自动将3个replica shard分配到新的机器上去。primary shard的数据会拷贝到对应的replica shard上去
1.1.2、副本(replicas)
代表索引副本,es可以设置多个索引的副本。
副本的作用:
- 一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复
- 二是提高es的查询效率,es会自动对搜索请求进行负载均衡
1.1.3、数据恢复(recovery)
代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配;
挂掉的节点重新启动时也会进行数据恢复。
1.2、基础概念
2、ElasticSearch集群
2.1、集群规划
2.1.1、集群角色规划
实际上,一个节点在默认情况下会同时扮演:Master Node,Data Node 和 Ingest Node。
节点类型 | 配置参数 | 默认值 |
---|---|---|
Master | node.master | true |
Master Eligible | node.master | true |
Data | node.data | true |
Coordinating | 无 | 每个节点是协调节点;设置上面3个参数全为false为协调节点 |
Ingest | node.ingest | true |
MachineLearning | node.ml | true(需要enable x-pack) |
2.1.2、节点角色建议
1、分环境
- 在开发环境,一个节点可以承担多种角色
- 生产环境中,需要根据数据量,写入和查询的吞吐量,选择合适的部署方式,建议设置单一角色的节点(dedicated node)
2、ES2.X及之前版本节点角色概述
3、ES5.X节点角色清单
4、不同角色节点的配置选择
Dedicated Master
- 每一个节点启动后,默认就是Mastrt eligible节点(可以设置node.master: flase 禁止)
- mastrt eligible节点可以参加选主流程,成为Master节点
- 当第一个节点启动时,它将会把自己选举成Master节点
- 每一个节点都保存集群状态,只有Master节点才能修改集群的状态
- 集群状态,维护一个集群中的必要信息
- 所有节点信息
- 所有索引和其相关的Mapping和Setting信息
- 分片的路由信息
Dedicated Master Eligible Node
- 负责集群状态的管理;
- 使用低配置的 CPU,RAM 和磁盘;
Dedicated Data Node
- 负责数据存储及处理客户端请求;
- 使用高配置的 CPU,RAM 和磁盘;
Dedicated Ingest Node
- 负责数据处理;
- 使用高配置的 CPU,中等配置的 RAM,低配置的磁盘;
Coordinating only Node
- 高配或中配的 CPU,高配或中配的 RAM,低配的磁盘;
- 生产环境中,建议为一些大的集群配置 Coordinating Only Node,其扮演的角色:
Load Balancer,降低 Master 和 Data Nodes 的负载;
- 负责搜索结果的 Gather 和 Reduce;
- 有时无法预知客户端会发送怎样的请求,大量占用内存的聚合操作,比如一个深度聚合可能会发生 OOM;
Hot & warm节点
- 不同硬件配置的Data Node。把热门索引或者近期索引放在高配置节点(Hot节点)上,反而冷门索引和相对久远的数据放到低配置节点(warm节点)上。从而节省资源
Machine Learning 节点
- 用来跑机器学习的job,来发现数据中的异常
2.1.3、高可用ES部署原则
1、配置多个Dedicated Master Node
为什么要配置 多个Dedicated Master Node?
从高可用 & 避免脑裂的角度出发,需要配置多个 Dedicated Master Node
- 一般在生产环境中配置 3 台,当有1 台丢失的时候,其余的节点会被提升成活跃主节点;
- 一个集群必须有一台活跃的主节点,负责分片管理,索引创建,集群管理等操作;
Elasticsearch集群至少三个Master实例,并且,生产建议每个es实例部署在不同的设备上,三个Master节点最多只能故障一台Master节点,数据不会丢失; 如果三个节点故障两个节点,则造成数据丢失并无法组成集群。
三台Master做集群,其中一台被真正选为了Master,那么其它两台就是 eligible 节点。
2、Master Node 和 Data Node 或 Coordinating Node 分开部署
如果 Master Node 和 Data Node 或 Coordinating Node 混合部署
- Data Node 相对有比较大的内存占用;
- Coordinating Node 有时候会有开销很高的查询,导致 OOM;
- 这些都有可能影响 Master 节点,导致集群的不稳定;
3、Data Node 水平扩展
在Elasticsearch集群中,此节点应该是最多的。
- Data Node 在以下两种场景,可以不断扩展:
- 当磁盘容量无法满足时,可以增加 Data Node;
- 当磁盘读写压力大时,可以增加 Data Node;
4、Coordinating Node 水平扩展
- 当系统中有大量复杂查询及聚合的时候,增加 Coordinating Node,提升查询和聚合的性能;
- 可以在 Coordinating Node 前配置 LB,软件或硬件实现,此时 Application 只需要和 LB 交互;
5、读写分离与LB负载均衡
读请求发到 Coordinating Node;
写请求发到 Ingest Node;
Coordinating Node 和 Ingest Node 前都可以配置 LB;
2.1.4、高可用ES的部署规划
1、小型的ES集群的节点架构
小型的ES集群,就是3/5/7这种少于10个节点的集群。
对于3个节点、5个节点甚至更多节点角色的配置,Elasticsearch官网、国内外论坛、博客都没有明确的定义。
2、小型的ES集群的节点角色规划
- 对于Ingest节点,如果我们没有格式转换、类型转换等需求,直接设置为false。
- 3-5个节点属于轻量级集群,要保证主节点个数满足((节点数/2)+1)。
- 轻量级集群,节点的多重属性如:Master&Data设置为同一个节点可以理解的。
- 如果进一步优化,5节点可以将Master和Data再分离。
3、大型的ES集群的节点架构
ES数据库最好的高可用集群部署架构为:
三台服务器做master节点
N(比如20)台服务器作为data节点(存储资源要大)
N(比如2)台做ingest节点(用于数据转换,可以提高ES查询效率)
4、高可用进阶:异地多活部署场景(多个data center)
异地多活部署场景, 可以在多个data center 部署多套ES集群。
在多个data center的部署场景。 如何进一步保证ES集群的高可用呢
读高可用架构
这几个集群需要确保有相同的数据。通过gtm进行流量路由,将用户的读请求,路由到最优的集群。
GTM主要用来做数据的读取。
具体的读高可用架构图如下:
5、如何保证数据一致性
两种方案:
需要程序分别写入这几个集群,保持数据一致
- 由于建立索引的及时性,没有那么高,更多的情况,是写入消息队列。
- 各个数据中心的程序,去消费消息队列中的数据。
或者就写入一个集群 ,使用es的跨集群复制确保数据一致
- Elasticsearch(后面统称ES) cross-cluster replication (后面统称CCR)是ES 6.5的一个测试特性,是ES 6.7的的一个全局高可用特性。
- CCR将索引复制到其他ES集群,可以解决多个用例,包括跨数据中心高可用(HA),灾难恢复(DR)和CDN样体系结构,最终实现ES集群的高可用。
- CCR没有所谓的冲突监测,如果要独立flower,只需要暂定同步,关闭索引,取消对leader的关注,重新打开索引即可。
2.2、部署集群
2.2.1、系统参数
2.2.2、前期准备
1、创建用户
2、创建目录授权
mkdir -p /mnt/elastic/{data,logs}
chown -R hadoop:hadoop /mnt/elastic/
2.2.3、解压
tar -zxf elasticsearch-7.17.9-linux-x86_64.tar.gz -C /opt/module/
2.3、配置集群
2.3.1、修改配置
1、elasticsearch.yml
vi /opt/module/elasticsearch-7.17.9/config/elasticsearch.yml
# ---------------------------------- Cluster -----------------------------------
# 集群名称
cluster.name: elastic-cluster
# ------------------------------------ Node ------------------------------------
# 节点名称
node.name: node-01
# ----------------------------------- Paths ------------------------------------
# 存放数据目录
path.data: /mnt/elastic/data
# 存放日志目录
path.logs: /mnt/elastic/logs
# ----------------------------------- Memory -----------------------------------
bootstrap.memory_lock: false
# ---------------------------------- Network -----------------------------------
# 启动地址,如果不配置,只能本地访问
network.host: 192.168.47.10
# 对外提供服务的http端口,默认为9200
http.port: 9201
# 内部节点之间沟通端口
transport.port: 9301
# --------------------------------- Discovery ----------------------------------
# es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["node-01:9301", "node-02:9301", "node-03:9301"]
# es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["node-01", "node-02", "node-03"]
# 每隔多长时间ping一个node
##master选举/节点间通讯超时时间(这个时间的配置需要根据实际情况设置)
discovery.zen.fd.ping_interval: 30s
# 每次ping的超时时间
discovery.zen.fd.ping_timeout: 120s
# 一个node被ping多少次失败就认为是故障了
discovery.zen.fd.ping_retries: 6
# 当前节点是否可以被选举为master节点,是:true否:false
node.master: true
# 当前节点是否用于存储数据,是:true否:false
node.data: true
# 至少有两个节点才进行主节点选举,一般情况下会配置(n/2 + 1)个节点
discovery.zen.minimum_master_nodes: 2
# 至少要有两个节点以上才进行数据恢复
gateway.recover_after_nodes: 2
# 有三个节点上线后才进行数据恢复
gateway.expected_nodes: 3
# 等待5分钟才进行数据恢复,取决与两者哪个先达到
gateway.recover_after_time: 5m
#
indices.fielddata.cache.size: 20%
# http请求最大内容设置
http.max_content_length: 200mb
# 打开跨域支持head插件使用
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,X-Requested-With,Content-Length,Content-Type
# ---------------------------------- Security ----------------------------------
2、jvm.options
-Xms512m
-Xmx512m
3、使用ES自带jdk
vi elasticsearch-env
# now set the classpath
ES_CLASSPATH="$ES_HOME/lib/*"
ES_JAVA_HOME=/opt/module/elasticsearch-7.17.9/jdk
# now set the path to java
if [ ! -z "$ES_JAVA_HOME" ]; then
JAVA="$ES_JAVA_HOME/bin/java"
JAVA_TYPE="ES_JAVA_HOME"
elif [ ! -z "$JAVA_HOME" ]; then
# fallback to JAVA_HOME
echo "warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME" >&2
#JAVA="$JAVA_HOME/bin/java"
#JAVA_TYPE="JAVA_HOME"
JAVA="$ES_JAVA_HOME/bin/java"
JAVA_TYPE="ES_JAVA_HOME"
else
# use the bundled JDK (default)
if [ "$(uname -s)" = "Darwin" ]; then
# macOS has a different structure
JAVA="$ES_HOME/jdk.app/Contents/Home/bin/java"
else
JAVA="$ES_HOME/jdk/bin/java"
fi
JAVA_TYPE="bundled JDK"
fi
4、分发配置文件
scp elasticsearch.yml jvm.options node-02:/$PWD
5、启动服务
bin/elasticsearch -d -p pid
6、检查服务情况
# 服务器
curl http://node-01:9200
curl http://node-01:9200/_cat/nodes?v
curl http://node-01:9200/_cat/nodes?pretty
# 浏览器
http://node-01:9200
http://node-01:9200/_cat/health?v
http://node-01:9200/_cat/nodes?pretty
2.3.2、启用Xpack
1、生成CA证书
# 这里直接回车即可,不要设置密码
bin/elasticsearch-certutil ca
2、生成p12秘钥
# 这里直接回车即可,不要设置密码
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
3、拷贝p12秘钥文件
mkdir config/certs
cp elastic-certificates.p12 config/certs
4、分发p12秘钥文件
scp -r certs node-02:/$PWD
5、elasticsearch.yml(所有节点)
# ---------------------------------- Security ----------------------------------
# 开启xpack
xpack.security.enabled: true
xpack.license.self_generated.type: basic
xpack.security.transport.ssl.enabled: true
# 证书配置
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
6、重启elasticsearch个节点
bin/elasticsearch -d -p pid
7、设置密码
# 任意节点
bin/elasticsearch-setup-passwords interactive
8、登录验证
账号/密码:elastic/xxx
http://node-01:9200/_cat/health?v
2.4、管理集群
2.4.1、启停脚本
需要以普通用户用户启动elasticsearch集群,不能用root有户启动
xcall.sh "/opt/module/elasticsearch-7.17.9/bin/elasticsearch -d -p pid"
2.4.2、开机自启
1、查看开机启动服务
chkconfig --list
2、创建elasticsearch系统启动服务文件
vi /etc/init.d/elasticsearch
3、编写启动脚本
#!/bin/bash
#description: elasticsearch
#processname: elasticsearch-7.17.9
export ES_HOME=/opt/module/elasticsearch-7.17.9
case $1 in
start)
su hadoop<<!
cd $ES_HOME
./bin/elasticsearch -d -p pid
exit
!
echo "elasticsearch is started"
;;
stop)
pid=`cat $ES_HOME/pid`
kill -9 $pid
echo "elasticsearch is stopped"
;;
restart)
pid=`cat $ES_HOME/pid`
kill -9 $pid
echo "elasticsearch is stopped"
sleep 1
su hadoop<<!
cd $ES_HOME
./bin/elasticsearch -d -p pid
exit
!
echo "elasticsearch is started"
;;
*)
echo "start|stop|restart"
;;
esac
exit 0
4、修改文件权限
chmod 777 elasticsearch
5、添加和删除服务并设置启动方式
chkconfig --add elasticsearch
chkconfig --del elasticsearch
6、关闭和启动服务
service elasticsearch start
service elasticsearch stop
service elasticsearch restart
7、设置开机是否启动
chkconfig elasticsearch on
chkconfig elasticsearch off
8、验证是否启动
ps -ef | grep elasticsearch
4、修改文件权限
chmod 777 elasticsearch
5、添加和删除服务并设置启动方式
chkconfig --add elasticsearch
chkconfig --del elasticsearch
6、关闭和启动服务
service elasticsearch start
service elasticsearch stop
service elasticsearch restart
7、设置开机是否启动
chkconfig elasticsearch on
chkconfig elasticsearch off
8、验证是否启动
ps -ef | grep elasticsearch