Elasticsearch 6.5.4,这个版本在很多人眼里已经算“老家伙”了,但直到今天,它仍然活跃在一大堆公司的生产环境里:日志平台、订单检索、商品搜索,甚至一些跑了好几年没敢动的业务系统。前段时间我把内网一套ES从单节点扩成3节点集群,中间踩了不少坑,也把常见的报错挨个处理了一遍。这篇文章就把整个 elasticsearch-6.5.4 集群部署过程完整记录下来,从环境初始化、配置文件解读,到三节点联调,最后把部署和运行时最常见的错误全部贴出来,附上报错现场、原因分析和解决办法。不管你是刚从单机ES迁移到集群的运维,还是第一次在测试环境搭ES集群的开发,这篇都能直接照着抄。
1. 项目概述与集群设计思路
1.1 为什么从单节点升级到三节点集群
很多人一开始接触ES都是单节点跑着玩,装好、启动、建索引、写数据,看起来一切正常。可一旦数据量上来,单节点的问题就藏不住了:JVM堆内存涨上去之后GC越来越卡,机器宕机数据直接不可用,想给索引配副本都配不了——因为副本分片不能和主分片放在同一个节点上,这不只是ES的限制,而是分布式系统的基础逻辑。
ES集群的核心就是把一个索引拆成多个分片(shard),散到不同节点上,每个分片还能配副本(replica)。这样单点挂了,其他节点上的副本还能继续服务;查询也可以并行打到多个分片,吞吐量比单机高出一截。生产环境里最常见的起步配置就是三节点,原因很简单:三节点可以同时容忍一个节点宕机,还能正常选出主节点。两个节点看着省钱,实际上很容易出现集群脑裂或主节点选举僵局,维护成本反而高。
这次部署的硬件环境是三台CentOS 7.6虚拟机,配置都是4核16G内存、100G数据盘。ES版本固定为6.5.4,主要考虑是这套环境和现有的日志采集链路已经跑通,升级大版本会牵扯到数据迁移、插件兼容、客户端版本等一系列改动,代价不小。如果是全新项目,我会建议直接上更新的版本;但存量系统里,6.5.4稳定跑着,别乱动就是最好的方案。
1.2 节点角色和硬件规划
ES 6.5.4里节点角色主要通过两个参数控制:node.master和node.data。简单理解,node.master: true表示这个节点有资格参与主节点选举,负责集群级别的元数据管理、索引创建删除、分片分配等操作;node.data: true表示这个节点负责存储数据、执行搜索和写入请求。
规划节点角色时不要想得太复杂。小集群(3到5个节点)最省事的做法是每个节点都同时承担 master 候选和 data 角色,也就是“混合节点”。只有当集群规模到了几十个节点、主节点负载明显偏高时,才需要拆出专门的 master 节点,避免数据节点频繁执行大查询把主节点拖垮。
这次三台机器的角色规划如下:
| 节点名 | IP | 角色 | 内存 | 数据盘 |
|---|---|---|---|---|
| node-1 | 192.168.80.101 | master候选 + data | 16G | 100G |
| node-2 | 192.168.80.102 | master候选 + data | 16G | 100G |
| node-3 | 192.168.80.103 | master候选 + data | 16G | 100G |
三节点全部设为 master 候选,是因为minimum_master_nodes这个防脑裂配置在奇数节点下最好算:候选节点数除以2加1,三节点就是2。如果只有两个节点是 master 候选,公式是2/2+1=2,也能运行,但一旦其中一个挂了,剩下的节点凑不够法定票数,整个集群就会停止服务,没有意义。
1.3 大数据集群部署的基本策略
做集群部署,最忌讳的是“装完再说”。ES集群虽然是软件层面的事情,但真正决定它稳不稳定的,往往是装之前的规划。我的习惯是先走一遍下面的清单,再动手指安装:
- 网络规划:三台机器内网互通,防火墙放行9200和9300端口,/etc/hosts里写好三台机器的解析记录。这一步没做好,后面会出现各种诡异的节点连接失败。
- 系统参数:JDK版本、
vm.max_map_count、文件句柄数、内存锁定限制,这些必须在启动ES之前调整完,否则会撞上一连串bootstrap check错误。 - 目录规划:数据目录、日志目录单独划分磁盘,不要和系统盘挤在一起。ES的写入放大效应很明显,数据盘满了会直接导致集群只读。
- 部署顺序:先单节点启动,确认没报错,再逐台加入,最后统一验证集群状态。
这套思路不光是ES适用,搭其他大数据组件(比如Kafka、HDFS)也是同一个套路:先设计再实施,启动失败时通过日志定位,而不是反复重启碰运气。
2. 环境准备与基础配置
2.1 JDK 1.8 安装与版本确认
ES 6.5.4官方要求JDK 1.8及以上,这里我直接用的是系统安装的OpenJDK 1.8。如果不想在服务器上装额外的东西,发行包里也带了自检逻辑,但生产环境我建议还是手动装一个明确的JDK版本,方便后续排查问题。
# 查看是否已安装JDK java -version # CentOS 7下用yum安装OpenJDK 1.8 yum install -y java-1.8.0-openjdk-devel # 确认JAVA_HOME echo $JAVA_HOME # 如果没有输出,在/etc/profile里加一行并source # export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk这里有一个容易忽略的坑:如果服务器上同时存在多个JDK版本,JAVA_HOME指到了JDK 11甚至更高版本,ES 6.5.4在启动时可能会报版本不兼容或者一些奇怪的类加载错误。所以在启动ES之前,先单独执行一次java -version,确认是1.8,再往下走。
2.2 系统参数调优:内核、文件句柄、内存锁定
ES官方文档里特别强调的Linux系统参数有三个,少一个都会导致启动失败或运行期性能问题。
第一个是vm.max_map_count,默认值是65530,ES要求至少262144。这个参数控制的是进程最多能拥有的内存映射区域数量,ES用mmap加载索引段文件,数据量大以后很容易触到上限。启动时如果没调,错误信息长这样:
[1] bootstrap checks failed [1]: max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]解决办法就是改内核参数并持久化:
sysctl -w vm.max_map_count=262144 echo "vm.max_map_count = 262144" >> /etc/sysctl.conf sysctl -p第二个是文件句柄数。ES进程需要打开大量文件,每个分片、每个索引段、日志文件都要占用fd,默认的4096根本不够。修改方式是在/etc/security/limits.conf里给ES用户加上限制:
cat >> /etc/security/limits.conf <<EOF esuser soft nofile 65536 esuser hard nofile 65536 esuser soft nproc 4096 esuser hard nproc 4096 esuser soft memlock unlimited esuser hard memlock unlimited EOF第三是内存锁定。如果你打算在elasticsearch.yml里设置bootstrap.memory_lock: true,就必须给用户配置memlock unlimited,否则启动会报“memory locking requested for elasticsearch process but memory is not locked”。所以limits.conf里那两行memlock不要漏掉。
2.3 创建用户与目录规划
ES出于安全考虑,不允许用root直接启动,报错信息很直接:“can not run elasticsearch as root”。所以需要单独建一个系统用户。
groupadd esgroup useradd -m -s /bin/bash -g esgroup esuser mkdir -p /data/es-data /data/es-logs chown -R esuser:esgroup /data/es-data /data/es-logs数据目录和日志目录分开放,这个细节看着不起眼,实际很有用。ES运行一段时间后,数据目录体积会涨得很快,日志如果也写在里面,排错时想清理日志就很不方便,数据盘和日志盘混在一起还容易相互影响。
下载和安装直接解压就行:
cd /usr/local wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.tar.gz tar -zxvf elasticsearch-6.5.4.tar.gz mv elasticsearch-6.5.4 /usr/local/elasticsearch chown -R esuser:esgroup /usr/local/elasticsearchES的安装包是免编译的,解压就能用,这也是它部署起来相对快的原因。但解压之后一定要记得改属主,否则以esuser用户启动时会遇到权限问题的报错,很容易被误判成别的问题。
3. 集群核心配置详解
3.1 集群名称、节点名称与角色划分
ES的配置文件在/usr/local/elasticsearch/config/elasticsearch.yml。第一个要改的是cluster.name,这是集群的“身份证”,只有相同cluster.name的节点才会加入同一个集群。默认值是“elasticsearch”,生产环境一定要改成自己的名字,否则内网里如果有别的ES实例,可能发生节点串集群的尴尬事故。
node.name是节点在集群里的名字,必须唯一。建议和机器名保持一致,这样在监控面板里一眼就能看出是哪台机器出了问题。我在node-1上配置如下:
cluster.name: es-cluster-prod node.name: node-1 node.master: true node.data: truenode.master和node.data都设为true,在自定义ES的时候要特别注意:如果一个节点node.master和node.data都是false,那这个节点就是个客户端节点,只转发请求不存储数据。小集群里一般不需要这样的节点,白白浪费一台机器。
3.2 网络绑定、端口与跨域设置
网络配置是初学者最容易懵的地方。network.host决定ES监听在哪个IP上。默认是127.0.0.1,也就是只能本机访问。要让集群节点间互相通信,必须绑到内网IP,最简单的写法是:
network.host: 192.168.80.101 http.port: 9200 transport.tcp.port: 9300http.port是供REST API调用的端口,Kibana、head插件、业务代码都走这个端口。transport.tcp.port是节点间内部通信的端口,集群的发现和数据复制都走9300。生产环境里防火墙一般要同时放行这两个端口,很多人只放9200,结果节点死活加入不了集群,排查到最后才发现是9300被挡了。
还有一个跨域配置,如果你打算用elasticsearch-head这个浏览器插件来管理集群,必须在yml里开启CORS:
http.cors.enabled: true http.cors.allow-origin: "*"不加这两行,head插件会一直报连接失败,因为浏览器的跨域策略直接拦截了请求。这个错误我在后面会专门列出来。
3.3 节点发现与脑裂防护
ES 6.5.4用的是ZenDiscovery机制,节点通过discovery.zen.ping.unicast.hosts指定的地址列表来互相发现。配置方法是把集群里所有节点的IP和transport端口都写进去:
discovery.zen.ping.unicast.hosts: - 192.168.80.101:9300 - 192.168.80.102:9300 - 192.168.80.103:9300这里有个细节要注意:列表里的IP要写全,每个节点都写同样的列表,而不是只写自己。这样任何一个节点启动后,都能通过列表里的其他节点找到整个集群。
防脑裂的配置是discovery.zen.minimum_master_nodes,这也是6.x版本里最重要的一个参数。脑裂指的是集群被分成两个“小集群”,各自以为自己是主,数据写入互相冲突。防止办法就是要求选举主节点时必须凑够法定票数,三节点集群计算公式为3 / 2 + 1 = 2:
discovery.zen.minimum_master_nodes: 2有些人图省事不配这个参数,默认值是1,这在三节点集群里是致命的。一旦网络抖动,两个从节点可能各自都认为自己是主节点,整个集群的写入就乱了。
3.4 JVM堆内存怎么设置最合理
ES的JVM堆内存配置在/usr/local/elasticsearch/config/jvm.options。6.5.4默认是1G,生产环境肯定不够。我的经验是设置成物理内存的一半,但最好不要超过30G。
-Xms8g -Xmx8g为什么是30G这个数字?因为JVM的CompressedOops(压缩指针)技术只对堆内存小于32G的情况有效,超过32G后指针会变宽,同样的数据占用更多内存,GC性能反而下降。所以即使机器有128G内存,ES堆内存也建议控制在31G以内,剩下的内存留给操作系统做文件缓存,这对ES的读取性能帮助很大。
-Xms和-Xmx要设成一样大,避免JVM运行中动态扩容导致GC抖动。还有一个原则是不要随便改GC策略,6.5.4默认的GC在绝大多数场景下已经够用,强行换成别的GC调优,没有压测数据支撑,基本是给自己挖坑。
4. 三节点集群部署实操全流程
4.1 节点一(node-1)完整部署
所有系统参数和用户准备完后,开始配node-1。先编辑elasticsearch.yml,把完整配置写出来:
cluster.name: es-cluster-prod node.name: node-1 node.master: true node.data: true path.data: /data/es-data path.logs: /data/es-logs bootstrap.memory_lock: true network.host: 192.168.80.101 http.port: 9200 transport.tcp.port: 9300 http.cors.enabled: true http.cors.allow-origin: "*" discovery.zen.ping.unicast.hosts: - 192.168.80.101:9300 - 192.168.80.102:9300 - 192.168.80.103:9300 discovery.zen.minimum_master_nodes: 2我建议用systemd来管理ES进程,比bin/elasticsearch -d直接后台跑更规范,开机自启和异常重启都方便。写一个systemd服务文件/etc/systemd/system/elasticsearch.service:
[Unit] Description=Elasticsearch After=network.target [Service] Type=simple User=esuser Group=esgroup LimitNOFILE=65536 LimitNPROC=4096 LimitMEMLOCK=infinity ExecStart=/usr/local/elasticsearch/bin/elasticsearch Restart=always [Install] WantedBy=multi-user.target注意systemd里也要设置LimitNOFILE和LimitMEMLOCK,即使已经在limits.conf里配置过了,systemd服务默认还是会用自己的一套限制,这两个地方必须同时改。
配置完成后,重载并启动服务:
systemctl daemon-reload systemctl enable elasticsearch systemctl start elasticsearch启动后先不要急着操作,观察日志。ES启动比较慢,第一次启动可能要等十几秒,看日志文件:
tail -f /data/es-logs/es-cluster-prod.log看到类似下面的输出说明启动成功:
[INFO ][o.e.n.Node] [node-1] initialized [INFO ][o.e.n.Node] [node-1] started [INFO ][o.e.n.Node] [node-1] adding [node-1] to [es-cluster-prod]...然后验证HTTP接口:
curl -s http://192.168.80.101:9200/?pretty正常会返回集群名、节点名和版本号信息。这时候集群里只有node-1一个节点,状态是yellow,这很正常,因为分片的副本还没地方放。
4.2 节点二、节点三加入集群
node-2和node-3的配置和node-1几乎一样,只有两个地方不同:node.name改成自己的机器名,network.host改成自己的IP。其他配置保持一致,尤其是discovery.zen.ping.unicast.hosts列表里要写三个节点,这一点不能漏。
node-2的/etc/systemd/system/elasticsearch.service和node-1相同,elasticsearch.yml只需要改两行:
node.name: node-2 network.host: 192.168.80.102node-3同理改成node-3和192.168.80.103。我一般会把node-1的整个配置目录用scp复制过去,再改这两个字段,这样不容易打错字:
scp -r /usr/local/elasticsearch/config esuser@192.168.80.102:/usr/local/elasticsearch/复制完记得改属主。然后分别启动node-2和node-3,再回到node-1上看集群状态:
curl -s http://192.168.80.101:9200/_cluster/health?pretty如果看到status: green、number_of_nodes: 3、unassigned_shards: 0,就说明集群已经构建成功。我部署时第一次没看到green,而是卡在yellow,后来发现是之前测试留下的索引副本还没分配完,等几十秒让ES自动重新分配就好了。如果等了几分钟还是黄色,就要用下面第5部分的方法排查了。
4.3 集群健康检查与功能验证
集群状态green只代表分片分配没问题,业务功能还得实际测一下。我习惯在部署完成后创建一个测试索引,写入几条数据再搜一遍:
curl -s -XPUT "http://192.168.80.101:9200/test-index" -H 'Content-Type: application/json' -d '{ "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }'然后写入一条文档:
curl -s -XPUT "http://192.168.80.101:9200/test-index/_doc/1" -H 'Content-Type: application/json' -d '{ "title": "cluster test", "content": "this is a test doc" }'再执行搜索:
curl -s "http://192.168.80.101:9200/test-index/_search?q=title:cluster&pretty"能看到正常返回结果,说明集群的写入、分片、副本和查询链路都通了。如果还需要Kibana,只需在Kibana的kibana.yml里配好一个节点的地址,比如elasticsearch.hosts: ["http://192.168.80.101:9200"],Kibana会自动感知集群里的其他节点。
5. 常见错误与排查技巧实录
5.1 启动失败类错误
这部分是部署ES时遇到最多的问题,几乎每个新手都会在这里卡一轮。我把最常见的几个启动失败错误列出来,都是真实报错信息。
错误一:max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
这个错误在初次部署时出现频率极高。原因是ES进程的文件句柄上限不够。在limits.conf里配了65536之后,重开SSH会话或者重启服务才会生效。如果你用的是systemd,还要检查服务文件里的LimitNOFILE是否也设置了。
# 确认当前进程的limit cat /proc/<es_pid>/limits | grep "open files"错误二:max virtual memory areas vm.max_map_count [65530] likely too low
这个在前面已经提过,直接执行sysctl -w vm.max_map_count=262144临时生效,再写进/etc/sysctl.conf持久化。有时候你明明执行了sysctl命令,但ES还是报同样的错误,可能是你改了宿主机的参数,但ES跑在容器里或者systemd开启了不同的命名空间,需要确认修改作用于ES所在的隔离环境。
错误三:memory locking requested for elasticsearch process but memory is not locked
如果你启用了bootstrap.memory_lock: true,这个错误说明锁定内存失败。检查limits.conf里的memlock是否为unlimited,systemd服务里是否加了LimitMEMLOCK=infinity。如果想要省事,可以把bootstrap.memory_lock设为false,但生产环境建议还是开启,避免ES堆内存被交换到磁盘导致性能骤降。
错误四:can not run elasticsearch as root
ES出于安全考虑禁止root启动,用之前创建的esuser用户来启动就好。检查当前用户:
whoami如果是root,切换到esuser:
su - esuser -c "/usr/local/elasticsearch/bin/elasticsearch"5.2 节点无法加入集群类错误
三台机器都配好启动后,节点之间能不能正常组集群,这是绕不开的一个坎。经典报错是日志里反复出现:
[INFO ][o.e.d.z.ZenDiscovery] [node-2] master not discovered yet, waiting for [30s]看到这个别慌,这不是立刻失败,是节点在等主节点。如果等了很久还是这个日志,就要往这几个方向排查:
先看discovery.zen.ping.unicast.hosts配置是否完整,三台机器的IP和9300端口都要写进去。再看防火墙是否放行了9300端口:
# 在node-1上测试到node-2的9300端口是否连通 telnet 192.168.80.102 9300telnet能通说明网络没问题,不通就去查防火墙。很多云环境的安全组规则也要检查,服务器本地防火墙可能关了,但安全组把你的9300端口挡在外面了。
再看cluster.name是否一致。三个节点集群名必须一模一样,这玩意不匹配,节点互相看不到对方,会一直重复“waiting for master”的循环。我在测试环境里犯过一次这个错误,node-1写的是es-cluster-prod,node-2的配置是从别的环境复制来的,集群名还是es-cluster-test,结果node-2永远进不了集群,日志里也不报明显的错误,排查了半小时才发现是这种低级问题。
如果日志里有类似failed to send join request to master,重点检查transport端口和节点间网络。这类问题排查思路跟“点击一个按钮没反应时先看页面报了什么错”是一样的:不要猜,先看节点日志,日志指向哪个方向就顺藤摸瓜。
5.3 集群运行期错误:分片未分配、磁盘水位、索引只读
集群启动成功不代表万事大吉,运行期的问题才是真正考验排错能力的地方。
分片未分配(unassigned shards)
集群状态yellow或者red,最直接的表现就是_cluster/health里的unassigned_shards不为0。先看哪些分片没分配:
curl -s "http://192.168.80.101:9200/_cat/shards?v" curl -s "http://192.168.80.101:9200/_cluster/allocation/explain?pretty"allocation/explain接口会直接告诉你为什么分片分配不了,是磁盘空间不足、还是副本数大于可用节点数、还是节点没起来。我用这个接口的时候,有一次是因为索引副本数配成了2,但集群只有3个节点,主分片占掉一个节点后,两个副本至少要4个节点才能放下,自然分配不了。把副本数改成1,问题立即解决。
如果节点宕机后重启,分片暂时显示UNASSIGNED是正常的,ES会自动重新分配。但如果等了很久还没恢复,可以尝试触发一次重新分配:
curl -s -XPOST "http://192.168.80.101:9200/_cluster/reroute?retry_failed=true"这个命令只是重新触发分配流程,不会帮你解决根本问题,最终还是要看explain接口指出的原因。
磁盘高水位(high disk watermark [90%] exceeded)
ES默认在磁盘使用率达到85%时停止分配新分片,到90%时会尝试把分片迁移到其他节点,防止磁盘写满。数据量大的业务,索引和分片涨得飞快,磁盘说满就满。日志里会出现:
[WARN ][o.e.c.r.a.DiskThresholdMonitor] [node-2] high disk watermark [90%] exceeded on [node-2], all copies of the shards are allocated to other nodes这时的解决办法不是改配置,而是先清理磁盘。删掉过期索引或者扩磁盘才是正路。临时降低水位线虽然能让ES继续写,但会带来很大的数据风险,比如磁盘真的写满导致节点崩溃,我一般只在应急的时候才用,用完之后立刻恢复默认值:
cluster.routing.allocation.disk.watermark.low: 85% cluster.routing.allocation.disk.watermark.high: 90%索引变成只读
磁盘水位出问题时,ES在某些版本里会自动把索引置为只读来保护数据,表现就是业务方写入报错。清理完磁盘后,记得手动解除索引的只读状态:
curl -s -XPUT "http://192.168.80.101:9200/your-index/_settings" -H 'Content-Type: application/json' -d '{ "index.blocks.read_only_allow_delete": null }'5.4 常见错误速查表
下面这些是我在实际部署和运维里遇到过的错误汇总,整理成速查表,方便大家直接对号入座:
| 错误现象 | 根本原因 | 快速解决办法 |
|---|---|---|
| can not run elasticsearch as root | 用root启动了ES | 创建esuser并切换用户 |
| max file descriptors [4096] too low | 文件句柄限制不够 | limits.conf + systemd LimitNOFILE |
| vm.max_map_count [65530] too low | 内存映射区域太少 | sysctl -w vm.max_map_count=262144 |
| memory locking not available | memlock未放开 | limits.conf + systemd LimitMEMLOCK + bootstrap.memory_lock |
| master not discovered yet | 节点发现失败 | 检查unicast.hosts、防火墙9300、cluster.name |
| failed to send join request | transport通信失败 | 检查9300端口连通性 |
| node.id重复 / node.name冲突 | 多个节点配了同一个名字 | 修改node.name保持唯一 |
| high disk watermark exceeded | 磁盘空间接近上限 | 清理磁盘,扩容数据盘 |
| unassigned_shards不为0 | 分片无法分配 | allocation/explain接口定位原因 |
| head插件连不上ES | 跨域未开启 | http.cors.enabled: true |
| system call filters failed | 容器环境不支持seccomp | 物理机别管;容器里按需调整bootstrap配置 |
| Permission denied | 目录属主不对 | chown -R esuser:esgroup |
| heap size mismatch | Xms和Xmx不一致 | 两个参数设置相同值 |
5.5 排查思路:像调试点击事件一样定位集群问题
很多人遇到ES报错就慌了,到处翻博客、试命令,最后问题没解决,反而把集群状态搞得更差。我自己的排错思路非常固定,和调试前端页面上的一个点击事件几乎一样:先看事件有没有触发,再顺着调用链一层层看哪里断了。
ES的“事件触发信息”就是它的日志和健康接口。打开节点日志,看启动时有没有ERROR,看运行中有没有WARN;打开_cluster/health,看status是green、yellow还是red;打开_cat/nodes,看所有节点是否都正确加入了集群。这一套下来,大部分问题的范围能缩小到“配置问题、网络问题、资源问题”三类。
接着就是顺着链路逐级排查。比如head插件点了连接没反应,第一步看浏览器开发工具的网络请求,请求是否到达了9200端口;如果到达了,看ES返回的是什么状态码;如果ES返回CORS相关的错误,就去检查yml里的跨域配置;如果请求根本没到,去看Kibana或者其他前端代理是否正常工作。每个节点上排查都遵循“日志为主、猜测为辅”的原则,不要凭感觉改配置,每次只改一个参数,改完看日志验证,改错了就回滚。
6. 集群上线后的日常运维建议
6.1 每天/每周该看哪些指标
集群部署完不是终点,日常运维才是长期要做的事。我建议每天固定看一次_cluster/health,确认status是green,同时看节点的CPU、内存、磁盘使用率。每周再花几分钟看看JVM堆内存的使用趋势、分片数量是否异常膨胀、查询的响应延迟有没有明显上升。
# 快速查看集群健康 curl -s "http://192.168.80.101:9200/_cluster/health?pretty" # 查看节点状态 curl -s "http://192.168.80.101:9200/_cat/nodes?v" # 查看索引大小和分片分布 curl -s "http://192.168.80.101:9200/_cat/indices?v"如果发现某个节点堆内存长期维持在85%以上,就要考虑扩容或者清理数据了。ES集群的容量规划要留出余量,磁盘用到70%左右就该准备清理或扩容,等到90%报警再处理,基本就处于很被动的状态了。
6.2 数据备份与安全
创建分片副本只是提供了高可用,不是备份。如果业务数据很重要,一定要配置ES的快照功能,把索引备份到独立的存储上。
# 注册快照仓库 curl -s -XPUT "http://192.168.80.101:9200/_snapshot/my_backup" -H 'Content-Type: application/json' -d '{ "type": "fs", "settings": { "location": "/data/es-backup" } }'注意location目录要提前创建好,并且确保ES进程有权限写入。生产环境里最好把快照仓库挂载到独立的共享存储或者对象存储,别跟数据盘放一起,否则整台机器挂了,数据盘和备份盘都没了,等于没备份。
6.3 关于6.5.4版本和未来升级的实话
6.5.4这个版本在ES的版本历史里不算新,官方也早已停止了维护。如果你的系统是新建的,我建议直接用7.x甚至8.x的版本;如果你是存量系统,短时间内动不了,那至少要做到两点:一是不要轻易跨大版本升级,ES的升级路径有严格限制,5.x到6.x、6.x到7.x的迁移规则都不一样;二是所有插件都要严格匹配版本,比如IK分词器有专门的6.5.4版本,装错版本会导致es启动后插件加载失败。
我个人的体会是,ES集群的坑大多数集中在部署初期,真正跑起来之后反而相对稳定。把环境参数调好、把角色规划清楚、把常见错误准备好排查套路,这套集群就能安安静静地为你服务很长一段时间。