# 部署
ES 常见的部署架构:
- 单实例
- 集群
- 由多个实例组成分布式集群,获得更大的容量、更高的性能,还可通过冗余节点提高可用性。
- 远程集群
- 远程集群与本地集群之间独立工作,但可以查询、拷贝其数据,实现横向扩容。
# 版本
ElasticSearch、Kibana 的开源版本又称为社区版(OSS),只提供了基础功能。其它功能通过一组闭源插件 x-pack 提供。
- x-pack 提供的 Monitoring、Grok Debugger 等功能是免费使用的,属于 basic license ,但 Security、Alerting 等功能是收费的。
- 详见 Elastic 公司的 订阅列表 (opens new window) 。
v1.0
- :于 2010 年发布。最初由 Shay Banon 开发,后来由 Elastic 公司管理。
v6.0
- :于 2017 年发布。
- 创建索引时,只能定义一个 type ,默认命名为 _doc 。
v7.0
- :于 2019 年发布。
- 创建索引时,建议不包含 type 。
- number_of_shards 默认值从 5 改为 1 。
- 终端日志改为 JSON 格式。
- 默认配置了
"search.max_open_scroll_context": 500
。建议将 scroll 请求改为 PIT + search_after 请求。 - 从 v6.8、v7.1 版本开始,将 x-pack 中的 RBAC 身份认证、TLS 加密通信改为免费功能。
- 启用方法:在 elasticsearch.yml 中加入
xpack.security.enabled: true
,然后执行bin/elasticsearch-setup-passwords auto
生成各个内置用户的密码。
- 启用方法:在 elasticsearch.yml 中加入
- v7.8 新增了可组合的索引模板(composable index template)。
- v7.10 新增了 PIT(point in time)。
v8.0
- :于 2022 年发布。
- 创建索引时,禁用 type 。
- 内置字段 _id 默认禁用 fielddata ,避免占用大量 JVM 内存,因此不支持 aggregations、sorting、scripting 操作。给集群配置
"indices.id_field_data.enabled": true
才会启用。 - 初次部署 ES 时,默认会自动修改
config/elasticsearch.yml
文件,启用 x-pack 中的 RBAC 身份认证、TLS 加密通信。- 它会自动生成自签名的 TLS 证书文件,保存到
config/certs/
目录下,有三个文件:http_ca.crt # CA 证书文件,用于签署 http.p12 证书 http.p12 # ES 提供 HTTP 端口供客户端访问时,采用该证书进行 TLS 加密通信 transport.p12 # ES 集群的各节点通过 TCP 端口相互通信时,采用该证书进行 TLS 加密通信
- 用户需要执行以下命令,为内置用户生成随机密码。
bin/elasticsearch-reset-password --url https://localhost:9200 -u elastic bin/elasticsearch-reset-password --url https://localhost:9200 -u kibana_system
- 用户需要拷贝
config/certs/http_ca.crt
这个 CA 证书文件,给访问 ES 的客户端使用,例如:如果客户端不使用 CA 证书文件,则不能验证 ES 服务器的身份,只能忽略 TLS 认证,例如:curl https://localhost:9200 --cacert http_ca.crt -u elastic
curl https://localhost:9200 -k -u elastic
- 它会自动生成自签名的 TLS 证书文件,保存到
# 单实例
# 部署
下载二进制版:
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.0-linux-x86_64.tar.gz
解压后运行:
bin/elasticsearch # 在前台运行 -d # 以 daemon 方式运行
- 运行时需要 JDK 环境,不过二进制发行版自带了一个 JDK 。
- 安装插件时,只需将插件解压到 plugins 目录下。
或者用 docker-compose 部署:
version: '3' services: elasticsearch: container_name: elasticsearch image: elasticsearch:7.10.0 restart: unless-stopped ports: - 9200:9200 # - 9300:9300 volumes: - ./config:/usr/share/elasticsearch/config - ./data:/usr/share/elasticsearch/data
- 容器内以非 root 用户运行服务,需要调整挂载目录的权限:
mkdir -p data chown -R 1000 .
- 容器内以非 root 用户运行服务,需要调整挂载目录的权限:
# 配置
ES 启动时会检查 Linux 主机是否满足以下条件,如果不满足则会发出警告。如果此时还配置了
network.host
参数,则 ES 会按生产环境严格要求,将这些警告升级为异常。- 禁用 Swap 分区:
- 需要执行命令
swapoff -a
,并且将/etc/fstab
文件中的 swap 分区都注释。
- 需要执行命令
- 增加进程的内存映射区域数量的上限:
- 需要执行命令
sysctl vm.max_map_count=262144
,并在/etc/sysctl.conf
文件中永久修改该参数。
- 需要执行命令
- 增加进程数量的上限:
- 需要执行命令
ulimit -u 4096
,并在/etc/security/limits.conf
文件中永久修改该参数。
- 需要执行命令
- 增加文件描述符数量的上限:
- 需要执行命令
ulimit -n 65535
,并在/etc/security/limits.conf
文件中永久修改该参数。
- 需要执行命令
- 禁用 Swap 分区:
可以在
config/jvm.options
文件中配置 ES 的 JVM :-Xms4g -Xmx4g
- JVM -Xmx 过低时,会频繁引发 GC ,增加 CPU 负载,增加 ES 读写耗时。
- 建议 JVM -Xmx 不超过 32G 。
- 超过 32G 时,内存的寻址范围变大,JVM 会停止使用 CompressedOops 压缩指针,改为使用普通指针,导致多占用 10 多 GB 的内存。
- 如果需要使用超过 32G 的内存,则建议增加 ES 集群的节点数,横向扩容。
- 主机应该留出一些空闲内存,相当于 JVM -Xmx 的 0.5~1 倍,用作 Page Cache ,提高 Lucene 读写磁盘的性能。
ES 的主配置文件是
config/elasticsearch.yml
。修改它之后,需要重启 ES 才会生效。- 部署 ES 集群时,修改一个 elasticsearch.yml 只会作用于一个 ES 节点,因此需要同步修改所有 ES 节点的配置文件。
elasticsearch.yml 的内容示例:
cluster.name: cluster-1 # 该 ES 所属的集群名 discovery.type: single-node # 发现模式。这里取消发现集群的其它节点,从而部署成单实例 node.name: node-1 # 该 ES 的节点名,默认采用当前主机名 # path.data: /var/data/elasticsearch # path.logs: /var/log/elasticsearch network.host: 0.0.0.0 # 该 ES 的 Socket 绑定的 IP network.publish_host: 10.0.0.1 # 该 ES 公布给集群中其它 ES 的 IP ,供它们访问。默认等于 network.host # transport.port: 9300 # TCP 通信监听的端口,供集群中其它 ES 节点访问 # 关于 HTTP API # http.port: 9200 # HTTP 通信监听的端口,供用户访问 # http.max_initial_line_length: 4kb # 允许接收的 HTTP 请求的 URL 长度 # http.max_header_size: 8kb # 允许接收的 HTTP 请求的 header 体积 # http.max_content_length: 100mb # 允许接收的 HTTP 请求的 body 体积(解压之后) # http.compression: true # 是否压缩 HTTP 响应的 body # http.compression_level: 3 # 压缩级别,取值范围为 1~9 ,9 的压缩率最高 # http.cors.enabled: false # 是否允许 CORS 请求 xpack.monitoring.enabled: false # 是否启用对 ELK 自身的监控,默认为 true ,监控数据保存到索引 .monitoring-* # xpack.security.enabled: true # 是否启用 security 功能,包括 RBAC 身份认证、TLS 加密通信等 # xpack.security.http.ssl.enabled: true # ES 提供 HTTP 端口供客户端访问时,是否启用 TLS 加密通信 # xpack.security.transport.ssl.enabled: true # ES 集群的各节点通过 TCP 端口相互通信时,采用启用 TLS 加密通信
ES 允许在运行时通过 API 修改一些配置参数,称为动态参数(Dynamic)。而其它配置参数称为静态参数(Static)。
- 动态参数分为两种作用域:
- persistent :持久配置,即使集群重启也会生效。
- transient :暂时配置,在集群重启之后失效。
- 集群按以下优先级顺序采用配置参数:
- transient
- persistent
- 配置文件
- 默认配置
- 例:将一个参数的 transient 值设置为 null ,或者等集群重启,则会采用该参数的 persistent 值。
- 修改动态参数的示例:
PUT /_cluster/settings { "persistent": { "indices.id_field_data.enabled": false, # 内置字段 _id 是否启用 fielddata ,ES v8 开始默认禁用 "indices.recovery.max_bytes_per_sec": "50mb", # 每个节点执行 peer recovery 或 snapshot recovery 操作时,最大的 IO 速度 "cluster.max_shards_per_node": 1000 # 每个数据节点最多打开的 shard 数量(包括主分片、副分片、unassigned_shards,不包括 closed 索引的分片),默认为 1000 }, "transient" : { "indices.recovery.max_bytes_per_sec" : "20mb" } }
- 动态参数分为两种作用域:
# 备份数据
ES 备份数据的几种方式:
- 通过 Snapshot API 创建快照文件。
- 适合离线备份,备份速度快。
- 通过 reindex API 将远程集群的数据拷贝到本地集群。
# 集群
# 部署
部署 ES 集群时,需要部署多个 ES 实例,在它们的 elasticsearch.yml 中都加入以下配置:
# discovery.type: single-node # 不部署成单节点 discovery.seed_hosts: # 声明该集群的所有节点,默认值为 127.0.0.1、[::1] - 10.0.0.1:9300 - 10.0.0.2:9300 - 10.0.0.3:9300
- 每个 ES 节点启动时,会自动根据
discovery.seed_hosts
连接到其它 ES 节点,如果它们拥有相同的cluster.name
,则组成同一个 ES 集群。
- 每个 ES 节点启动时,会自动根据
初次启动 ES 集群时,尚未选举出主节点。第一个启动的 ES 节点应该属于主资格节点,并临时添加以下配置:
cluster.initial_master_nodes: - node-1 # 指定当前节点的名称或 IP
- 这表示初始的主资格节点有哪些,需要从中选举出一个节点,担任主节点。
- ES 集群初次启动成功之后,即可删除
cluster.initial_master_nodes
配置。此后如果重启 ES 节点、新增 ES 节点,会自动根据discovery.seed_hosts
连接到其它 ES 节点,获知当前的主节点地址。
# 节点
ES 集群(cluster)中,每个 ES 实例称为一个节点(node)。
- 全部节点中,有且仅有一个主节点(master),负责管理集群,比如增删索引、分配分片给某个节点。
一个 ES 节点可以担任多种角色:
master
- :主资格节点(master-eligible),有资格被选举为主节点。
- ES 集群中可存在一个或多个主资格节点,会自动选举出一个节点,担任主节点。
- 只有主资格节点有权参与主节点的选举投票,data、coordinating 等角色的节点无权参与 。
- 可以给某个主资格节点配置
node.voting_only: true
,表示只参与选举投票,不会当选。
data
- :数据节点,负责存储数据,支持增删查改、聚合等操作。
- master 和 data 节点都需要使用
path.data
目录。
ingest
- :摄取节点,负责将管道应用于文档,以便在建立索引之前加工文档。
ml
- :机器学习节点。集群至少拥有一个此类节点才能提供机器学习功能。
remote_cluster_client
- :远程集群节点,可以连接到远程集群,作为其客户端。
transform
- :转换节点。提供转换功能。
coordinating
- :协调节点。它是每个节点的隐式角色,不能取消。
- 每个节点都知道各个文档存储在哪个节点上,也默认可以处理用户的 HTTP 请求。
因此用户可以向任意节点发出查询请求,该节点会将请求转发给存储相应文档的数据节点(可能有多个),然后将查询结果返回给用户。
节点的默认角色配置如下:
node.master: true node.voting_only: false node.data: true node.ingest: true node.ml: true cluster.remote.connect: true
在以下情况下,主资格节点会发起主节点的选举:
- 发现它自己不是主节点。
- 询问其它节点,发现大家都没有连接到主节点。
- 发现有至少
discovery.zen.minimum_master_nodes
个主资格节点没有连接到主节点。该参数的默认值为:主资格节点总数/2 + 1
ES 集群的高可用方案:
- 部署至少 3 个主资格节点,其中至少 2 个节点为
node.voting_only: false
,从而可以通过选举更换主节点。 - 不能同时停止 50% 数量的主资格节点,否则集群不能投票决策。但可以分多次停止。
- 让每个节点专注于一种角色,以减少不相关的工作负担。比如配置专用的主节点:
node.master: true node.voting_only: false node.data: false node.ingest: false node.ml: false cluster.remote.connect: false
- 部署至少 3 个主资格节点,其中至少 2 个节点为
# 管理
相关 API :
GET / # 查询集群的基本信息 GET /_cluster/stats # 查询集群的统计信息 GET /_cluster/health # 查询集群的健康状态 GET /_cluster/settings # 查询集群的配置 GET /_nodes # 查询所有节点的配置 GET /_nodes/stats # 查询所有节点的状态
例:查询所有节点
[root@CentOS ~]# curl 127.0.0.1:9200/_cat/nodes?v ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 10.0.0.1 11 85 1 0.06 0.09 0.18 dilm * node-1
例:查询集群的基本信息
[root@CentOS ~]# curl 127.0.0.1:9200 { "name" : "node-1", "cluster_name" : "cluster-1", "cluster_uuid" : "cDXF4mIeRqK4Dlj_YmSSoA", "version" : { "number" : "7.10.0", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "7f634e9f44834fbc12724506cc1da681b0c3b1e3", "build_date" : "2020-02-06T00:09:00.449973Z", "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" }
例:查询集群的健康状态
[root@CentOS ~]# curl 127.0.0.1:9200/_cluster/health?pretty { "cluster_name" : "cluster-1", "status" : "yellow", # 集群的状态 "timed_out" : false, "number_of_nodes" : 1, # 节点的数量 "number_of_data_nodes" : 1, # 数据节点的数量 "active_shards" : 4, # 可用分片的数量,包括主分片、副分片,不包括未分配的分片 "active_primary_shards" : 4, # 可用主分片的数量 "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 4, # 未分配的分片的数量 "delayed_unassigned_shards" : 0, "number_of_pending_tasks" : 0, "number_of_in_flight_fetch" : 0, "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 50.0 }
- status 的可能取值:
- green :所有主分片、副分片都可用。
- yellow :所有主分片都可用,但存在不可用的副分片。
- red :存在不可用的主分片。
- status 的可能取值:
例:查询所有索引的状态
[root@CentOS ~]# curl 127.0.0.1:9200/_cat/indices?v health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open class aeUT1h6QS8-vSAzoEclR3Q 1 1 0 0 283b 283b yellow open test_log EaDptPz9TtqGk-CNL-yTMg 1 1 1 0 4.4kb 4.4kb
- health 表示分片的状态,status 表示索引是否被关闭。
- 这里索引的 health 为 yellow ,是因为只部署了单实例 ES ,而副分片不能被分配到主分片所在节点上,导致一直处于未分配状态。
# 远程集群
- ES 支持给本地集群添加多个远程集群(remote cluster)。
- 这些集群之间会独立工作,独立存储自己的数据。
- 这是单向连接,本地集群故障时不会影响远程集群,但远程集群故障时可能影响本地集群。
- 用户可以跨集群搜索,同时查询本地集群和远程集群,从而实现 ES 的横向扩容。
- 原理:
- 用户将跨集群的查询请求发送到本地集群。
- 本地集群验证用户的身份,如果有效,则将请求及用户的身份转发到远程集群。
- 远程集群验证用户的身份,如果有权访问指定的数据,则执行查询,然后将查询结果返回给本地集群。
- 本地集群将远程集群的查询结果返回给用户。
- 本地集群使用的 SSL 公钥必须受到远程集群的信任。
- 用户账号必须在本地集群、远程集群都存在。
- 原理:
# 配置
可以在 elasticsearch.yml 文件中配置远程集群,但这只会对当前节点生效。如下:
cluster: remote: cluster_1: # 添加一个远程集群,该名称不必与目标集群的实际名称一致 seeds: - 10.0.0.1:9300 # 远程集群中的节点列表 cluster_2: # 添加另一个远程集群 seeds: - 10.0.0.2:9300 # transport.initial_connect_timeout: 30s # 启动当前节点时,第一次连接到远程集群的超时时间 # transport.ping_schedule: 30s # 每隔多久检查与远程集群的连接是否正常正常,默认为 -1 ,即不检查 # transport.compress: true # 将请求压缩之后再发送到远程集群 # skip_unavailable: false # 跨集群搜索时是否跳过不可用集群
也可以通过 API 添加远程集群,上传其配置信息:
PUT /_cluster/settings { "persistent": { "cluster": { "remote": { "cluster_1": { "seeds": [ # 设置 "seeds": null 则会删除该远程集群 "127.0.0.1:9300" ] }, "cluster_2": { "seeds": [ "10.0.0.2:9300" ] } } } } }
相关 API :
GET /_cluster/settings # 查询集群的配置,包括远程集群 GET /_remote/info # 查询远程集群的状态
# 查询
用
<cluster_name>:<index_name>
的格式,即可查询远程集群的索引:GET /test_log/_search # 不指定集群名,则默认查询本地集群 GET /cluster_1:test_log/_search # 可以指定一个集群进行查询 GET /test_log,cluster_1:test_log,cluster_2:test_log/_search # 可以指定多个集群进行查询
可创建指向远程集群的 index pattern ,例如:
cluster_1:test_log