ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Elasticsearch 7.10.2 安装手册:Kibana、分词与调优

Elasticsearch 7.10.2 安装手册:Kibana、分词与调优 做 Elasticsearch 这行7.10.2 这个版本号在我手里装过的次数少说也有几十遍从早期的单机试用到后来给日志平台、检索服务、监控系统做底座它几乎是我最熟的一个版本。原因不复杂它自带 OpenJDK开箱即用核心功能走的是 Apache License 2.0商用不用提心吊胆同时生态里针对 7.10.2 编译的中文分词、SQL 插件、监控组件又足够齐全。这篇安装手册就是把我这些年在这台版本上踩过的坑、验证过的参数、能直接抄的配置一次性摊开面向的读者既有第一次装 Elasticsearch 的新手也有需要把这套东西放到生产环境里跑几年的老运维。全文会覆盖版本选型、环境准备、Windows 与 Linux 两套完整安装流程、Kibana 联调、加固调优和报错排查照着走基本不会卡在中间。1. 版本选型为什么到现在还有人坚持装 7.10.21.1 7.10.2 在版本谱系里的真实位置很多人第一次看到别人指定 7.10.2 会疑惑明明有 8.x 甚至更新的版本为什么非要钉在这个小版本上。这里得先把版本谱系捋清楚。7.x 系列是 Elasticsearch 生命周期里最长、生态最成熟的一代从 7.0 到 7.17 横跨了将近三年7.10.2 处在 7.x 的中后段发布于 2021 年初修掉了 7.10.0 和 7.10.1 上几个比较扎眼的问题属于那个阶段最稳的补丁版本之一。更关键的是时间线。从 7.11 开始Elastic 把核心部分的许可证从 Apache License 2.0 换成了双许可模式虽然对绝大多数自建自用的场景没有实质影响但对一些需要把 Elasticsearch 打包进自己产品、或对许可证合规有硬性要求的团队来说7.10.2 就成了那条分界线之前的最后一站。这也是它至今被反复提起、反复安装的核心原因之一。我不建议盲目追新也不建议无脑守旧。判断标准其实很朴素如果你的检索需求就是全文检索、日志聚合、简单的聚合分析7.10.2 完全够用而且周边资料最多如果你需要向量检索、更强的聚合能力或者更长的官方支持周期那就应该评估更新的版本。安装手册本身不解决选型问题但装之前一定要想清楚这一点否则后面迁移的代价会很大。1.2 免费能力边界7.10.2 到底能白嫖多少东西装之前必须搞明白功能边界不然装完发现某个功能不能用白折腾。7.10.2 的核心引擎部分能力是完整的全文检索、倒排索引、聚合、滚动查询、快照恢复、集群分片路由这些全都有不区分收费。随包附带的 X-Pack 里一部分基础功能也是可用的比如监控数据的采集展示、基础的安全能力需要手动开启并配置但像机器学习、图分析、细粒度的字段级和文档级权限控制这些属于商业功能。这里有个常见的误解要澄清不是启动了 X-Pack 就收费也不是启用安全就收费。基础的安全能力在免费范围内是允许开启的只是它的精细程度不如商业版。对于内部系统我通常的做法是不折腾 X-Pack 的安全模块直接在网络层用反向代理加账号验证把 9200 端口挡起来把精力放在数据本身。还有一个细节要注意默认情况下 X-Pack 的基础功能是开着的你会在启动日志里看到一堆 xpack 相关的提示。如果你确定用不上可以在配置里把它关掉能省下一点内存和启动时间如果打算用监控面板就留着。1.3 什么场景该选它什么场景该绕开按照我的经验下面这几类场景装 7.10.2 是很合适的一是内部日志平台用 Filebeat 采集、Kibana 展示日均写入量在几十 GB 这个量级二是应用内的搜索服务数据量在千万到亿级文档之间三是学习和验证环境因为资料最多、报错最容易搜到答案四是一些对许可证合规有要求的项目需要留在 Apache License 2.0 覆盖的版本范围内。反过来如果你的场景涉及大规模向量相似度检索、需要用到较新的 ES|QL 语法、或者团队没有精力自己运维、希望用云托管服务那就没必要死磕 7.10.2。另外如果你的单集群规模要超过五十个节点、索引数量上万也建议重新评估版本和架构因为 7.x 早期版本在集群状态管理上的开销相对高一些。我的建议很直接用 7.10.2 做存量和稳定业务用新版本做增量和新特性验证两条腿走路而不是一刀切。这个思路在后面很多配置取舍上都会用到。2. 装之前必须做的环境盘点2.1 内存与堆大小一个被严重低估的决策点Elasticsearch 装得好不好一半取决于内存怎么分。它是个纯 Java 应用跑在 JVM 上JVM 堆heap的大小直接决定了它能缓存多少段文件segment的元数据、能扛住多少并发聚合。新手最容易犯的错是把堆设成物理内存的百分之八九十结果操作系统没有内存做文件系统缓存查询性能反而塌方。我的经验规则是堆大小不超过物理内存的 50%且绝对不要超过 31GB。前半个规则的原因是要给操作系统留出文件系统缓存Lucene 的段文件读取严重依赖这一层缓存这部分内存用得越充分查询越快。后半个规则来自 JVM 的压缩普通对象指针Compressed OOPs机制一旦堆超过大约 32GB 这个阈值对象指针会从 4 字节膨胀到 8 字节实际可用内存反而下降。再补一个细节-Xms和-Xmx必须设成同一个值。很多人只设-Xmx让-Xms保持默认的很小值结果 JVM 在运行过程中反复扩容堆每一次扩容都会触发一次 Full GC表现出来就是服务每隔一段时间卡一下。启动时直接把初始堆和最大堆都定死JVM 就不用折腾了。2.2 JDK 该不该自己装7.10.x 随包自带了一份 OpenJDK解压后jdk目录就在根目录下启动脚本会优先使用它。这是我最推荐的方式原因是版本匹配问题被官方替你解决了你不用担心 JDK 小版本带来的兼容性坑。但有两个例外情况需要自己准备 JDK。第一种是你打算把 Elasticsearch 注册成 Windows 系统服务服务启动时用的可能是系统环境变量里的JAVA_HOME这时候系统里得有一个受支持的 JDK第二种是公司有统一的安全基线要求所有 Java 应用使用指定供应商和版本的运行时这时候就在jvm.options里显式指定或者通过环境变量ES_JAVA_HOME覆盖。用ES_JAVA_HOME而不是JAVA_HOME是有讲究的避免影响机器上其他 Java 应用。判断当前用的是哪个 JDK启动时日志第一行就会打印或者直接执行java -version确认。别小看这一步我见过因为系统里装了 JDK 17 导致启动直接报模块访问错误的案例。2.3 Linux 上必须提前调好的内核参数Linux 环境下Elasticsearch 对系统资源的要求比一般 Java 应用高得多因为它要用内存映射文件的方式读索引同时打开大量文件句柄。下面这几个参数如果不调启动就会失败而且报错信息比较隐晦。第一个是虚拟内存映射区域数量。索引文件靠 mmap 加载每个分片会占用若干个映射区域默认的 65530 完全不够用必须提到 262144 以上。临时生效用sysctl -w vm.max_map_count262144永久生效要写进/etc/sysctl.conf或/etc/sysctl.d/下的配置文件然后执行sysctl -p重载。第二个是文件描述符上限。默认 1024 或者 4096 都太低建议提到 65536。这个要分两处配置/etc/security/limits.conf里给运行 Elasticsearch 的用户配上nofile和memlock同时 systemd 的服务单元文件里也要写LimitNOFILE65536因为 systemd 启动的服务不读limits.conf这是很多人配完没生效的原因。第三个是交换分区。操作系统把内存页换到磁盘上对 Elasticsearch 来说是灾难性的因为一次查询可能触发几百次磁盘读。最彻底的做法是关闭 swap退一步至少把vm.swappiness设成 1再配合bootstrap.memory_lock: true把堆内存锁定在物理内存里。锁定内存需要memlock设为 unlimited否则节点启动时会给出警告甚至拒绝启动。2.4 下载源与完整性校验下载我一般只认官方地址压缩包文件名形如elasticsearch-7.10.2-linux-x86_64.tar.gzWindows 版是.zip。下载完成后强烈建议核对一下 SHA512 校验值官方在下载页会给出。这一步在内网环境或者用离线包分发的时候尤其重要我确实遇到过公司内网缓存了半个损坏包、解压后启动莫名报错的情况。校验命令很简单Linux 下用sha512sum elasticsearch-7.10.2-linux-x86_64.tar.gz然后把结果和官网公布的比对。Windows 下可以用 PowerShell 的Get-FileHash -Algorithm SHA512。还有一点如果你是在完全离线的内网部署需要提前把插件包也一起下好。中文分词插件、SQL 插件这些离线安装的时候走的是本地文件路径格式是file:///path/to/plugin.zip而不是网址。这一点在离线场景里能省掉大量来回。3. Windows 环境下的完整安装实操3.1 目录规划与路径踩坑Windows 上装 Elasticsearch 最大的坑不是配置是路径。压缩包解压完先规划一个干净的目录比如D:\app\elasticsearch-7.10.2把数据目录和日志目录单独拆出去放到D:\data\es\data和D:\data\es\logs这样将来升级版本的时候只换程序目录数据不用动。路径里有三件事绝对不能做。第一路径里不要有中文某些 Java 版本对含中文的路径处理会出错第二路径里不要有空格配置文件和脚本里引用路径时会带来转义麻烦第三不要放在系统盘的默认用户目录下一是权限问题二是系统盘的 IO 波动会直接影响写入性能。另外提一句如果你打算用 Windows 版的压缩包解压工具不要用那些智能解压的国产软件它们有时会改文件权限或者打乱目录结构。用系统自带的解压或者 7-Zip 手动解压到目标目录最稳妥。3.2 最小可用配置elasticsearch.yml 怎么写配置文件在config\elasticsearch.yml。默认文件里注释一大堆实际生效的没几行。我一般会清空重写一个精简版本只保留必要项。下面是我常用的 Windows 单机配置cluster.name: es-dev-cluster node.name: node-win-01 path.data: D:\\data\\es\\data path.logs: D:\\data\\es\\logs network.host: 127.0.0.1 http.port: 9200 discovery.type: single-node bootstrap.memory_lock: true逐条说一下理由。cluster.name是集群名将来同一个网段里如果有多个集群靠这个区分默认值elasticsearch很容易撞车建议改。node.name是节点名多节点时如果不显式指定系统会自动生成一堆随机名字排查问题时认不出来。path.data和path.logs用双反斜杠转义或者直接写正斜杠也可以YAML 里正斜杠更省事。network.host这里我写的是127.0.0.1本地开发够用。如果你想让局域网内其他机器访问改成0.0.0.0或者具体网卡 IP。但要特别注意一旦从回环地址改成外部地址Elasticsearch 会自动从开发模式切换到生产模式触发一系列引导检查bootstrap checks配置不到位就会直接启动失败。这些检查包括是否配置了发现种子节点、内存是否锁定、文件描述符是否够用等等报错信息会明确告诉你缺什么。discovery.type: single-node是单节点集群的快捷配置加上它节点启动时会自动把自己选成主节点不需要配置种子列表。这在开发环境非常方便但生产环境不要用它原因后面讲。3.3 jvm.options 调整与堆内存设置堆内存的调整在config\jvm.options里找到这两行-Xms1g -Xmx1g改成你规划好的值比如机器有 16GB 内存就设成 8g如果只有 8GB设成 4g 比较稳。改完保存不用做别的操作启动脚本会自动读取。这里有个 Windows 特有的注意点jvm.options里默认可能有-Dfile.encodingUTF-8这类设置如果启动后控制台窗口输出的中文日志是乱码别急着去改这个参数——先确认是控制台代码页的问题还是文件本身的问题。用记事本打开logs\elasticsearch.log如果文件里中文正常那就是控制台代码页的问题执行chcp 65001切到 UTF-8 再启动就行如果文件里也是乱码才需要考虑编码参数。这个顺序别搞反否则改了参数问题依旧。还有如果你的机器内存比较紧张想把堆调小一点跑起来看看效果也不要低于 1GB低于这个值很可能因为内存不够导致段合并merge频繁被中断表现出来是写入越来越慢。3.4 启动、验证与注册成系统服务启动直接双击bin\elasticsearch.bat。注意这个窗口不能关关掉进程就停了。启动过程中日志会刷很多东西看到类似started和publish_address这样的行说明起来了。验证用浏览器或命令行都行curl -X GET http://127.0.0.1:9200/?pretty返回的 JSON 里会有number: 7.10.2、cluster_name、cluster_uuid等字段。看到这个就说明服务正常对外提供 HTTP 接口了。再检查一下集群健康度curl -X GET http://127.0.0.1:9200/_cat/health?v单节点环境下状态是yellow属于正常因为默认会有副本分片分配不出去。想变绿就把索引的副本数设为 0或者再加一个节点。如果希望它开机自启、后台常驻就注册成系统服务。用管理员权限打开命令行切到bin目录执行elasticsearch-service.bat install elasticsearch-service.bat start卸载服务用elasticsearch-service.bat remove。服务模式有个前提系统里必须有可用的 JDK因为服务进程不走随包的 JDK。我踩过一次坑机器上装了个很新的 JDK服务启动直接失败后来把JAVA_HOME切到 11 才恢复正常。所以注册服务之前java -version一定要先确认。4. Linux 环境下的完整安装实操4.1 独立用户与目录权限Linux 上第一件事是建一个专用用户。Elasticsearch 明确禁止用 root 启动因为一旦有安全漏洞攻击者拿到的就是 root 权限。命令很简单useradd -m -s /bin/bash elasticsearch passwd elasticsearch然后解压到/usr/local下并把目录归属改成这个用户tar -zxvf elasticsearch-7.10.2-linux-x86_64.tar.gz -C /usr/local/ mv /usr/local/elasticsearch-7.10.2 /usr/local/elasticsearch mkdir -p /data/es/{data,logs} chown -R elasticsearch:elasticsearch /usr/local/elasticsearch chown -R elasticsearch:elasticsearch /data/es这里有个容易被忽略的细节/data/es/data这个目录如果有旧版本遗留的文件或者锁文件新节点启动会报failed to obtain node locks。升级或者重装的时候记得先清干净或者干脆换个新的数据目录让节点重新初始化。另外如果你把path.data指向了一个新的空目录第一次启动会有一段比较长的初始化过程会创建集群元数据、生成节点 ID 等不要以为卡死了等日志出现started就行。4.2 配置文件详解与踩坑点Linux 版的配置文件跟 Windows 基本一样路径区别而已。我生产环境上常用的配置模板是这样的cluster.name: es-prod-cluster node.name: node-01 node.roles: [ master, data, ingest ] path.data: /data/es/data path.logs: /data/es/logs network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 discovery.seed_hosts: [10.0.0.11:9300, 10.0.0.12:9300, 10.0.0.13:9300] cluster.initial_master_nodes: [node-01, node-02, node-03] bootstrap.memory_lock: true几点说明。node.roles用来指定节点角色单机测试可以全给生产上建议把 master、data、ingest 拆开部署避免角色互相影响。network.host设为0.0.0.0后进入生产模式前面提到的引导检查全部生效。discovery.seed_hosts是节点发现用的种子地址列表写的是传输层端口 9300不是 9200。cluster.initial_master_nodes只在集群第一次启动时起作用用来选出初始主节点集群成型之后这个配置就要删掉否则节点重启时可能因为重复参与投票造成脑裂。这是我最想强调的一条经验很多人图省事一直留着结果某次断电重启后集群状态异常。bootstrap.memory_lock: true需要配套在/etc/security/limits.conf里加上elasticsearch soft memlock unlimited elasticsearch hard memlock unlimited而且如果用的是 systemd 启动还得在服务单元里加LimitMEMLOCKinfinity否则这个锁定不会生效节点启动时会给出Unable to lock JVM Memory的警告。4.3 堆内存参数与 jvm.options.d 的正确用法Linux 上的堆设置同样在config/jvm.options。但 7.10.x 提供了一个更好的做法在config/jvm.options.d/目录下新建一个自定义文件比如heap.options里面只写堆参数-Xms8g -Xmx8g这样升级版本时覆盖默认的jvm.options不会丢自定义配置也不用每次都去 diff 官方文件改了什么。这是我强烈推荐的习惯尤其是管理多台机器的时候用配置管理工具统一下发这个文件比改主文件安全得多。还有个参数值得关注7.x 默认使用的垃圾回收器是 G1可以通过-XX:UseG1GC显式指定。G1 对大堆的停顿控制比较好通常不需要改。如果你的写入量特别大观察到频繁的 Young GC可以适当调整-XX:MaxGCPauseMillis但我不建议没有测量数据就乱调先看 GC 日志再说。开启 GC 日志的方法是在jvm.options.d里加-XX:PrintGCDetails -XX:PrintGCDateStamps -Xloggc:/data/es/logs/gc.log注意 7.10 已经支持新的统一日志框架如果同时配置了新旧两套可能会冲突。建议就用传统的-Xloggc这一套简单直接。4.4 systemd 服务化与开机自启手工nohup启动不是长久之计正规做法是写 systemd 单元。在/etc/systemd/system/elasticsearch.service里写[Unit] DescriptionElasticsearch 7.10.2 Afternetwork.target [Service] Typesimple Userelasticsearch Groupelasticsearch ExecStart/usr/local/elasticsearch/bin/elasticsearch Restarton-failure RestartSec10 LimitNOFILE65536 LimitMEMLOCKinfinity TimeoutStartSec180 [Install] WantedBymulti-user.target写完执行systemctl daemon-reload systemctl enable elasticsearch systemctl start elasticsearch systemctl status elasticsearchTimeoutStartSec这个参数建议显式加上。默认值是 90 秒大集群冷启动时健康检查可能等更久不加这个参数服务会被 systemd 判定超时然后杀掉日志里能看到Start request repeated too quickly排查起来比较绕。Restarton-failure也是我必加的节点因为内存抖动或者其他临时原因退出时能自动拉起来虽然不能替代监控告警但能减少半夜被叫醒的次数。4.5 Docker 方式的取舍如果你更习惯容器化部署7.10.2 的官方镜像是现成的。基本的启动命令docker run -d --name es7102 \ --ulimit nofile65536:65536 \ --ulimit memlock-1:-1 \ -p 9200:9200 -p 9300:9300 \ -e discovery.typesingle-node \ -e ES_JAVA_OPTS-Xms4g -Xmx4g \ -v /data/es/data:/usr/share/elasticsearch/data \ -v /data/es/logs:/usr/share/elasticsearch/logs \ elasticsearch:7.10.2注意vm.max_map_count必须在宿主机上设置容器里改不了这是容器化部署最常见的启动失败原因。另外生产上如果数据目录挂载到宿主机要确认容器内的 uid 1000 对宿主机目录有写权限否则会报权限拒绝。容器化的好处是部署一致、升级方便坏处是多了一层网络开销堆内存的锁定也不如物理机直接。如果 IO 压力大我会优先选物理机或虚拟机上直接部署如果只是中小规模日志检索容器足够了。5. Kibana 7.10.2 配套安装与联调5.1 Kibana 安装与最小配置Kibana 的版本必须和 Elasticsearch 严格一致7.10.2 配 7.10.2不要配 7.10.1 或者 7.11。下载解压之后配置文件在config/kibana.yml。我常用的精简配置server.port: 5601 server.host: 0.0.0.0 server.name: kibana-01 elasticsearch.hosts: [http://127.0.0.1:9200] i18n.locale: zh-CNelasticsearch.hosts指向 ES 的 HTTP 地址如果 ES 和 Kibana 不在同一台机器改成实际 IP。i18n.locale这一行设成zh-CN重启后界面就变成中文了对不熟悉英文界面的同事非常友好。Kibana 和 Elasticsearch 一样Linux 下不能用 root 启动也要单独建用户或者复用 elasticsearch 用户注意目录权限。启动执行bin/kibana日志里出现Kibana is now available就成功了。访问http://ip:5601就能看到界面。第一次进去会让你选一些示例数据直接跳过即可。有一点要提醒Kibana 启动时会做一次版本和许可证的校验如果 ES 和 Kibana 版本不一致界面上会出现警告横幅虽然部分功能还能用但会出现各种莫名其妙的问题坚持版本对齐别省这一步。5.2 中文分词插件的安装与验证做中文检索默认的标准分词器是把每个汉字拆开效果很差。必须装中文分词插件。7.10.2 对应的版本号也是 7.10.2安装命令cd /usr/local/elasticsearch ./bin/elasticsearch-plugin install \ https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.2/elasticsearch-analysis-ik-7.10.2.zip安装过程中会提示你确认输入y。装完必须重启节点才会加载。离线环境的做法是先把 zip 下到本地然后./bin/elasticsearch-plugin install file:///opt/packages/elasticsearch-analysis-ik-7.10.2.zip验证插件生效用 Kibana 的 Dev Tools 或者 curl 发一个分析请求POST _analyze { analyzer: ik_max_word, text: 中华人民共和国国歌 }返回结果里会把文本切成若干个词看到明显的中文词汇切分而不是单字说明插件工作正常。ik_max_word是最细粒度切分适合建索引ik_smart粒度粗一些适合查询时用。建映射的时候这两个可以配合使用索引用细粒度查询用粗粒度召回和准确率比较平衡。5.3 装机后的验证语句清单装完不算完得有一套验证语句跑一遍才算交付。下面几条我每次都会执行curl -X GET localhost:9200/_cat/nodes?vhname,role,heap.percent,ram.percent,cpu,load_1m curl -X GET localhost:9200/_cat/indices?v curl -X GET localhost:9200/_cat/allocation?v curl -X GET localhost:9200/_cluster/stats?pretty第一条看节点的堆使用率、内存使用率、CPU 负载判断资源是否健康。第二条列出现有索引的状态和文档数。第三条看分片分布是否均衡有没有节点分片过多。第四条是一个汇总视图能看到集群名字、节点数、分片数、存储占用等信息。写完这些再测一次写入和查询curl -X PUT localhost:9200/test_index/_doc/1 -H Content-Type: application/json -d {title:测试文档,ts:2024-01-01} curl -X GET localhost:9200/test_index/_search?q测试写入成功、查询能命中基础链路就通了。测完记得把测试索引删掉curl -X DELETE localhost:9200/test_index。6. 安装后的安全加固与性能调优6.1 免费版下的访问控制方案默认装完的 Elasticsearch 是没有任何认证的谁都能访问 9200 端口这在生产环境里绝对不能接受。7.10.2 上我常用的方案有两种。第一种是网络层隔离加反向代理。把 ES 绑定在127.0.0.1前面放一个反向代理用基础账号验证挡一层。这种方式配置简单不依赖 X-Pack 的安全模块做起来比较干净缺点是账号管理比较粗糙只有一层。适合内部系统配合防火墙白名单使用。第二种是开启 X-Pack 的基础安全能力在配置里打开安全开关然后设置内置账号的密码。这套方案的好处是账号、角色、TLS 都有基础支持代价是配置项比较多证书需要自己生成和管理第一次配容易配错。团队里如果没有专人管这套我通常建议先用第一种。不管用哪种方案有一件事必须做把 9200 和 9300 端口暴露到公网的机器上关掉。9300 是节点间通信端口一旦暴露风险更大。防火墙规则里只放行必要的来源 IP这是最低成本的加固。6.2 生产参数调优清单装完之后有一批参数需要根据实际负载调整下面这张表是我在多个项目里总结出来的默认起点实际值要结合监控数据微调。参数建议值调整理由indices.memory.index_buffer_size10%默认写入压力大时可提到 20%吃的是堆内存index.refresh_interval写多读少时 30s默认 1s每次刷新都会生成新段写放大严重index.translog.durability可接受少量丢失时用 async从每请求落盘改为定时落盘写入吞吐提升明显index.number_of_replicas初始写入阶段设 0写完再调回减少副本同步开销批量导入更快cluster.routing.allocation.disk.watermark.low85%默认磁盘到水位后停止分配新分片thread_pool.write.queue_size1000默认队列过大会掩盖写入瓶颈不建议盲目调大这里我重点说一下refresh_interval。很多人觉得默认 1 秒意味着数据立即可见是好事但在日志或者大批量导入场景下每秒产生一个新段段合并的压力会非常大磁盘 IO 一直处于高位。改成 30 秒甚至 60 秒写入吞吐能明显提升代价是数据可见性延迟。如果是搜索类业务对实时性要求高那就保持默认或者改成 5 秒看业务能接受多少延迟。另一个值得单独提的是分片数量。7.x 默认是 1 个主分片加 1 个副本对单机开发够了但生产上要根据数据量规划。我的经验值是单个分片控制在 10GB 到 50GB 之间太小会导致分片数量爆炸集群元数据膨胀太大会导致单个分片恢复时间长、并行度低。假如你预计三年后数据量是 500GB那规划 10 到 20 个主分片比较合适注意分片数一旦创建就不能改只能重建索引所以规划要在建索引之前完成。6.3 快照仓库与数据保护数值再好的调优也抵不过一次误删。装完必须配快照仓库。在elasticsearch.yml里加上白名单路径path.repo: [/data/es/backup]重启节点后注册仓库curl -X PUT localhost:9200/_snapshot/my_backup -H Content-Type: application/json -d { type: fs, settings: { location: /data/es/backup, compress: true } }然后可以创建快照curl -X PUT localhost:9200/_snapshot/my_backup/snapshot_20240101?wait_for_completiontrue快照是增量的第一次全量后续只备份变化的段文件所以对磁盘和带宽的压力比想象中小。建议用定时任务每天跑一次保留最近 14 天再配合每月一次的全量归档到异地存储。这套机制我用了很多年救过至少两次命——一次是有人误删了索引一次是磁盘故障导致数据目录损坏。还有一点path.repo的目录权限必须给 elasticsearch 用户可读写且不能被多个集群共享否则会因为锁文件冲突导致仓库注册失败。7. 常见报错速查与排查思路7.1 启动阶段的高频报错启动阶段的报错最好排查因为原因通常很明确报错信息里就直接写出来了。下面这张表是我整理的最高频的几个建议装之前先扫一眼。报错关键词根本原因解决方式max virtual memory areas vm.max_map_count [65530] is too lowmmap 区域不足宿主机执行sysctl -w vm.max_map_count262144并写入配置文件持久化max file descriptors [4096] for elasticsearch process is too low文件句柄上限低修改limits.confsystemd 单元里加LimitNOFILE65536the default discovery settings are unsuitable for production use绑定外部地址但没配发现参数至少配置discovery.seed_hosts和cluster.initial_master_nodes之一can not run elasticsearch as root用 root 启动切换到普通用户别想着加参数绕过failed to obtain node locks数据目录被占用或残留锁确认没有旧进程检查path.data下是否有.lock文件Unable to lock JVM Memory内存锁定失败配memlock unlimitedsystemd 加LimitMEMLOCKinfinityjava.lang.IllegalStateException: failed to load plugin插件与版本不匹配确认插件版本号与 ES 完全一致我特别想说一下failed to obtain node locks这个。表面上看是锁的问题但根因往往有两类一类是真的有旧进程没杀干净用ps -ef | grep elastic查一下另一类是你把同一个数据目录挂给了两个节点比如 Docker 里路径映射写重了。我遇到过最隐蔽的一次是 NFS 挂载的数据目录因为网络抖动导致锁文件判断异常节点反复重启。所以数据目录尽量用本地盘别用网络存储。7.2 运行阶段的典型问题运行阶段的问题更难查因为服务看起来是好的但性能不对或者功能异常。下面按我的排查顺序说。第一种是查询越来越慢。先看是不是堆内存吃满了用_cat/nodes看 heap 百分比如果长期在 80% 以上说明堆太小或者有内存泄漏式的查询比如超大聚合。再看段文件数量用_cat/segments看单个索引的段数段数过多说明合并跟不上这时候要检查refresh_interval是不是太短。还有一种情况是分片分布不均某些节点承担了过多查询用_cat/allocation一看就知道。第二种是写入被拒绝。日志里会出现rejected execution或者es_rejected_execution_exception。这是线程池队列满了说明写入速度超过了节点的处理能力。解决方案不是简单调大队列那样只会让延迟更高正确做法是找瓶颈是磁盘跟不上、是 CPU 打满、还是分片数太多导致每个分片分到的资源太少。先把批量写入的 bulk size 调大比如从 500 调到 2000减少请求次数往往立竿见影。第三种是集群状态一直 yellow。单节点环境下这是正常的因为副本分配不出去。如果多节点还是 yellow用_cluster/allocation/explain这个接口把未分配分片的 ID 传进去它会明确告诉你为什么分配不出去——磁盘水位、节点过滤规则、还是分片规则冲突。这个接口是排查分片问题的利器比瞎猜快得多。第四种是 Kibana 界面报Kibana server is not ready yet。九成是 Kibana 连不上 ES检查kibana.yml里的地址、ES 是否在跑、防火墙是否放行。还有一个小概率原因是版本不匹配Kibana 的升级检查没通过这时候看 Kibana 日志里会有明确的版本提示。7.3 我的排错工具箱与顺序排错这件事顺序比工具重要。我一般按这个顺序走先看 Elasticsearch 的日志文件logs/elasticsearch.log里通常已经有答案再看系统资源top、iostat、free -m三件套判断是 CPU、IO 还是内存的瓶颈然后看集群接口_cat系列接口基本能覆盖八成的状态问题最后才去看具体的慢查询日志或者 GC 日志。慢查询日志默认是关的排查查询性能问题时可以临时打开index.search.slowlog.threshold.query.warn: 10s index.search.slowlog.threshold.fetch.warn: 1s打开之后超过阈值的查询会被记录到logs目录下独立的日志文件里能直接定位到是哪个查询拖慢了整体。这个功能用完记得关掉否则日志量增长很快。还有一个小技巧排查集群状态异常时GET _cluster/health?pretty之外一定要配合GET _cluster/pending_tasks看看有没有卡住的任务。我有一次遇到集群状态迟迟不变绿最后在 pending_tasks 里发现是一个索引的映射更新任务卡住了原因是那个任务要等待所有分片确认而其中一个分片的节点正在做段合并等了一会儿自己就好了。这类问题不查 pending_tasks 是看不出来的。我个人在生产上跑 7.10.2 这些年最深的体会是装的过程其实很快真正花时间的是装完之后那几天的观察。头一周一定要盯着堆内存曲线、段文件数量、慢查询日志和磁盘水位这四项把基线摸出来后面出问题时才有对比。配置文件的每一行改动最好都记一笔哪怕是改了一个 refresh_interval也要在变更记录里写清楚时间和原因否则三个月后回头看谁也不知道那行配置是谁加的、为什么加。另外不要一次性把网上看到的调优参数全塞进去一次改一项观察一天稳了再改下一项这个节奏看着慢实际上是最快的路。
返回列表