ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

麒麟V10国产化环境部署ElasticSearch集群实战与调优

麒麟V10国产化环境部署ElasticSearch集群实战与调优

1. 国产化环境下的搜索服务部署挑战

麒麟V10操作系统这两年在信创项目里出现的频率越来越高,尤其是政务、金融、能源这些对自主可控有硬性要求的行业。我最近刚在一个基于麒麟V10的国产化平台上完成了一套ElasticSearch集群的部署,整个过程踩了不少坑,也积累了一些在通用Linux发行版上根本遇不到的经验。这篇文章就把整个部署过程拆开揉碎讲清楚,从系统适配、依赖处理、参数调优到集群验证,每一步都附上我实际操作过的命令和配置。

ElasticSearch本身是一个分布式搜索和分析引擎,底层依赖Java运行环境,通过RESTful接口对外提供服务。它在日志分析、全文检索、数据聚合等场景下表现非常出色。但问题在于,麒麟V10虽然基于Linux内核,它的软件源、系统库版本、安全策略跟常见的CentOS、Ubuntu有相当大的差异。直接照搬网上的部署教程,大概率会在某个环节卡住——可能是JDK版本不兼容,可能是systemd服务脚本报错,也可能是文件句柄限制怎么都调不上去。

这篇文章适合谁看?如果你手头正好有一台麒麟V10的服务器,需要在上面跑ElasticSearch,不管你是运维工程师、后端开发还是刚接触信创环境的技术人员,只要跟着我的步骤走,基本可以一次跑通。我假设你对Linux基本操作有了解,能使用命令行编辑文件、查看日志、管理服务,但不需要你之前部署过ElasticSearch。

注意:麒麟V10有多个版本分支,包括服务器版、桌面版、嵌入式版,不同版本的系统库和预装软件有差异。本文基于麒麟V10服务器版SP2进行实操,其他版本在依赖包版本上可能需要微调。

2. 部署前的系统环境摸底与依赖规划

2.1 麒麟V10的系统特性对ElasticSearch的影响

麒麟V10的底层跟主流Linux发行版有几个关键差异,直接影响到ElasticSearch的部署方式。第一,它默认的软件源里包的数量和版本跟CentOS不一样,很多在CentOS上yum install一条命令搞定的事情,在麒麟上可能需要手动下载rpm包或者从源码编译。第二,麒麟V10默认启用了更严格的安全策略,包括SELinux的定制版本和安全增强模块,这些会限制ElasticSearch绑定端口和访问文件。第三,麒麟V10自带的JDK版本可能跟ElasticSearch要求的版本不匹配,而系统自带的JDK又不太好直接替换,因为可能有其他系统组件依赖它。

我在第一次部署的时候就遇到了JDK的问题。麒麟V10 SP2自带的是OpenJDK 1.8,而ElasticSearch 7.x虽然支持JDK 8,但官方推荐使用JDK 11或JDK 17。更麻烦的是,ElasticSearch 8.x直接要求JDK 17以上,而麒麟V10的软件源里根本没有JDK 17的包。所以我的建议是:先确定你要部署的ElasticSearch版本,然后根据版本要求准备对应的JDK,不要试图用系统自带的JDK凑合。

2.2 版本选型:ElasticSearch与JDK的搭配逻辑

版本选型这件事,我的原则是“跟业务需求走,不盲目追新”。ElasticSearch 7.x和8.x在API层面有不小的变化,8.x默认开启了安全认证,包括TLS加密和用户名密码,这在信创环境里其实是好事,因为等保要求通常也需要这些。但8.x对JDK版本要求更高,部署复杂度也更大。

我整理了一个版本搭配的参考表,基于我在麒麟V10上的实际测试:

ElasticSearch版本推荐JDK版本麒麟V10适配难度适用场景
7.10.xJDK 11中等需要稳定、API兼容性好的场景
7.17.xJDK 11或17中等7.x的最终版本,bug修复最全
8.11.xJDK 17较高需要安全认证、新特性
8.14.xJDK 17或21较高最新特性,但需更多调优

我这次选的是ElasticSearch 7.17.22配JDK 11,原因是7.17是7.x系列的最后一个功能版本,稳定性经过大量验证,而且JDK 11在麒麟V10上可以通过手动安装tar.gz包解决,不需要动系统自带的JDK。如果你没有特殊需求,我建议也走这个组合,踩坑最少。

2.3 系统参数预检清单

在动手安装之前,有几项系统参数必须先检查,不然后面ElasticSearch启动会直接报错。这些检查在麒麟V10上尤其重要,因为它的默认值跟CentOS不一样。

# 查看当前文件句柄限制 ulimit -n # 查看当前进程数限制 ulimit -u # 查看虚拟内存映射数量 sysctl vm.max_map_count # 查看当前内存和swap free -h # 查看磁盘空间 df -h /data # 查看系统版本 cat /etc/kylin-release

麒麟V10默认的vm.max_map_count是65530,而ElasticSearch要求至少262144。ulimit -n默认可能是1024,ElasticSearch建议至少65535。这些参数如果不提前改,启动时就会报“max virtual memory areas vm.max_map_count [65530] is too low”或者“max file descriptors [1024] for elasticsearch process is too low”这类错误。

实操心得:麒麟V10的/etc/security/limits.conf文件里,默认可能已经有了一些限制条目,直接追加可能会冲突。我的做法是先备份原文件,然后在文件末尾追加ElasticSearch用户的限制,并且确保没有其他条目覆盖它。

3. 麒麟V10上的实操部署全流程

3.1 创建专用用户与目录规划

ElasticSearch出于安全考虑,不允许用root用户直接启动。所以第一步是创建一个专用用户,并且规划好目录结构。我习惯把ElasticSearch的数据、日志、安装目录分开,这样后期扩容和备份都方便。

# 创建elasticsearch用户组和用户 groupadd es useradd es -g es -m -s /bin/bash # 设置密码 passwd es # 创建目录结构 mkdir -p /data/es/{app,data,logs,plugins} chown -R es:es /data/es chmod -R 755 /data/es

目录规划的逻辑是这样的:app放ElasticSearch程序本身,data放索引数据,logs放日志,plugins放插件。数据目录单独挂载一块盘是最好的,因为ElasticSearch的索引文件IO很密集,跟系统盘混在一起容易互相影响。如果条件允许,data目录所在的磁盘建议用SSD,至少也要是独立的机械盘。

3.2 JDK 11的手动安装与验证

麒麟V10的软件源里没有JDK 11,所以需要手动下载tar.gz包安装。我选择的是OpenJDK 11的通用Linux版本,下载后解压到/usr/local/目录下。

# 下载OpenJDK 11(这里以某开源镜像站为例,实际地址根据环境调整) # 解压到指定目录 tar -zxvf openjdk-11.0.2_linux-x64_bin.tar.gz -C /usr/local/ mv /usr/local/jdk-11.0.2 /usr/local/java11 # 配置环境变量,只对es用户生效 su - es cat >> ~/.bashrc << 'EOF' export JAVA_HOME=/usr/local/java11 export PATH=$JAVA_HOME/bin:$PATH export ES_JAVA_HOME=/usr/local/java11 EOF source ~/.bashrc # 验证 java -version

这里有个细节:ElasticSearch 7.x会优先读取ES_JAVA_HOME环境变量,如果没有才用JAVA_HOME。我两个都设了,确保万无一失。另外,环境变量只对es用户生效,不要写到/etc/profile里,避免影响系统其他组件。

注意:麒麟V10自带的JDK可能被系统工具依赖,千万不要卸载或替换系统自带的JDK。我们只是给es用户单独指定了一个JDK路径,两者互不干扰。

3.3 ElasticSearch的下载与目录配置

ElasticSearch的安装包直接从官方下载tar.gz格式,不要用rpm包,因为rpm包在麒麟V10上安装时可能会因为依赖关系报错。tar.gz包解压即用,最省心。

# 切换到es用户 su - es cd /data/es/app # 下载ElasticSearch 7.17.22 # 解压 tar -zxvf elasticsearch-7.17.22-linux-x86_64.tar.gz mv elasticsearch-7.17.22 es-node1

解压后,ElasticSearch的目录结构是这样的:bin放启动脚本,config放配置文件,jdk目录里自带了一个JDK(但我们可以用自己的),lib放依赖库,modules放模块,plugins放插件。我习惯把自带的jdk目录删掉或者改名,强制它用我们指定的JDK 11,避免版本混乱。

3.4 核心配置文件逐项拆解

ElasticSearch的配置文件在config目录下,主要改两个文件:elasticsearch.yml和jvm.options。这两个文件的配置直接决定了集群能不能正常启动、性能好不好。

先看elasticsearch.yml的关键配置:

# 集群名称,同一集群内所有节点必须一致 cluster.name: kylin-es-cluster # 节点名称,每个节点唯一 node.name: es-node1 # 数据目录和日志目录 path.data: /data/es/data path.logs: /data/es/logs # 绑定地址,0.0.0.0表示监听所有网卡 network.host: 0.0.0.0 # 对外服务端口 http.port: 9200 # 集群内部通信端口 transport.port: 9300 # 单节点模式发现配置(单机部署时使用) discovery.type: single-node # 初始主节点列表(集群模式时使用) # cluster.initial_master_nodes: ["es-node1", "es-node2", "es-node3"] # 跨域配置,如果需要从浏览器或其他域访问 http.cors.enabled: true http.cors.allow-origin: "*" # 内存锁定,防止内存被交换到swap bootstrap.memory_lock: true

这里重点解释几个参数。network.host设成0.0.0.0是为了让其他机器能访问,如果只在本机用,设成127.0.0.1更安全。discovery.type: single-node是单机部署的关键,不加这个配置,ElasticSearch会尝试找其他节点,找不到就会一直报错。bootstrap.memory_lock: true配合后面的limits.conf配置,可以防止ElasticSearch的内存被swap,这对性能影响很大。

再看jvm.options里的堆内存配置:

# 在jvm.options中找到-Xms和-Xmx,修改为合适值 -Xms4g -Xmx4g

堆内存的设置有个经验公式:不超过物理内存的50%,且不超过32GB。比如你的服务器有16GB内存,那堆内存设8GB比较合适。设太小会导致频繁GC,设太大反而会因为GC停顿时间过长影响性能。我这次部署的服务器是16GB内存,所以设了4GB,留足够的内存给文件系统缓存,因为ElasticSearch的检索性能很大程度上依赖操作系统的文件缓存。

3.5 系统级参数调优与安全策略适配

前面预检时提到的那些系统参数,现在要正式修改。麒麟V10上修改这些参数需要root权限。

# 修改vm.max_map_count echo "vm.max_map_count=262144" >> /etc/sysctl.conf sysctl -p # 修改文件句柄和进程数限制 cat >> /etc/security/limits.conf << 'EOF' es soft nofile 65535 es hard nofile 65535 es soft nproc 4096 es hard nproc 4096 es soft memlock unlimited es hard memlock unlimited EOF # 修改systemd服务的限制(如果通过systemd启动) mkdir -p /etc/systemd/system/elasticsearch.service.d/ cat > /etc/systemd/system/elasticsearch.service.d/override.conf << 'EOF' [Service] LimitMEMLOCK=infinity LimitNOFILE=65535 EOF

麒麟V10的安全策略里,SELinux可能是 enforcing 模式,这会阻止ElasticSearch绑定端口和访问数据目录。我的做法是给ElasticSearch相关的目录和端口打上正确的SELinux标签,而不是直接关闭SELinux。

# 查看SELinux状态 getenforce # 如果返回Enforcing,需要配置策略 # 允许ElasticSearch绑定9200和9300端口 semanage port -a -t http_port_t -p tcp 9200 semanage port -a -t http_port_t -p tcp 9300 # 设置数据目录的SELinux上下文 semanage fcontext -a -t var_lib_t "/data/es/data(/.*)?" restorecon -Rv /data/es/data

如果getenforce返回Disabled,那就不用管这些。但如果是Enforcing,不做这些配置,ElasticSearch启动时会报权限拒绝的错误。

实操心得:麒麟V10的SELinux策略跟标准CentOS有差异,有些在CentOS上能用的setsebool命令在麒麟上可能不存在。如果遇到SELinux相关的报错,先看/var/log/audit/audit.log里的拒绝记录,然后根据记录里的type和tclass来针对性配置,不要盲目关闭SELinux。

4. 启动验证与集群健康检查

4.1 首次启动的完整流程与日志观察

配置改完后,就可以启动ElasticSearch了。启动方式有两种:前台启动和后台启动。第一次启动建议用前台方式,方便看日志输出。

su - es cd /data/es/app/es-node1 # 前台启动 ./bin/elasticsearch

启动过程中,终端会输出大量日志。重点观察几个关键信息:JDK版本是否正确、堆内存是否按配置生效、端口是否绑定成功、有没有报错。如果看到started字样,说明启动成功了。如果卡在某个环节,日志里会有明确的错误提示。

常见的启动报错和原因:

报错信息原因解决方法
max file descriptors too low文件句柄限制没生效检查limits.conf和systemd配置
max virtual memory areas too lowvm.max_map_count没改执行sysctl -p
memory locking requested but not availablememlock限制没生效检查limits.conf里的memlock配置
bind exception: address already in use端口被占用用netstat查端口占用
permission deniedSELinux或文件权限问题检查SELinux日志和目录权限

启动成功后,用curl验证服务是否正常:

curl -X GET "http://localhost:9200/?pretty"

正常返回应该包含集群名称、节点名称、版本号等信息。如果返回连接拒绝,说明服务没起来或者端口没绑定对。

4.2 集群健康状态与索引操作验证

单节点启动后,集群健康状态是yellow,这是正常的,因为单节点没有副本分片。用以下命令查看:

curl -X GET "http://localhost:9200/_cluster/health?pretty"

返回的status字段如果是yellow,说明主分片都正常,只是副本分片没地方分配。单节点部署不用管这个。如果是red,说明有主分片不可用,需要排查。

接下来做一个完整的索引操作验证,确保读写都正常:

# 创建索引 curl -X PUT "http://localhost:9200/test-index?pretty" -H 'Content-Type: application/json' -d' { "settings": { "number_of_shards": 1, "number_of_replicas": 0 } } ' # 写入文档 curl -X POST "http://localhost:9200/test-index/_doc/1?pretty" -H 'Content-Type: application/json' -d' { "title": "麒麟V10部署测试", "content": "这是一条测试数据", "timestamp": "2024-01-15T10:00:00" } ' # 查询文档 curl -X GET "http://localhost:9200/test-index/_doc/1?pretty" # 搜索 curl -X GET "http://localhost:9200/test-index/_search?q=麒麟&pretty"

这一套操作下来,如果都能正常返回结果,说明ElasticSearch在麒麟V10上的部署基本完成了。

4.3 配置systemd服务实现开机自启

前台启动只适合测试,生产环境需要用systemd管理,实现开机自启和进程守护。麒麟V10的systemd版本跟CentOS 7差不多,服务脚本的写法基本通用。

cat > /etc/systemd/system/elasticsearch.service << 'EOF' [Unit] Description=Elasticsearch Documentation=https://elastic.co Wants=network-online.target After=network-online.target [Service] Type=simple User=es Group=es Environment=ES_JAVA_HOME=/usr/local/java11 Environment=ES_PATH_CONF=/data/es/app/es-node1/config ExecStart=/data/es/app/es-node1/bin/elasticsearch Restart=on-failure RestartSec=10 LimitMEMLOCK=infinity LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF # 重载systemd配置 systemctl daemon-reload # 启动服务 systemctl start elasticsearch # 设置开机自启 systemctl enable elasticsearch # 查看状态 systemctl status elasticsearch

这里有个关键点:Environment里必须指定ES_JAVA_HOME,否则systemd启动时可能找不到JDK。另外LimitMEMLOCK和LimitNOFILE也要在service文件里再设一遍,因为systemd服务不读limits.conf。

注意:麒麟V10的systemd对service文件的语法检查比较严格,如果ExecStart路径里有空格或者特殊字符,需要用引号包裹。另外,如果启动失败,用journalctl -u elasticsearch -f查看详细日志。

5. 踩坑记录与常见问题速查

5.1 麒麟V10特有的兼容性问题汇总

在麒麟V10上部署ElasticSearch,我遇到的坑主要集中在几个方面。第一个是JDK版本问题,前面已经讲过了。第二个是文件系统的问题,麒麟V10默认可能使用ext4或xfs文件系统,如果是xfs,需要确保挂载参数里没有nobarrier之类的选项,否则可能影响数据持久性。第三个是网络配置,麒麟V10的网络管理工具可能跟CentOS不一样,network.host设成0.0.0.0后如果还是无法远程访问,要检查防火墙规则。

# 查看防火墙状态 systemctl status firewalld # 开放端口 firewall-cmd --permanent --add-port=9200/tcp firewall-cmd --permanent --add-port=9300/tcp firewall-cmd --reload

麒麟V10的防火墙默认可能是开启的,而且规则跟CentOS有差异。如果firewall-cmd命令不存在,可能是用了iptables或者麒麟自己的安全组件,需要根据实际情况调整。

5.2 性能调优的进阶参数

基础部署完成后,如果对性能有更高要求,可以调整一些进阶参数。比如thread_pool的配置、indices.memory.index_buffer_size的大小、translog的刷盘策略等。这些参数没有固定值,需要根据实际负载来调。

# 在elasticsearch.yml中追加 # 索引缓冲区大小,默认是堆内存的10% indices.memory.index_buffer_size: 20% # 写入线程池配置 thread_pool.write.queue_size: 1000 # 搜索线程池配置 thread_pool.search.queue_size: 2000

调整这些参数的原则是:先压测,看瓶颈在哪里,再针对性调整。不要一上来就把所有参数拉满,那样反而可能因为资源竞争导致性能下降。

5.3 常见问题速查表

问题现象可能原因排查命令解决方案
启动后立即退出JDK版本不兼容./bin/elasticsearch -V更换JDK版本
9200端口无法访问防火墙或绑定地址netstat -tlnp | grep 9200检查network.host和防火墙
集群状态red磁盘空间不足或分片损坏curl localhost:9200/_cluster/health清理磁盘或恢复分片
写入速度慢堆内存不足或磁盘IO瓶颈iostat -x 1调整堆内存或更换SSD
频繁GC堆内存设置不合理jstat -gcutil <pid> 1000调整Xms和Xmx
节点无法加入集群集群名称或端口不一致检查elasticsearch.yml统一集群配置

5.4 数据备份与恢复的实操建议

ElasticSearch的数据备份不能直接拷贝data目录,因为集群运行时文件是打开状态,直接拷贝可能得到不一致的数据。正确的做法是用snapshot API。

# 注册备份仓库(需要先在elasticsearch.yml中配置path.repo) curl -X PUT "http://localhost:9200/_snapshot/backup_repo" -H 'Content-Type: application/json' -d' { "type": "fs", "settings": { "location": "/data/es/backup", "compress": true } } ' # 创建快照 curl -X PUT "http://localhost:9200/_snapshot/backup_repo/snapshot_20240115?wait_for_completion=true" # 恢复快照 curl -X POST "http://localhost:9200/_snapshot/backup_repo/snapshot_20240115/_restore"

在麒麟V10上,path.repo指定的目录需要提前创建并赋予es用户读写权限,否则注册仓库时会报错。另外,备份目录最好跟数据目录在不同的磁盘上,避免磁盘故障导致数据和备份同时丢失。

6. 个人实操体会与后续扩展思路

这套部署方案我在麒麟V10上跑了三个多月,中间经历过一次服务器重启和一次磁盘扩容,整体稳定性没问题。有几个体会比较深:第一,麒麟V10的软件生态确实跟主流发行版有差距,但ElasticSearch这种用tar.gz包部署的软件受影响很小,关键是把JDK和系统参数搞定。第二,不要迷信网上的“一键脚本”,在信创环境里,每个环节都可能因为系统差异出问题,手动一步步来反而更快。第三,日志是最好的老师,启动失败时不要慌,仔细看日志里的错误信息,90%的问题都能定位到。

后续如果要做集群部署,思路跟单机差不多,主要是在elasticsearch.yml里配置discovery.seed_hosts和cluster.initial_master_nodes,然后确保各节点的cluster.name一致、JDK版本一致、系统参数一致。另外,集群模式下建议至少三个master节点,避免脑裂问题。

还有一个扩展方向是跟Kibana配合使用。Kibana的部署跟ElasticSearch类似,也是tar.gz包解压即用,主要配置kibana.yml里的elasticsearch.hosts指向ElasticSearch的地址。不过Kibana对Node.js版本有要求,麒麟V10上可能需要单独装Node.js,这个后面有机会再单独写一篇。

最后分享一个小技巧:在麒麟V10上部署任何Java应用,都建议先用java -version确认JDK版本,再用update-alternatives --config java看看系统默认的Java是哪个。很多时候问题就出在系统默认Java跟你以为的不一样。把ES_JAVA_HOME显式指定好,能省掉很多莫名其妙的报错。

返回列表