- 文档
- 教程
- 数据库
【免费下载链接】db-tutorial
📚 后端程序员应该掌握的主流数据库知识
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,作为 Elastic Stack 的核心组件,它集中存储数据,帮助发现意料之中以及意料之外的情况。本文基于 db-tutorial 仓库中的运维文档,系统梳理 Elasticsearch 从安装启动、集群容量规划、核心配置文件
elasticsearch.yml逐项参数说明,到 Linux 环境下四大高频启动报错的完整排查方案,并结合仓库内的 Docker Compose 集群编排与 Java 客户端源码,给出可落地、可复现的运维实践。
Elasticsearch 安装
Elasticsearch 的安装非常简单,本质上就是"下载解压 + 启动脚本 + 验证端口"三步。
下载解压
访问 Elasticsearch 官方下载地址,选择需要的版本,下载解压到本地。不同平台对应不同的压缩包格式(tar.gz / zip),解压后得到如下目录结构:
elasticsearch-<version>/ ├── bin/ # 启动与管理脚本 ├── config/ # 配置文件(elasticsearch.yml、jvm.options、log4j2.properties 等) ├── data/ # 索引数据默认存储目录 ├── logs/ # 日志默认输出目录 ├── lib/ # 依赖的 Java 类库 └── plugins/ # 插件安装目录运行
运行启动脚本(Windows 上为.bat文件):
# Linux / macOS bin/elasticsearch # Windows bin\elasticsearch.bat注意:Elasticsearch 默认在前台运行,便于观察启动日志;如需后台运行可追加
-d参数(bin/elasticsearch -d)。启动时要求本机已安装对应版本的 JDK(Elasticsearch 7.x 内置了捆绑的 JDK,也可通过JAVA_HOME指定)。
访问验证
服务启动后,执行以下命令测试服务是否可用:
curl http://localhost:9200/正常时返回类似下面的 JSON 响应,其中version字段包含版本号与构建信息:
{ "name": "node-1", "cluster_name": "elasticsearch", "cluster_uuid": "...", "version": { "number": "7.16.3", "build_flavor": "default", ... }, "tagline": "You Know, for Search" }从仓库代码也可以印证这个验证流程:在 RestLowLevelClientTest.java 中,客户端通过new HttpHost("localhost", 9200)连接本机 9200 端口;而在 application.properties 中,Spring Boot 应用的默认连接地址同样是spring.elasticsearch.uris = http://localhost:9200。
Elasticsearch 集群规划
Elasticsearch 集群需要根据业务实际情况合理规划,不能照搬固定模板。规划前至少需要明确以下四个问题:
- 集群部署几个节点?
- 有多少个索引?
- 每个索引有多大数据量?
- 每个索引有多少个分片?
一个可参考的规划案例
原文档给出了一组贴近生产场景的参考数据:
- 硬件:3 台机器,每台 6 核 64G。
- 数据增长:ES 集群日增量数据约 2000 万条、约 500MB;每月增量约 6 亿条、15G;系统运行数月后集群数据总量约 100G。
- 索引与分片:线上有 5 个索引(按各自业务决定哪些数据入 ES),每个索引数据量约 20G。在这个量级下,每个索引分配8 个 shard,比默认的 5 个 shard 多 3 个。
规划背后的逻辑是:主分片数量决定索引最大可存储的数据量(主分片数在索引创建时即已确定,之后不可修改),而副本分片数量决定读吞吐与数据冗余度。关于分片与集群健康状态(green/yellow/red)的细节,可进一步阅读仓库中的 13.Elasticsearch集群和分片.md。
用 Docker Compose 编排三节点集群
仓库在 docker-compose.yaml 中提供了一个 Elasticsearch 7.1.0 三节点集群编排示例,非常适合在开发环境快速验证集群规划。其核心设计如下:
- 三个 ES 节点通过
cluster.name=geektime-hwc加入同一集群,分别以node.name区分(es7_hot、es7_warm、es7_cold),并通过node.attr.box_type标记热、温、冷分层属性; - 通过
discovery.seed_hosts=es7_hot,es7_warm,es7_cold声明种子节点,通过cluster.initial_master_nodes指定首批可竞选 master 的节点; - 通过
bootstrap.memory_lock=true加ulimits.memlock(soft/hard 均为 -1)锁定内存,避免 JVM 发生 swap; - 通过
ES_JAVA_OPTS=-Xms512m -Xmx512m将堆内存固定为 512m(生产环境建议按机器内存的 50% 左右配置,且 Xms 与 Xmx 保持一致); - 每个节点挂载独立的命名卷(
hwc_es7data_hot/warm/cold)持久化数据,并共享同一个 bridge 网络hwc_es7net; - 同文件还编排了 Kibana 7.1.0(5601 端口)与 cerebro(9000 端口,用于集群监控与分片管理)。
这组编排与下方elasticsearch.yml配置章节中的cluster.name、node.name、discovery.zen.ping.unicast.hosts(7.x 中演变为discovery.seed_hosts)等参数一一对应,可对照学习。
Elasticsearch 配置
ES 的默认配置文件为config/elasticsearch.yml。以下是原文档给出的基本配置项逐条说明,覆盖集群、节点角色、存储路径、网络、网关恢复、分片分配与节点发现等运维核心参数。
集群与节点角色
cluster.name: elasticsearch # 配置 es 的集群名称,默认是 elasticsearch。es 会自动发现在同一网段下的 es, # 如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。 node.name: 'Franz Kafka' # 节点名,默认随机指定一个 name 列表中的名字,该列表在 es 的 jar 包中 config 文件夹里的 # name.txt 文件中,其中有很多作者添加的有趣名字。 node.master: true # 指定该节点是否有资格被选举成为 node(主节点),默认是 true。 # es 默认集群中的第一台机器为 master,如果这台机器挂了就会重新选举 master。 node.data: true # 指定该节点是否存储索引数据,默认为 true。说明:node.master与node.data组合可以构造出"专用 master 节点"(master=true, data=false)与"专用数据节点"(master=false, data=true)等角色划分,是大规模集群规划中的常见做法。
索引默认设置
index.number_of_shards: 5 # 设置默认索引分片个数,默认为 5 片。 index.number_of_replicas: 1 # 设置默认索引副本个数,默认为 1 个副本。这两个参数也可以在创建索引时通过 settings 单独指定。仓库的 ElasticsearchTemplate.java 中createIndex方法就是运行时用Settings.builder().put("index.number_of_shards", shard).put("index.number_of_replicas", replica)动态传入分片与副本数的实现,测试基类 BaseElasticsearchTemplateTest.java 通过getShard()、getReplica()两个抽象方法让不同业务定义各自的取值。
路径配置
path.conf: /path/to/conf # 设置配置文件的存储路径,默认是 es 根目录下的 config 文件夹。 path.data: /path/to/data # 设置索引数据的存储路径,默认是 es 根目录下的 data 文件夹。 # 可以设置多个存储路径,用逗号隔开,例如: # path.data: /path/to/data1,/path/to/data2 path.work: /path/to/work # 设置临时文件的存储路径,默认是 es 根目录下的 work 文件夹。 path.logs: /path/to/logs # 设置日志文件的存储路径,默认是 es 根目录下的 logs 文件夹。 path.plugins: /path/to/plugins # 设置插件的存放路径,默认是 es 根目录下的 plugins 文件夹。版本提示:
path.conf、path.work属于早期版本(ES 2.x/5.x)的参数,自 ES 6.x 起不再支持自定义,配置目录固定为安装目录下的config,临时文件目录也已调整。path.data与path.logs在 6.x/7.x 中依然有效且必须提前创建。
内存与交换(Swap)
bootstrap.mlockall: true # 设置为 true 来锁住内存。因为当 jvm 开始 swapping 时 es 的效率会降低,所以要保证它不 swap, # 可以把 ES_MIN_MEM 和 ES_MAX_MEM 两个环境变量设置成同一个值,并且保证机器有足够的内存分配给 es。 # 同时也要允许 elasticsearch 的进程可以锁住内存,linux 下可以通过 `ulimit -l unlimited` 命令。版本提示:在 ES 6.x/7.x 中该参数更名为
bootstrap.memory_lock。仓库的 docker-compose.yaml 正是使用bootstrap.memory_lock=true配合ulimits.memlock(-1 表示不限制)来锁定内存,这与ulimit -l unlimited的语义一致:内存锁定后 JVM 堆不会因换页(swap)而性能劣化。
网络与端口
network.bind_host: 192.168.0.1 # 设置绑定的 ip 地址,可以是 ipv4 或 ipv6,默认为 0.0.0.0。 network.publish_host: 192.168.0.1 # 设置其它节点和该节点交互的 ip 地址,如果不设置它会自动判断,值必须是个真实的 ip 地址。 network.host: 192.168.0.1 # 这个参数用来同时设置 bind_host 和 publish_host 上面两个参数。 transport.tcp.port: 9300 # 设置节点间交互的 tcp 端口,默认是 9300。 transport.tcp.compress: true # 设置是否压缩 tcp 传输时的数据,默认为 false,不压缩。 http.port: 9200 # 设置对外服务的 http 端口,默认为 9200。 http.max_content_length: 100mb # 设置内容的最大容量,默认 100mb。 http.enabled: false # 是否使用 http 协议对外提供服务,默认为 true,开启。版本提示:
transport.tcp.port、transport.tcp.compress在 ES 7.x 中更名为transport.port、transport.compress,但 9300 默认端口保持不变;http.max_content_length自 6.x 起更名为http.max_content_length(早期为http.max_content_length,5.x 前为http.max_content_length,实际以各版本官方文档为准)。
网关(Gateway)与数据恢复
gateway.type: local # gateway 的类型,默认为 local 即为本地文件系统,可以设置为本地文件系统、分布式文件系统、 # hadoop 的 HDFS、amazon 的 s3 服务器等。 gateway.recover_after_nodes: 1 # 设置集群中 N 个节点启动时进行数据恢复,默认为 1。 gateway.recover_after_time: 5m # 设置初始化数据恢复进程的超时时间,默认是 5 分钟。 gateway.expected_nodes: 2 # 设置这个集群中节点的数量,默认为 2,一旦这 N 个节点启动,就会立即进行数据恢复。版本提示:
gateway.*系列参数是 ES 2.x 时代的配置,从 ES 5.x 起集群恢复逻辑已由gateway.recover_after_*演变为分片级恢复,默认行为由indices.recovery.*控制。升级到新版本后此类旧参数会被忽略。
分片分配与恢复并发
cluster.routing.allocation.node_initial_primaries_recoveries: 4 # 初始化数据恢复时,并发恢复线程的个数,默认为 4。 cluster.routing.allocation.node_concurrent_recoveries: 2 # 添加删除节点或负载均衡时并发恢复线程的个数,默认为 4。 indices.recovery.max_size_per_sec: 0 # 设置数据恢复时限制的带宽,如 100mb,默认为 0,即无限制。 indices.recovery.concurrent_streams: 5 # 设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为 5。这些参数用于控制节点扩容、故障恢复、负载均衡时数据搬迁的并发度与带宽,防止恢复过程挤占搜索资源。
节点发现(Discovery)
discovery.zen.minimum_master_nodes: 1 # 设置这个参数来保证集群中的节点可以知道其它 N 个有 master 资格的节点。 # 默认为 1,对于大的集群来说,可以设置大一点的值(2-4)。 discovery.zen.ping.timeout: 3s # 设置集群中自动发现其它节点时 ping 连接超时时间,默认为 3 秒, # 对于比较差的网络环境可以调高一点的值来防止自动发现时出错。 discovery.zen.ping.multicast.enabled: false # 设置是否打开多播发现节点,默认是 true。 discovery.zen.ping.unicast.hosts: ['host1', 'host2:port', 'host3[portX-portY]'] # 设置集群中 master 节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。版本提示:
discovery.zen.*是 ES 2.x/6.x 的配置体系。ES 7.x 中改由discovery.seed_hosts(种子节点列表,对应discovery.zen.ping.unicast.hosts)、cluster.initial_master_nodes(初始 master 候选)、discovery.zen.minimum_master_nodes的替代品discovery.zen.minimum_master_nodes(7.x 早期版本仍保留)等参数承担同样的职责。仓库的 docker-compose.yaml 即为 7.x 写法,可直接对照。
配置与客户端对接
配置完成并启动 ES 后,业务侧需要与集群建立连接。仓库中给出了两种典型方式:
- Spring Boot 自动装配:在 application.properties 中声明
spring.elasticsearch.uris = http://localhost:9200,Spring Data Elasticsearch 会自动创建RestHighLevelClient。 - 手动工厂创建:elasticsearch6 模块的 ElasticsearchConfig.java 读取
es.hosts配置(支持逗号分隔多地址),由 ElasticsearchFactory.java 构建RestHighLevelClient与ElasticsearchTemplate,其中getDefaultEsAddress按prd(三节点地址)与pre/test(单节点)环境区分了默认连接地址;随后通过 EnableElasticsearch.java 注解一键导入配置。生产环境多节点地址形如127.0.0.1:9200,127.0.0.2:9200,127.0.0.3:9200,与elasticsearch.yml中的节点列表保持一致。
Elasticsearch FAQ
elasticsearch 不允许以 root 权限来运行
问题:在 Linux 环境中,elasticsearch 不允许以 root 权限来运行。如果以 root 身份运行 elasticsearch,会提示这样的错误:
can not run elasticsearch as root解决方法:使用非 root 权限账号运行 elasticsearch:
# 创建用户组 groupadd elk # 创建新用户,-g elk 设置其用户组为 elk,-p elk 设置其密码为 elk useradd elk -g elk -p elk # 更改 /opt 文件夹及内部文件的所属用户及组为 elk:elk chown -R elk:elk /opt # 假设你的 elasticsearch 安装在 /opt 目录下 # 切换账号 su elk之后用elk用户执行bin/elasticsearch即可正常启动。生产环境中建议同时为 elk 用户配置好数据、日志目录的写权限。
vm.max_map_count 不低于 262144
问题:vm.max_map_count表示虚拟内存区域(memory map)数量上限,它是一个内核参数。elasticsearch 默认要求vm.max_map_count不低于 262144。不满足时会报错:
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]解决方法:
可以执行以下命令临时设置vm.max_map_count,但重启后又会恢复为原值:
sysctl -w vm.max_map_count=262144持久化的做法是在/etc/sysctl.conf文件中修改vm.max_map_count参数:
echo "vm.max_map_count=262144" > /etc/sysctl.conf sysctl -p注意
如果运行环境为 docker 容器,可能会限制执行 sysctl 来修改内核参数。这种情况下,只能选择直接修改宿主机上的参数。
nofile 不低于 65536
问题:nofile表示进程允许打开的最大文件数。elasticsearch 进程要求可以打开的最大文件数不低于 65536。不满足时会报错:
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]解决方法:在/etc/security/limits.conf文件中修改nofile参数:
echo "* soft nofile 65536" > /etc/security/limits.conf echo "* hard nofile 131072" > /etc/security/limits.conf修改后需要重新登录会话(或重启进程)才能生效,可使用ulimit -n验证当前值。将 soft 与 hard 分别设为 65536 与 131072 的用意是:soft 限制可在会话内自行提升至 hard 上限,为进程留出余量。
nproc 不低于 2048
问题:nproc表示最大线程数。elasticsearch 要求最大线程数不低于 2048。不满足时会报错:
max number of threads [1024] for user [user] is too low, increase to at least [2048]解决方法:在/etc/security/limits.conf文件中修改nproc参数:
echo "* soft nproc 2048" > /etc/security/limits.conf echo "* hard nproc 4096" > /etc/security/limits.conf补充:常见启动参数核对清单
综合上述 FAQ,Linux 下首次启动 ES 前建议按顺序核对以下四项:
| 内核/系统参数 | 最低要求 | 持久化修改位置 |
|---|---|---|
vm.max_map_count | 262144 | /etc/sysctl.conf |
nofile(最大打开文件数) | 65536 | /etc/security/limits.conf |
nproc(最大线程数) | 2048 | /etc/security/limits.conf |
| 运行账号 | 非 root | 独立系统用户(如 elk) |
另外,在 ES 6.x/7.x 中开启bootstrap.memory_lock=true时,还需保证ulimit -l(最大锁定内存)为 unlimited,对应仓库 docker-compose.yaml 中ulimits.memlock设为 -1 的写法。
参考资料
- Elasticsearch 官方下载安装说明
- Elasticsearch 官方文档之 Install Elasticsearch with RPM
- 13.Elasticsearch集群和分片.md:集群健康、分片与扩容原理
- docker-compose.yaml:仓库内 ES 7.1.0 三节点 + Kibana + cerebro 编排示例
- ElasticsearchFactory.java:多环境 ES 客户端工厂
- ElasticsearchConfig.java:Spring 配置类与
es.hosts参数 - application.properties:Spring Boot 连接配置
- 文档
- 教程
- 数据库
【免费下载链接】db-tutorial
📚 后端程序员应该掌握的主流数据库知识
相关推荐
Apache RocketMQ 运维实战:四种集群部署模式、mqadmin 命令速查与常见问题排查
Apache RocketMQ 运维实战:四种集群部署模式、mqadmin 命令速查与常见问题排查 本篇技术指南以 Apache RocketMQ 的运维管理为
消息队列流处理后端抖音批量下载无水印怎么做?免费开源工具 douyin-downloader 完整实战指南
抖音批量下载无水印怎么做?免费开源工具 douyin downloader 完整实战指南 douyin downloader 是一款免费开源的抖音批量下载工具:
网页爬虫CLIDendrite 常见问题(FAQ)完全指南:部署、联邦、配置与运维排障实战
Dendrite 常见问题(FAQ)完全指南:部署、联邦、配置与运维排障实战 本文以 Dendrite 官方 FAQ 文档 https://link.gitco
后端即时通讯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考