当前位置: 首页 > news >正文

Elasticsearch 集群升级实战指引—7.x 升级到 8.x

升级Elasticsearch集群从7.x到8.x是一项复杂且关键的任务,涉及重大版本变更(如API调整、配置变更、安全功能强制启用等),可能影响集群的性能和稳定性。结合您提到的业务量增长导致索引写入变慢的问题,本指引不仅提供详细的升级步骤,还深入分析写入性能瓶颈的可能原因,并提出针对性优化方案,确保升级后集群性能提升、业务无中断。以下内容适用于中小型到大型集群,涵盖硬件、软件、配置和监控的方方面面。


一、前期准备

升级前的准备工作是成功的关键,直接决定升级过程的平滑性和数据安全性。以下是详细的准备步骤,涵盖版本确认、兼容性检查、备份、测试和性能基线评估。

1.1 确认当前版本与目标版本

  • 检查当前版本:

    • 使用API确认集群当前版本:GET /,返回的version.number应为7.x.x。

    • 建议升级到最新补丁版本(如7.17.28,截至2025年6月为7.x系列最新版),因为7.17.x支持直接滚动升级到8.x,且包含关键修复和性能优化。

    • 检查所有节点的版本一致性:GET _cat/nodes?v&h=name,version。

  • 目标版本:

    • 选择最新8.x版本(如8.18.x,截至2025年6月为最新稳定版本),以获取新功能(如增强的向量搜索、TSDB支持)和安全补丁。
    • 阅读Elastic官方8.x发布说明(https://www.elastic.co/guide/en/elasticsearch/reference/8.x/release-notes.html),关注重大变更(如_type移除、安全功能强制启用)。
  • 升级路径:

    • 7.17.x可直接滚动升级到8.x。
    • 如果集群包含6.x索引,需先在7.x环境中重新索引(reindex)到7.x格式。

1.2 检查兼容性

  • 插件兼容性:

    • 列出所有插件:GET _cat/plugins?v&s=component,检查每个插件是否有8.x版本。

    • 常见官方插件(如analysis-icu、ingest-attachment)通常有8.x版本,但第三方或自定义插件可能不兼容。

    • 若插件无8.x版本,需:

      • 联系插件开发者确认更新计划。

      • 寻找替代插件或移除插件(需评估对业务的影响)。

      • 示例:卸载不兼容插件:

        bin/elasticsearch-plugin remove <plugin_name>
        
  • 客户端兼容性:

    • 检查应用程序使用的客户端库(如Java High Level REST Client、Python elasticsearch-py)是否支持8.x。

    • 8.x提供7.x REST API兼容模式,但部分API(如_type相关)已移除,需修改代码。例如:

      // 7.x代码
      SearchRequest request = new SearchRequest("index_name").types("doc");
      // 8.x代码(移除types)
      SearchRequest request = new SearchRequest("index_name");
      
    • 推荐迁移到8.x的Elasticsearch Java API或OpenSearch REST Client。

  • Elastic Stack组件:

    • 确保Kibana、Logstash、Beats版本与8.x匹配(例如,Kibana 8.18.x与Elasticsearch 8.18.x兼容)。

    • 检查Filebeat、Metricbeat的配置文件,更新输出目标为8.x集群:

      output.elasticsearch:hosts: ["https://new-cluster:9200"]ssl.certificate_authorities: ["/path/to/ca.crt"]
      
  • 索引兼容性:

    • 8.x不支持6.x及更早版本的索引,需在7.x环境中重新索引:

      POST _reindex
      {"source": {"index": "old_index_6x"},"dest": {"index": "new_index_7x"}
      }
      
    • 检查mapping是否使用已移除的功能(如_type字段、多类型索引)。示例:

      GET /index_name/_mapping
      

      如果mapping包含_type,需重构索引结构。

1.3 使用升级助手

  • 启用升级助手:

    • 在Kibana的Stack Management中打开Upgrade Assistant,扫描集群和索引的兼容性问题。

    • 解决报告的问题,例如:

      • 弃用API:检查是否使用了8.x移除的API,如transient集群设置:

        # 7.x transient设置(已弃用)
        PUT _cluster/settings
        {"transient": {"indices.query.bool.max_clause_count": 2048}
        }
        # 8.x使用persistent
        PUT _cluster/settings
        {"persistent": {"search.max_buckets": 10000}
        }
        
      • 节点角色:8.x默认启用节点角色(master、data_hot、data_warm等),检查elasticsearch.yml配置:

        node.roles: [master, data_hot]
        
      • 安全设置:8.x强制启用X-Pack安全功能,需配置TLS和用户认证。

  • 检查弃用日志:

    • 查看/var/log/elasticsearch/Your-Cluster-Name_deprecation.log,识别并修复所有弃用警告。

    • 示例日志:

      [WARNING][deprecation] The use of types is deprecated and will be removed in 8.0
      

      解决方案:移除_type字段,重构查询。

1.4 备份数据

  • 创建快照:

    • 配置快照存储库(如S3、NFS、HDFS),确保7.x和8.x集群均可访问:

      PUT _snapshot/my_backup
      {"type": "s3","settings": {"bucket": "my-es-backup","region": "us-east-1"}
      }
      
    • 创建完整快照,包含所有索引和集群状态:

      PUT _snapshot/my_backup/snapshot_20250629
      {"indices": "*","include_global_state": true
      }
      
    • 验证快照状态:GET _snapshot/my_backup/_all。

  • 恢复测试:

    • 在测试环境中恢复快照,确保数据完整性:

      POST _snapshot/my_backup/snapshot_20250629/_restore
      {"indices": "*","include_global_state": true
      }
      
    • 检查Liferay等应用程序的索引(如liferay_company、liferay_system)是否正常加载。

  • 数据库备份:

    • 如果ES与Liferay或其他系统集成,备份相关数据库(如Liferay的MySQL/PostgreSQL表)。
    • 确保备份与快照时间点一致,使用时间戳命名(如backup_20250629)。
  • 多副本备份:

    • 将快照存储在多个位置(如S3和本地磁盘),提高数据安全性。

1.5 评估集群性能基线

  • 记录关键指标:

    • 使用Kibana Monitoring或API记录当前性能:

      GET _cat/indices?v&h=index,docs.count,store.size,pri,rep
      GET _cat/nodes?v&h=name,heap.percent,cpu,disk.used_percent
      
    • 针对写入变慢问题,额外记录:

      • 索引刷新间隔:GET /index_name/_settings
      • 写入速率:GET _stats/indexing
      • 慢查询日志:GET /index_name/_settings?include_defaults=true(检查index.search.slowlog)。
  • 硬件评估:

    • 检查节点硬件配置:

      • CPU:建议8核以上,8.x对多核性能优化更明显。
      • 内存:每个节点至少32GB,JVM堆内存设置为物理内存的50%(最大31GB)。
      • 磁盘:使用SSD,检查IO性能(iostat -x 1)。
    • 针对写入变慢,检查磁盘IO是否饱和:

      iostat -x 1 | grep sda
      

      如果%util接近100%,需升级磁盘或优化分片。

  • 负载测试:

    • 使用工具(如JMeter、Rally)模拟生产负载,记录写入和查询性能。

    • 示例:Rally测试写入性能:

      esrally race --track=pmc --target-hosts=localhost:9200 --pipeline=benchmark-only
      
  1. 测试环境验证
  • 搭建测试集群:

    • 配置与生产环境相同的节点数量、分片设置、索引结构和硬件规格。
    • 示例:3节点集群(1主节点、2数据节点),每个节点16GB堆内存。
  • 模拟升级:

    • 在测试集群上执行完整升级流程(滚动升级或完整重启)。
    • 验证应用程序连接、Kibana仪表板、机器学习任务、快照恢复等功能。
  • 性能对比:

    • 记录7.x和8.x的写入速率、查询响应时间、资源使用率。

    • 针对写入变慢问题,测试8.x的批量写入性能:

      POST /index_name/_bulk
      { "index": {} }
      { "field1": "value1" }
      { "index": {} }
      { "field1": "value2" }
      
  • 故障模拟:

    • 模拟节点掉线、快照恢复、数据丢失场景,确保8.x集群的容错能力。

二、升级策略

根据集群规模、业务连续性要求和数据量大小,选择以下三种升级策略。以下详细说明每种策略的步骤、注意事项和针对写入变慢的优化点。

2.1 滚动升级(Rolling Upgrade)

  • 适用场景:适合希望最小化服务中断的场景,推荐用于7.17.x到8.x的升级。

  • 步骤:

    1. 禁用分片分配:

      • 防止升级过程中分片重新分配,降低性能影响:

        PUT _cluster/settings
        {" persistent": {"cluster.routing.allocation.enable": "primaries"}
        }
        
    2. 执行同步刷新:

      • 确保所有索引数据写入磁盘:

        POST _flush/synced
        
    3. 逐节点升级:

      • 按角色顺序:

        • 先升级非主节点(node.master: false),如数据节点(data_hot、data_warm、data_cold)。
        • 再升级协调节点(node.coordinating_only: true)。
        • 最后升级主节点(node.master: true)。
      • 单节点升级流程:

        1. 停止节点:systemctl stop elasticsearch。

        2. 备份配置文件:

          cp -r /etc/elasticsearch /etc/elasticsearch.bak
          
        3. 升级Elasticsearch:

          # 示例:CentOS上使用yum升级
          sudo yum install elasticsearch-8.18.0
          
        4. 更新配置文件:

          • elasticsearch.yml:

            node.name: node-1
            node.roles: [master, data_hot]
            cluster.name: my-cluster
            network.host: 0.0.0.0
            http.port: 9200
            xpack.security.enabled: true
            xpack.security.transport.ssl.enabled: true
            xpack.security.transport.ssl.keystore.path: /path/to/keystore.p12
            
          • jvm.options:

            -Xms16g
            -Xmx16g
            
        5. 启动节点:systemctl start elasticsearch。

        6. 检查日志:/var/log/elasticsearch/my-cluster.log,确保无错误(如TLS配置错误)。

        7. 验证节点加入集群:GET _cat/nodes?v&h=name,version,role。

    4. 重复升级其他节点:

      • 逐一升级,等待每个节点后集群状态恢复为绿色:GET _cat/health?v。
      • 检查分片状态:GET _cat/shards?v&h=index,shard,prirep,state。
    5. 启用分片分配:

      PUT _cluster/settings
      {"persistent": {"cluster.routing.allocation.enable": null}
      }
      
    6. 验证集群状态:

      • 检查集群健康:GET _cluster/health。
      • 验证索引写入和查询功能:POST /index_name/_search。
      • 检查快照生命周期管理(SLM)是否正常:GET _slm/policy。
  • 注意事项:

    • 升级期间,集群可能短暂处于黄色状态(副本分片未分配),但主分片应始终可用。

    • 避免运行高负载任务(如机器学习、批量索引),以减少资源竞争。

    • 如果节点升级失败,回滚到7.17.x并从快照恢复:

      POST _snapshot/my_backup/snapshot_20250629/_restore
      

2.2 完整集群重启(Full Cluster Restart)

  • 适用场景:适合小型集群或允许短时间停机的场景。

  • 步骤:

    1. 停止所有服务:

      • 停止Kibana、Logstash和所有Elasticsearch节点:

        systemctl stop kibana
        systemctl stop logstash
        systemctl stop elasticsearch
        
      • 通知业务方计划停机时间(通常几小时)。

    2. 升级所有节点:

      • 在每个节点上安装8.x版本:

        sudo yum install elasticsearch-8.18.0
        
      • 更新配置文件,启用TLS和认证:

        xpack.security.enabled: true
        xpack.security.http.ssl.enabled: true
        xpack.security.http.ssl.keystore.path: /path/to/http.p12
        
      • 生成用户密码:

        bin/elasticsearch-setup-passwords auto
        
    3. 启动集群:

      • 按角色顺序启动:先主节点,再数据节点,最后协调节点。
      • 检查集群状态:GET _cat/health?v,确保为绿色。
    4. 重新索引:

      • 如果存在不兼容索引,执行重新索引:

        POST _reindex
        {"source": {"index": "old_index"},"dest": {"index": "new_index_8x"}
        }
        
    5. 验证功能:

      • 检查Kibana仪表板、搜索功能、机器学习任务。
      • 验证Liferay的索引(如liferay_company)是否正常。
  • 注意事项:

    • 需提前规划停机时间,确保业务影响最小。
    • 验证所有节点版本一致,避免启动失败。

2.3 蓝绿部署(Blue/Green Deployment)

  • 适用场景:适合大规模集群、数据量大或要求零停机的场景,特别适合您提到的写入变慢问题(可能与数据规模相关)。

  • 步骤:

    1. 搭建新8.x集群:

      • 配置与7.x集群相同的硬件、网络和存储库。

      • 设置快照存储库:

        PUT _snapshot/my_backup
        {"type": "s3","settings": {"bucket": "my-es-backup","readonly": true}
        }
        
    2. 恢复快照:

      • 恢复7.x快照到8.x集群:

        POST _snapshot/my_backup/snapshot_20250629/_restore
        {"indices": "*","include_global_state": true
        }
        
      • 验证数据完整性:GET /index_name/_search。

    3. 数据同步:

      • 修改应用程序代码,双写到7.x和8.x集群:

        // 示例:Java客户端双写
        RestHighLevelClient client7x = new RestHighLevelClient(...);
        RestHighLevelClient client8x = new RestHighLevelClient(...);
        IndexRequest request = new IndexRequest("index_name").source(...);
        client7x.index(request, RequestOptions.DEFAULT);
        client8x.index(request, RequestOptions.DEFAULT);
        
      • 或者使用Logstash同步:

        input {elasticsearch {hosts => ["http://7x-cluster:9200"]index => "index_name"}
        }
        output {elasticsearch {hosts => ["https://8x-cluster:9200"]index => "index_name"}
        }
        
    4. 性能测试:

      • 模拟生产负载,验证8.x集群的写入和查询性能。
      • 检查写入变慢问题是否缓解(见优化部分)。
    5. 切换流量:

      • 更新应用程序配置,切换到8.x集群。
      • 监控新集群的稳定性,确认无异常后停止7.x集群。
    6. 清理旧集群:

      • 删除7.x集群,释放资源。
  • 注意事项:

    • 蓝绿部署需要额外资源,预算需提前规划。
    • 确保快照存储库在8.x集群上正确配置,验证恢复的索引完整性。
    • 数据同步期间监控两集群的一致性,避免数据丢失。

三、升级后优化与调优

3.1 索引配置优化

  • 检查mapping结构:

    • 8.x移除_type字段,检查所有索引mapping:

      GET /index_name/_mapping
      

      如果包含_type,需重新索引并更新应用程序代码。

    • 优化mapping,减少字段数量和嵌套深度:

      PUT /index_name
      {"mappings": {"properties": {"field1": { "type": "keyword" },"field2": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }}}
      }
      
  • 合并段文件:

    • 减少段文件数量,降低IO开销:

      POST /index_name/_forcemerge?max_num_segments=1
      
    • 在低峰期执行,避免影响在线业务。

  • 优化分片设置:

    • 每个分片大小控制在10-50GB,过多分片增加管理开销:

      GET _cat/shards?v&h=index,shard,prirep,store
      
    • 如果分片过多,合并索引或调整分片数量:

      PUT /index_name/_settings
      {"index": {"number_of_shards": 5,"number_of_replicas": 1}
      }
      

3.2 集群资源管理

  • 调整JVM堆内存:

    • 8.x对内存需求更高,建议JVM堆内存为节点物理内存的50%,最大31GB:

      # jvm.options
      -Xms16g
      -Xmx16g
      
    • 监控堆使用率:GET _nodes/stats/jvm。

  • 磁盘IO优化:

    • 使用SSD,确保磁盘IO不饱和(iostat -x 1)。

    • 针对写入变慢,检查是否因磁盘队列过长:

      iostat -x 1 | grep sda
      

      如果avgqu-sz过高,考虑增加磁盘或减少写入负载。

  • 节点角色分配:

    • 使用8.x的节点角色优化资源分配:

      node.roles: [data_hot]
      
    • 将写入密集型索引分配到data_hot节点,查询密集型索引分配到data_warm节点。

3.3 写入流程优化

  • 批量写入:

    • 使用_bulk API减少网络开销:

      POST /_bulk
      { "index": { "_index": "index_name" } }
      { "field1": "value1" }
      { "index": { "_index": "index_name" } }
      { "field1": "value2" }
      
    • 批量大小控制在5-15MB,过大可能导致内存压力。

  • 调整刷新间隔:

    • 增加index.refresh_interval(如从1s到30s),降低写入频率:

      PUT /index_name/_settings
      {"index": {"refresh_interval": "30s"}
      }
      
  • 线程池调整:

    • 针对写入变慢,增加write线程池大小:

      PUT _cluster/settings
      {"persistent": {"thread_pool.write.size": 16,"thread_pool.write.queue_size": 200}
      }
      
    • 监控线程池:GET _nodes/stats/thread_pool。

3.4 启用索引生命周期管理(ILM)

  • 8.x默认启用ILM,优化数据老化:

    PUT _ilm/policy/my_policy
    {"policy": {"phases": {"hot": {"actions": {"rollover": {"max_size": "50gb","max_age": "30d"}}},"warm": {"actions": {"allocate": {"require": { "data": "warm" }}}},"delete": {"min_age": "90d","actions": {"delete": {}}}}}
    }
    
  • 应用ILM到索引:

    PUT /index_name/_settings
    {"index.lifecycle.name": "my_policy"
    }
    

3.5 监控与验证

  • 慢日志分析:

    • 启用慢查询日志,定位写入瓶颈:

      PUT /index_name/_settings
      {"index.search.slowlog.threshold.query.warn": "10s","index.indexing.slowlog.threshold.index.warn": "5s"
      }
      
    • 检查日志:/var/log/elasticsearch/index_name_indexing_slowlog.log。

  • 性能监控:

    • 使用Kibana Monitoring跟踪写入速率、查询延迟、资源使用率。

    • 示例:检查索引统计:

      GET /index_name/_stats/indexing,search
      
  • 验证功能:

    • 检查Kibana仪表板、搜索结果、机器学习任务。
    • 验证Liferay的拼写检查和搜索调优索引是否正常。

四、常见问题处理

  • TLS配置错误:
    • 错误日志:javax.net.ssl.SSLHandshakeException
    • 解决方案:检查keystore.p12路径和密码,确保证书有效。
  • 索引不兼容:
    • 问题:6.x索引无法在8.x加载。
    • 解决方案:在7.x环境中重新索引到7.x格式,再迁移到8.x。
  • 写入性能下降:
    • 可能原因:分片过多、刷新间隔过短、磁盘IO瓶颈。
    • 解决方案:参考优化部分,调整分片、刷新间隔和线程池。
  • 节点无法加入集群:
    • 错误日志:master not discovered yet
    • 解决方案:检查cluster.initial_master_nodes配置,确保网络连通性。
http://www.lryc.cn/news/577044.html

相关文章:

  • 【C++】C++中的友元函数和友元类
  • Prompt Depth Anything:以提示方式驱动的Depth Anything用于实现4K分辨率下的精确米制深度估计
  • 大事件项目记录12-文章管理接口开发-总
  • 【学习】《算法图解》第八章学习笔记:平衡树
  • springboot校园新闻网站
  • 基于Pandas和FineBI的昆明职位数据分析与可视化实现(三)- 职位数据统计分析
  • 二叉树找到下一个中序遍历节点的思路
  • MATLAB仿真:经过大气湍流的涡旋光束的光斑漂移
  • 消息队列:Redis Stream到RabbitMQ的转换
  • python中*args, **kwargs到底是什么意思
  • Mac使用VMware安装win11使用Origin绘图巨卡解决办法
  • linux运维学习第10周
  • 智能新纪元:大语言模型如何重塑电商“人货场”经典范式
  • 条件概率:不确定性决策的基石
  • Oracle 递归 + Decode + 分组函数实现复杂树形统计进阶(第二课)
  • 中介者模式 - Flutter中的通信指挥中心,告别组件间混乱对话!
  • 怎样学习STM32
  • Springboot 集成 SpringBatch 批处理组件
  • 2.安装Docker
  • 力扣第87题-扰乱字符串
  • 如何通过自动化减少重复性工作
  • Vue中的v-if与emit事件传递:一个常见陷阱分析
  • 推荐几本关于网络安全的书
  • FastAPI+Sqlite+HTML的登录注册与文件上传系统:完整实现指南
  • 6月28日记
  • Re:从0开始的 空闲磁盘块管理(考研向)
  • H3C-路由器交换机-中继
  • 用户行为序列建模(篇六)-【阿里】DSIN
  • DeepSeek五子棋游戏与AI对战
  • 【unity游戏开发——网络】网络游戏通信方案——强联网游戏(Socket长连接)、 弱联网游戏(HTTP短连接)