📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

在企业级搜索与数据分析场景中,性能往往是衡量系统优劣的核心标准。作为一款自主可控、基于 Apache Lucene 构建的分布式近实时搜索与分析引擎,INFINI Easysearch 在保持与 Elasticsearch 高度兼容的同时,针对高并发、大数据量及复杂业务场景进行了深度的内核级优化。

本文将深入探讨 Easysearch 的核心性能指标,并结合实战案例,详细解析缓存策略、分片管理及副本配置的调优技巧,帮助你在极限科技(INFINI Labs)的最佳实践指导下,构建高效、稳定的搜索系统。


一、 核心性能指标体系 #

在对 Easysearch 进行调优之前,必须建立一套科学的性能监控指标体系。这些指标不仅是发现问题的“听诊器”,也是验证调优效果的“标尺”。

1.1 搜索性能指标 #

  • 延迟(Latency):指从发起请求到收到响应的时间。
    • 关键点:重点关注 P95、P99 延迟,而不仅仅是平均值。对于实时性要求高的业务(如金融风控),P99 延迟需控制在毫秒级。
  • 吞吐量(Throughput):通常用 QPS(Queries Per Second)衡量。

1.2 索引性能指标 #

  • 索引速率(Indexing Rate):每秒索引的文档数量。
  • 刷新时间(Refresh Time):段数据从内存写入磁盘的过程。过频繁的 Refresh 会消耗大量 I/O 和 CPU。
  • 合并时间(Merge Time):段合并的过程。如果 Merge 占用过高资源,会导致查询变慢。

1.3 资源利用率指标 #

  • 堆内存(JVM Heap):需密切监控 Old Generation(老年代)的使用情况。
    • 警告信号:老年代持续增长,Full GC 频繁,可能导致 OOM。
  • Disk I/O:磁盘读写速度和 IOPS。Easysearch 的 ZSTD 压缩功能可以有效降低磁盘 I/O 压力。
  • CPU Load:CPU 队列长度是否持续过高。

二、 缓存策略与优化:以空间换时间 #

合理的缓存策略是提升查询性能最直接的手段。Easysearch 继承并增强了 Lucene 的缓存机制,同时针对中文场景进行了优化。

2.1 节点查询缓存(Node Query Cache) #

该缓存主要缓存 Filter 上下文中的过滤条件结果(Bitset),适用于在不同查询中重复使用的 Filter 条件。。

调优技巧

  • 场景:适合不随时间变化或变化较慢的仪表盘查询。
  • 配置:通过 indices.queries.cache.size 调整大小(默认为 JVM 堆的 10%)。Easysearch 默认只缓存被多次使用的 Filter,并非查一次就缓存。
  • 注意:对于实时性要求极高的查询,建议禁用或设置较小的 TTL,以免读到“脏”数据。

2.2 分片请求缓存(Shard Request Cache) #

缓存聚合结果(Aggregations)和 size=0 的请求

调优技巧

  • 场景:非常适合过滤条件固定、但数据频繁变化的场景(如“查询昨天的日志”)。
  • Easysearch 优势:在涉及中文分词查询时,Easysearch 优化了词典结构,大幅降低了 Field Data 和分词器的内存开销,间接提升了缓存命中率。

2.3 Doc Values 与 Field Data 的取舍 #

用于排序和聚合。ES 默认使用磁盘上的 Doc Values,堆内存中的 Field Data 仅用于 Text 字段。

实战建议

  • 对于基数很高(如 UserID、UUID)的字段,务必使用 Keyword 类型并确保开启 Doc Values,既能保证性能又能避免堆内存溢出。
  • 严禁对高基数的 Text 字段开启 fielddata: true,这极易导致 OOM。
  • 开启 index: false 对于不需要被搜索(Search)但需要聚合(Aggs)的字段,可节省磁盘空间。

三、 分片策略:性能的晴雨表 #

分片是分布式存储的最小单元,分片策略的好坏直接决定了集群的并发能力和稳定性。

3.1 分片大小与数量原则 #

常见误区:分片越多越好。实际上,过多的分片会带来严重的“Segment Scattering”和 State 管理开销。

黄金法则

  1. 单个分片大小:建议控制在 10GB - 50GB 之间。最大不超过 50GB,否则恢复速度会变慢。
    如果是日志类(Log/Time-series)且只写不改,分片可以稍大(50GB);如果是频繁更新(Update/Delete)的业务数据,建议分片稍小(20-30GB)以加速 Merge。
  2. 分片数量
    • 公式分片数 = 目标数据总量 / 单个分片大小
    • 案例:一汽集团案例中数据量超 1.5PB,由于规划得当,依然保持了高性能。
  3. 避免 Over-sharding:每个节点的分片数不宜超过 20-30 个。

3.2 索引生命周期管理 (ILM) 与 Rollover #

为了避免单个索引过大,应采用 基于时间的 Rollover 策略。

实战配置示例

PUT _ilm/policy/logs_policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_size": "50GB",
            "max_age": "30d"
          }
        }
      },
      "warm": {
        "min_age": "30d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          }
        }
      }
    }
  }
}

3.3 冷热数据分离 #

Easysearch 支持高效的冷热分离,结合 可搜索快照 功能,可以极大地降低成本。

  • Hot 节点:使用高性能 SSD,存放高频访问数据。
  • Cold 节点:使用大容量 HDD 或对象存储(如 Minio),存放历史数据。
  • 优势:一汽集团通过开启 ZSTD 压缩和冷热分离,存储空间降低了 50%

四、 副本策略:高可用与读性能的平衡 #

副本主要用于数据冗余(高可用)和提升读并发能力,但会增加写入延迟。

4.1 副本数设置 #

  • 写入为主:副本数设为 0 或 1。副本复制需要跨网络传输,会影响写入速度。
  • 读为主:适当增加副本(如 2-3),将读请求分散到多个副本分片上。

4.2 动态调整副本 #

Easysearch 允许动态调整副本数,无需停机。

实战操作

# 在促销活动前,增加副本以提升读并发
PUT /my_index/_settings
{
  "number_of_replicas": 3
}

# 活动结束后,减少副本以释放资源
PUT /my_index/_settings
{
  "number_of_replicas": 1
}

五、 Easysearch 独家实战技巧:超越 ES 的调优能力 #

作为自主可控的增强版搜索引擎,Easysearch 提供了一些原生 ES 不具备或收费的高级调优功能,这在处理极端流量时尤为关键。

5.1 三级写入限流 #

在面对海量 Bulk 写入(如日志洪峰)时,单纯靠硬件扩容往往成本高昂且不够灵活。Easysearch 提供了 节点、分片、索引 三级限流能力,无需重启即可生效,保护集群不被压垮。

技术细节:这里的限流是基于写入链路中对“bulk item 数”与“bulk 请求体内存字节(ramBytesUsed)”的计量进行扣减,更接近“每 interval(默认1秒)的请求数/字节数预算”,并非严格意义上的 HTTP QPS 或真实落盘吞吐。

实战配置

# 1. 开启节点级别的写入限流
# 限制每个数据节点的写入字节数为 50MB/s
PUT _cluster/settings
{
  "transient": {
    "cluster.throttle.node.write": true,
    "cluster.throttle.node.write.max_bytes": "50mb"
  }
}

# 2. 开启分片级别的写入限流(新增补充)
# 同步限制单个分片的写入压力,细化到分片级别
PUT _cluster/settings
{
  "transient": {
    "cluster.throttle.shard.write": true,
    "cluster.throttle.shard.write.max_bytes": "10mb"
  }
}

# 3. 开启索引级别的精细控制
# 限制特定索引的写入 QPS
PUT /my_logs/_settings
{
  "index.throttle.write.enable": true,
  "index.throttle.write.max_requests": 10000
}

来源:基于 Easysearch 1.8.0+ 版本特性验证

5.2 ZSTD + Source Reuse 多重压缩 #

Easysearch 内置了对 Zstandard (ZSTD) 压缩算法的支持,相比默认的 LZ4,压缩率显著提高(通常可节省 20-40% 的空间),同时将 CPU 开销控制在极低范围内。

Easysearch 的独有优势: 虽然 Elasticsearch 8.x 也引入了对 ZSTD 的支持,但 Easysearch 通过独有的 Source Reuse (源数据复用) 技术实现了二次压缩优化:

  • 精细化去重:Source Reuse 能够智能识别并剔除 _source 字段中与 doc_values 或倒排索引重复的数据内容。
  • 极致容量压缩:在开启 ZSTD 的基础上叠加 Source Reuse,针对日志类等高冗余数据场景,可额外再降低约 20%-25% 的存储成本。

配置

PUT /my_index/_settings
{
  "index": {
    "codec": "zstd",
    "source_reuse": true
  }
}

5.3 查询加速与去重 #

对于业务中常见的精确去重需求(如统计每日 UV),传统 ES 方式极其消耗内存。Easysearch 优化了去重算法,能够实现百万级文档毫秒级响应。


六、 总结与最佳实践清单 #

Easysearch 的性能调优是一个系统工程,需要结合业务场景、硬件资源和数据特性进行综合考虑。以下是一个快速调优清单:

  1. 监控先行:部署统一管控平台(INFINI Console),实时监控 JVM、Disk、CPU 及 P99 延迟。
  2. 规划分片:保持单个分片在 10-50GB,拒绝过度分片,使用 ILM 自动滚动索引。
  3. 合理缓存:针对聚合查询开启 Node Query Cache,针对排序/聚合字段开启 Doc Values。
  4. 冷热分离:结合 ZSTD 压缩和可搜索快照,降低 50% 以上的存储成本。
  5. 利用限流:在业务高峰期,开启 Easysearch 的 Write Throttling 功能,避免集群雪崩。
  6. 硬件选择:Hot 节点使用 NVMe SSD,Warm/Cold 节点使用 SATA SSD 或 HDD;JVM Heap 设置不要超过 30GB。

通过掌握上述核心指标与调优技巧,你可以充分发挥 INFINI Easysearch “降本增效、自主可控”的产品优势,在金融、制造、运营商等高要求场景中构建坚若磐石的搜索底座。

参考 #

Easysearch 索引生命周期管理实战

Easysearch 新特性:写入限流功能介绍

Easysearch 压缩模式深度比较:ZSTD + source_reuse 的优势分析