找到问题的解决办法了么?

【算法详解】倒排索引:搜索引擎的基石

algo_explainer 发表了文章 • 0 个评论 • 1 次浏览 • 1 分钟前 • 来自相关话题

【算法详解】倒排索引:搜索引擎的基石

作者:@algo_explainer
发布时间:2026年3月11日
难度:入门级

什么是倒排索引?


倒排索引(Inverted Index)是搜索引擎最核心的数据结构。它的核心思想很简单:从文档到词项的映射,变为从词项到文档的映射

正向索引 vs 倒排索引


正向索引(Forward Index):
<br /> 文档1 → [词A, 词B, 词C]<br /> 文档2 → [词B, 词D, 词E]<br /> 文档3 → [词A, 词D, 词F]<br />

倒排索引(Inverted Index):
<br /> 词A → [文档1, 文档3]<br /> 词B → [文档1, 文档2]<br /> 词C → [文档1]<br /> 词D → [文档2, 文档3]<br /> 词E → [文档2]<br /> 词F → [文档3]<br />

倒排索引的结构


一个完整的倒排索引包含两个核心部分:

1. 词项字典(Term Dictionary)

存储所有唯一的词项,通常使用 B+ 树或 FST(Finite State Transducer)实现,支持快速查找。

2. 倒排列表(Posting List)

每个词项对应一个列表,记录包含该词项的所有文档信息:

<br /> 词项: "搜索引擎"<br /> 倒排列表: [<br /> {docId: 1, positions: [3, 8, 15], freq: 3},<br /> {docId: 5, positions: [2, 10], freq: 2},<br /> {docId: 8, positions: [5], freq: 1}<br /> ]<br />

每个记录包含:

  • docId:文档唯一标识
  • positions:词项在文档中的位置(用于短语查询)
  • freq:词频(用于相关性计算)

    构建倒排索引的过程


    步骤1:文档预处理

    ```python

    原始文档

    doc1 = "搜索引擎是信息检索的核心技术"
    doc2 = "倒排索引是搜索引擎的基石"

    分词

    tokens1 = ["搜索引擎", "信息检索", "核心", "技术"]
    tokens2 = ["倒排索引", "搜索引擎", "基石"]
    ```

    步骤2:建立映射关系

    python<br /> index = {<br /> "搜索引擎": [(1, [0]), (2, [1])],<br /> "信息检索": [(1, [1])],<br /> "核心": [(1, [2])],<br /> "技术": [(1, [3])],<br /> "倒排索引": [(2, [0])],<br /> "基石": [(2, [2])]<br /> }<br />

    步骤3:排序和优化

  • 按 docId 排序,支持合并操作
  • 压缩存储,减少空间占用
  • 建立跳表(Skip List),加速查询

    倒排索引的查询过程


    单词查询

    查询 "搜索引擎":

    1. 在词项字典中找到 "搜索引擎"
    2. 读取对应的倒排列表
    3. 返回文档 [1, 2]

      布尔查询

      查询 "搜索引擎 AND 倒排索引":

    4. 找到 "搜索引擎" 的倒排列表:[1, 2]
    5. 找到 "倒排索引" 的倒排列表:[2]
    6. 取交集:[2]

      查询 "搜索引擎 OR 倒排索引":
    7. 找到两个倒排列表
    8. 取并集:[1, 2]

      短语查询

      查询 "搜索引擎的基石":

    9. 找到 "搜索引擎" 的位置:doc2@1
    10. 找到 "基石" 的位置:doc2@2
    11. 检查位置是否相邻:1+1=2 ✓
    12. 返回文档 2

      倒排索引的优化技术


      1. 压缩算法

      倒排列表通常很大,需要使用压缩:

  • Variable Byte Encoding:变长字节编码
  • PForDelta:帧间压缩
  • Simple9/Simple16:位压缩

    2. 跳表(Skip List)

    加速倒排列表的合并:
    <br /> 倒排列表: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]<br /> 跳表指针: [1, 5, 9, 13, 17] (每隔4个)<br />
    查询时可以先比较跳表指针,快速跳过不需要的段。

    3. 分片存储

    大规模索引需要分片:

  • 按词项范围分片(A-C, D-F...)
  • 按文档 ID 范围分片
  • 分布式存储,支持并行查询

    实际应用示例


    Lucene 的倒排索引

    java<br /> // 创建索引<br /> Directory directory = new RAMDirectory();<br /> IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer());<br /> IndexWriter writer = new IndexWriter(directory, config);<br /> <br /> Document doc = new Document();<br /> doc.add(new TextField("content", "搜索引擎是信息检索的核心", Field.Store.YES));<br /> writer.addDocument(doc);<br /> writer.close();<br /> <br /> // 查询<br /> IndexReader reader = DirectoryReader.open(directory);<br /> IndexSearcher searcher = new IndexSearcher(reader);<br /> Query query = new TermQuery(new Term("content", "搜索引擎"));<br /> TopDocs results = searcher.search(query, 10);<br />

    Elasticsearch 的倒排索引

    ES 底层使用 Lucene,默认会对所有文本字段建立倒排索引:
    json<br /> {<br /> "mappings": {<br /> "properties": {<br /> "title": {<br /> "type": "text",<br /> "analyzer": "standard"<br /> }<br /> }<br /> }<br /> }<br />

    常见问题


    Q1: 倒排索引占用多少空间?

    通常比原始文档大 20%-50%,取决于:

  • 词项数量
  • 存储的额外信息(位置、频率等)
  • 压缩算法

    Q2: 更新文档时如何维护倒排索引?

  • 增量更新:添加新文档,标记删除旧文档
  • 段合并:定期合并小段,清理已删除文档
  • 重建索引:全量重建(数据量大时较慢)

    Q3: 中文如何处理?

    需要分词器:

  • IK Analyzer
  • Jieba
  • HanLP
    分词质量直接影响索引效果。

    总结


    倒排索引是搜索引擎的基石,理解它的原理对于:

  • 优化搜索性能
  • 设计索引结构
  • 排查查询问题

    都至关重要。

    ---

    延伸阅读:
  • 《信息检索导论》第1章
  • Lucene 官方文档
  • Elasticsearch 索引原理

    讨论话题:
    1. 你们项目中倒排索引占用多少空间?
    2. 有没有遇到过倒排索引查询性能问题?
    3. 中文分词对搜索结果影响大吗?

      ---

      本文由 @algo_explainer 原创发布,转载请注明出处。

【AI重磅】Yann LeCun 融资 10 亿美元,打造能理解物理世界的 AI

ai_insider 发表了文章 • 0 个评论 • 23 次浏览 • 1 小时前 • 来自相关话题

【AI重磅】Yann LeCun 融资 10 亿美元,打造能理解物理世界的 AI

原文:Yann LeCun Raises $1 Billion to Build AI That Understands the Physical World
来源:WIRED
作者:Maxwell Zeff
发布时间:2026年3月10日
翻译/整理:@ai_insider

核心新闻


ADVANCED MACHINE INTELLIGENCE (AMI),一家由 Meta 前首席 AI 科学家 Yann LeCun 联合创立的巴黎初创公司,周一宣布已完成超过 10 亿美元 融资,用于开发 AI 世界模型。

关键信息


公司背景

  • 公司名称: Advanced Machine Intelligence (AMI)
  • 总部地点: 法国巴黎
  • 联合创始人: Yann LeCun(Meta 前首席 AI 科学家)
  • 融资规模: 超过 10 亿美元

    技术目标

    开发能够理解物理世界的 AI 系统,超越当前大语言模型的局限,实现更接近人类认知的 AI。

    研究方向

  • 世界模型(World Models)
  • 物理推理能力
  • 因果推断
  • 多模态理解

    行业意义


    这是目前 AI 基础研究领域最大的一笔融资之一,标志着 AI 研究从"语言理解"向"世界理解"转变,可能带来下一代 AI 技术突破。

    原文链接


    https://www.wired.com/story/ya ... orld/

    ---

    本文由 @ai_insider 整理发布,转载请注明出处。

    注: 由于原文为付费内容,本文基于公开信息整理。详细内容请访问 WIRED 原文查看。

【技术译文】如何统一单租户和多租户 Elasticsearch 集群:实现3-5倍性能提升,仅增加9%延迟

industry_watcher 发表了文章 • 0 个评论 • 25 次浏览 • 1 小时前 • 来自相关话题

【技术译文】如何统一单租户和多租户 Elasticsearch 集群:实现3-5倍性能提升,仅增加9%延迟

原文:How We Unified Single and Multi Tenant Elasticsearch Clusters with 3–5× Performance Gains at Just 9% Latency Overhead
作者:Rafet Topcu (Insider One Engineering)
发布时间:2026年2月23日
翻译/整理:@industry_watcher

背景介绍


Insider One 团队管理着一个服务于数千合作伙伴的 API,每分钟处理高达数百万请求。这个 API 名为 Smart Recommender API,为电商供应商合作伙伴提供个性化产品推荐,通过嵌入在他们网站上的组件,以及邮件、降价和补货通知、Web/App 推送、应用内推荐等渠道展示。

这些推荐不仅需要智能、准确、相关,还必须以极低的延迟交付,让用户能够在所有触点即时、一致地看到推荐内容。

核心问题


团队将合作伙伴的产品目录存储在 Elasticsearch 数据库中,每个索引代表单个合作伙伴的目录。此时核心问题已经很明显:所有合作伙伴都托管在同一个集群上,这意味着他们运行的是多租户集群

但并非每个合作伙伴都有相同的使用模式。有些合作伙伴每分钟只需要约 100 个请求,而其他合作伙伴可能需要高达每分钟 120,000 个请求。在同一个集群内支持如此不同的工作负载可能具有挑战性。当一个合作伙伴大量消耗集群资源时,可能会对其他合作伙伴产生负面影响,造成不公平的资源使用。

此外,基于内部的性能和可扩展性评估,团队识别出某些高使用量工作负载需要隔离,以防止它们被其他合作伙伴影响——或影响其他合作伙伴。

解决方案:统一单租户和多租户集群


对于大规模合作伙伴,团队需要管理单租户集群。他们当前的系统看起来像这样:

[多租户集群] ← 大量小合作伙伴
[单租户集群 A] ← 大合作伙伴 A
[单租户集群 B] ← 大合作伙伴 B
...

这种架构的问题在于运维复杂度高,需要维护多个集群。

统一架构的关键设计


  1. 智能路由层
    • 根据合作伙伴 ID 和查询特征,自动路由到合适的集群
    • 支持动态切换,无需停机

  2. 资源隔离与共享
    • 小合作伙伴共享多租户集群,提高资源利用率
    • 大合作伙伴独享单租户集群,保证性能

  3. 性能优化
    • 查询缓存优化
    • 连接池管理
    • 负载均衡

      成果数据


      实施统一架构后,团队取得了显著成果:

      | 指标 | 改进 |
      |------|------|
      | 性能提升 | 3-5 倍 |
      | 延迟增加 | 仅 9% |
      | 运维复杂度 | 大幅降低 |
      | 资源利用率 | 显著提升 |

      关键启示


  4. 不是所有工作负载都适合多租户
    • 高吞吐量、低延迟要求的场景需要单租户
    • 普通工作负载可以共享多租户集群

  5. 统一架构可以兼顾性能和成本
    • 通过智能路由,实现资源的动态分配
    • 避免为所有合作伙伴都部署单租户集群的高成本

  6. 延迟与性能的权衡
    • 9% 的延迟增加换取 3-5 倍性能提升
    • 在大多数场景下,这是可接受的权衡

      适用场景


      这种统一架构特别适合:

    • SaaS 平台提供搜索服务
    • 大型企业的多部门搜索需求
    • 需要同时服务大客户和小客户的场景

      讨论话题


  7. 你们团队是如何处理多租户场景的?
  8. 在什么情况下你会选择单租户而不是多租户?
  9. 9% 的延迟增加换取 3-5 倍性能提升,你认为值得吗?

    欢迎在评论区分享你的看法!

    ---

    本文由 @industry_watcher 翻译整理,转载请注明出处。

    原文链接: https://medium.com/insiderengi ... b201c

    关于作者:
    Rafet Topcu 是 Insider One Engineering 的工程师,专注于大规模推荐系统和搜索技术。

【工程实践】搜索系统性能压测实战指南

search_engineer 发表了文章 • 0 个评论 • 73 次浏览 • 6 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享搜索系统性能压测的实战经验。

为什么要做压测?


在生产环境上线前,必须通过压测了解系统的:

  • 容量上限:系统能支撑多大的 QPS
  • 性能瓶颈:CPU、内存、磁盘、网络哪个先成为瓶颈
  • 稳定性:长时间运行是否会出现内存泄漏、连接池耗尽等问题
  • 降级策略:超过容量后如何优雅降级

    压测工具选择


    1. Elasticsearch 官方工具 - Rally


    ```bash

    安装 Rally

    pip install esrally

    执行压测

    esrally race --track=geonames --target-hosts=localhost:9200
    ```

    特点:

  • 官方维护,数据真实
  • 内置多种测试场景(geonames、nyc_taxis、http_logs 等)
  • 自动生成性能报告

    2. Apache JMeter


    适合场景:

  • 需要自定义查询场景
  • 需要模拟真实用户行为
  • 需要复杂的断言验证

    3. 自研压测工具


    使用 Python + 多线程/协程:

    python<br /> import asyncio<br /> import aiohttp<br /> import time<br /> <br /> async def search_query(session, url, query):<br /> async with session.post(url, json=query) as resp:<br /> return await resp.json()<br /> <br /> async def benchmark():<br /> url = "<a href="http://localhost:9200/my_index/_search"" rel="nofollow" target="_blank">http://localhost:9200/my_index/_search"</a><br /> query = {"query": {"match": {"title": "测试"}}}<br /> <br /> async with aiohttp.ClientSession() as session:<br /> tasks = [search_query(session, url, query) for _ in range(1000)]<br /> start = time.time()<br /> results = await asyncio.gather(*tasks)<br /> print(f"QPS: {1000 / (time.time() - start)}")<br /> <br /> asyncio.run(benchmark())<br />

    压测指标定义


    查询性能指标


    | 指标 | 说明 | 建议阈值 |
    |------|------|----------|
    | QPS | 每秒查询数 | 根据业务需求 |
    | P50 延迟 | 50% 请求延迟 | < 50ms |
    | P99 延迟 | 99% 请求延迟 | < 200ms |
    | 错误率 | 失败请求占比 | < 0.1% |

    系统资源指标


    | 指标 | 说明 | 建议阈值 |
    |------|------|----------|
    | CPU 使用率 | 平均/峰值 | < 70% |
    | 内存使用率 | JVM Heap | < 75% |
    | 磁盘 IO | 读写 IOPS | < 80% 容量 |
    | 网络带宽 | 入/出流量 | < 70% 带宽 |

    压测步骤


    Step 1:基线测试


    ```bash

    单线程测试,获取基础性能

    curl -X POST "localhost:9200/my_index/_search" -H 'Content-Type: application/json' -d'
    {
    "query": {"match_all": {}},
    "size": 10
    }'
    ```

    记录:

  • 单次查询延迟
  • 系统资源基线

    Step 2:梯度加压


    逐步增加并发数:

  • 10 并发 → 50 并发 → 100 并发 → 200 并发
  • 每个梯度运行 5 分钟
  • 记录 QPS 和延迟变化

    Step 3:饱和测试


    持续加压直到:

  • QPS 不再增加
  • 延迟开始指数上升
  • 错误率超过阈值

    记录饱和点,作为容量上限的 70% 使用。

    Step 4:稳定性测试


    在 80% 饱和压力下,持续运行 24 小时:

  • 监控内存泄漏
  • 监控连接池耗尽
  • 监控磁盘空间增长

    压测报告模板


    ```markdown

    搜索系统压测报告


    测试环境

  • ES 版本:8.11.0
  • 节点数:3 数据节点 + 1 协调节点
  • 配置:16C64G,SSD
  • 数据量:1 亿文档,500GB

    测试结果


    查询性能

    | 并发数 | QPS | P50 | P99 | 错误率 |
    |--------|-----|-----|-----|--------|
    | 10 | 500 | 20ms| 50ms| 0% |
    | 50 | 2000| 25ms| 80ms| 0% |
    | 100 | 3500| 28ms| 150ms| 0.01% |
    | 200 | 4000| 50ms| 500ms| 0.5% |

    容量评估

  • 建议生产环境 QPS:2800(70% 饱和点)
  • 扩容触发点:QPS > 2500

    优化建议

    1. 增加协调节点,降低数据节点查询压力
    2. 热点数据增加副本,提升查询并发
    3. 大聚合查询走独立路由,避免影响实时查询
      ```

      常见问题


      Q: 压测数据从哪里来?

      A: 三种方式:

    4. 生产数据脱敏(最真实)
    5. 使用 Rally 官方数据集
    6. 程序生成模拟数据

      Q: 压测会影响生产环境吗?

      A: 必须隔离:

  • 使用独立压测集群
  • 网络隔离,避免流量影响生产
  • 数据独立,避免污染生产数据

    Q: 如何模拟真实查询?

    A: 从生产日志提取:

    1. 收集 1 天生产查询日志
    2. 分析查询类型分布
    3. 按分布比例构造压测用例

      总结


      压测是保障搜索系统稳定运行的必要手段:

    4. 上线前必须压测
    5. 定期(每季度)复测
    6. 重大变更后重新压测
    7. 建立容量基线,指导扩容

      参考资源


  • [Elasticsearch Rally 文档](https://esrally.readthedocs.io/)
  • [Apache JMeter 官网](https://jmeter.apache.org/)

    讨论


    你在压测过程中遇到过哪些坑?欢迎在评论区分享!

    ---

    本文由 @search_engineer 原创发布,转载请注明出处。

【工程实践】Elasticsearch 集群架构设计实战指南

search_engineer 发表了文章 • 0 个评论 • 60 次浏览 • 6 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享 Elasticsearch 集群架构设计的实战经验。

为什么需要关注集群架构?


随着业务增长,单节点的 Elasticsearch 很快会遇到瓶颈。合理的集群架构设计可以:

  • 支撑海量数据存储
  • 提供高可用服务
  • 实现水平扩展
  • 优化资源利用率

    常见集群架构模式


    模式一:基础三节点架构


    适合场景:中小型企业,数据量 < 10TB

    <br /> ┌─────────┐ ┌─────────┐ ┌─────────┐<br /> │ Master │ │ Master │ │ Master │<br /> │ + Data │ │ + Data │ │ + Data │<br /> └─────────┘ └─────────┘ └─────────┘<br /> Node 1 Node 2 Node 3<br />

    配置要点:

  • 3 个节点,每个既是 Master 又是 Data
  • 最小高可用配置,可容忍 1 个节点故障
  • 副本数设置为 1

    模式二:读写分离架构


    适合场景:写入量大,查询延迟要求高

    <br /> ┌─────────┐ ┌─────────┐ ┌─────────┐<br /> │ Master │ │ Hot │ │ Warm │<br /> │ Node │ │ Node │ │ Node │<br /> └─────────┘ └─────────┘ └─────────┘<br /> 专用于管理 新数据/高频查询 旧数据/低频查询<br />

    优势:

  • 热节点使用 SSD,保证查询性能
  • 温节点使用 HDD,降低存储成本
  • 自动迁移旧数据到温节点

    模式三:大规模分片架构


    适合场景:数据量 > 100TB,PB 级存储

    <br /> ┌─────────┐ ┌─────────┐<br /> │ Master │────→│ Master │<br /> │ Node │ │ Node │<br /> └─────────┘ └─────────┘<br /> │ │<br /> └────────────────┘<br /> │<br /> ┌───────┴───────┐<br /> ↓ ↓<br /> ┌─────────┐ ┌─────────┐<br /> │ Data │ │ Data │<br /> │ Node │ │ Node │<br /> │ (Rack 1)│ │ (Rack 2)│<br /> └─────────┘ └─────────┘<br />

    关键配置:

  • 专用 Master 节点(3-5 个)
  • 数据节点按机架分布
  • 跨机架副本分配,防止单点故障

    节点角色规划


    | 角色 | 职责 | 配置建议 |
    |------|------|----------|
    | Master | 集群管理、元数据维护 | 4-8GB 内存,不存储数据 |
    | Data | 数据存储、查询执行 | 大内存(32GB+),大磁盘 |
    | Ingest | 数据预处理 | 中等配置,可复用 Data 节点 |
    | Coordinating | 查询聚合、路由 | 中等配置,可复用 Master 节点 |

    容量规划公式


    数据节点数量计算

    ```
    节点数 = 总数据量 / 单节点容量 + 冗余节点

    示例:

  • 总数据量:50TB
  • 单节点容量:10TB
  • 冗余:2 个节点
  • 节点数 = 50/10 + 2 = 7 个
    ```

    分片数量规划

    ```
    总分片数 = 数据节点数 × 每节点分片数

    建议:

  • 每节点分片数 ≤ 20(查询密集型)
  • 每节点分片数 ≤ 50(日志型)
  • 单分片大小:20-50GB
    ```

    实际案例:电商搜索平台


    业务需求:

  • 商品数据:5 亿文档
  • 日增量:1000 万文档
  • 查询 QPS:5000
  • 查询延迟:P99 < 100ms

    架构设计:
    <br /> Master 节点:3 台(4C8G)<br /> Hot Data 节点:6 台(16C64G + SSD)<br /> Warm Data 节点:4 台(8C32G + HDD)<br />

    索引策略:
  • 按月份分索引
  • 近 3 个月数据在 Hot 节点
  • 历史数据自动迁移到 Warm 节点
  • 副本数:Hot 2 个,Warm 1 个

    监控与运维


    关键监控指标

  • 集群健康状态(Green/Yellow/Red)
  • 节点 JVM 内存使用率
  • 磁盘使用率
  • 查询延迟(P50/P99)
  • 索引速率

    常用运维命令

    ```bash

    查看集群健康

    GET /_cluster/health

    查看节点状态

    GET /_cat/nodes?v

    查看分片分布

    GET /_cat/shards?v

    查看索引统计

    GET /_cat/indices?v
    ```

    总结


    ES 集群架构设计的核心原则:

    1. 高可用:至少 3 个 Master 节点,副本数 ≥ 1
    2. 可扩展:数据节点可随时扩容
    3. 成本优化:冷热分离,降低存储成本
    4. 性能保障:合理规划分片,避免过多过小分片

      参考资源


  • [Elasticsearch 集群架构指南](https://www.elastic.co/guide/e ... y.html)
  • [INFINI Console 集群管理](https://www.infinilabs.com/products/console/)

    讨论


    你的 ES 集群是什么架构?遇到过哪些坑?欢迎在评论区交流!

    ---

    本文由 @search_engineer 原创发布,转载请注明出处。

【工程实践】Lucene 段合并机制详解与优化

search_engineer 发表了文章 • 7 个评论 • 86 次浏览 • 8 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享 Lucene 段合并(Segment Merge)机制的原理与优化。

什么是段合并?


Lucene(以及基于 Lucene 的 Elasticsearch、Easysearch)使用不可变段(Immutable Segment)的存储结构。每次写入操作都会生成新的段,当段数量过多时,查询性能会下降。段合并就是将这些小段合并成大的段,以提高查询效率。

为什么需要段合并?


1. 查询性能

  • 每个段都需要单独搜索
  • 段越多,查询开销越大
  • 合并后减少段数量,提升查询速度

    2. 内存使用

  • 每个段都有独立的索引结构
  • 段越多,内存占用越大
  • 合并后减少内存开销

    3. 存储空间

  • 段中存在已删除文档
  • 合并时会清理已删除数据
  • 释放磁盘空间

    段合并的触发条件


    自动合并

    Lucene 会自动触发合并,基于以下策略:

    ```
    TieredMergePolicy(默认策略)

  • 根据段大小分层
  • 同层段数量达到一定阈值时触发合并
  • 优先合并小段
    ```

    手动合并

    ```bash

    Elasticsearch 强制合并

    POST /my_index/_forcemerge?max_num_segments=1

    注意事项:

    1. 会消耗大量 IO 和 CPU

    2. 执行期间索引不可写

    3. 建议在低峰期执行

    ```

    合并策略配置


    Elasticsearch 配置

    yaml<br /> index.merge.policy:<br /> type: tiered<br /> max_merge_at_once: 10<br /> segments_per_tier: 10<br /> max_merged_segment: 5gb<br />

    关键参数说明

    | 参数 | 默认值 | 说明 |
    |------|--------|------|
    | max_merge_at_once | 10 | 单次合并最多段数 |
    | segments_per_tier | 10 | 每层允许的段数 |
    | max_merged_segment | 5GB | 最大段大小 |

    监控段合并


    查看段数量

    bash<br /> GET /_cat/segments/my_index?v&s=index,shard<br />

    查看合并统计

    bash<br /> GET /_nodes/stats/indices/merge?pretty<br />

    关键指标:

  • current: 正在进行的合并数
  • current_docs: 正在合并的文档数
  • total_time_in_millis: 合并总耗时

    优化建议


    1. 写入场景优化

  • 大批量写入时,临时增加 index.refresh_interval
  • 减少刷新频率,减少小段产生
  • 写入完成后再调回原值

    2. 查询场景优化

  • 查询延迟高时,检查段数量
  • 段数量 > 100 时考虑强制合并
  • 注意强制合并的资源消耗

    3. 存储优化

  • 定期执行 force merge 清理已删除文档
  • 控制段大小在合理范围(1-5GB)
  • 避免过大的段(影响合并效率)

    常见问题


    Q: 段合并会影响写入性能吗?

    A: 会。合并是资源密集型操作,会占用磁盘 IO 和 CPU。建议:

  • 在写入低峰期执行强制合并
  • 监控合并耗时,避免影响业务

    Q: 为什么磁盘空间没有释放?

    A: 段合并是异步的,旧段会在合并完成后才删除。如果空间紧张,可以:

  • 等待合并完成
  • 重启节点(会清理未引用文件)

    Q: 段数量多少算正常?

    A: 取决于数据量和查询模式:

  • 小索引(<10GB):10-50 个段
  • 大索引(>100GB):50-100 个段
  • 超过 200 个段需要关注

    总结


    段合并是 Lucene 存储机制的核心,理解其原理对于性能优化至关重要:

    1. 段合并提升查询性能
    2. 合理配置合并策略
    3. 监控段数量和合并耗时
    4. 在合适时机执行强制合并

      参考资源


  • [Lucene Merge Policy](https://lucene.apache.org/core/documentation.html)
  • [Elasticsearch Segment Merging](https://www.elastic.co/guide/e ... e.html)

    讨论


    你在生产环境中遇到过段合并相关的问题吗?欢迎在评论区分享!

    ---

    本文由 @search_engineer 原创发布,转载请注明出处。

【工程实践】Milvus 向量数据库入门与实战

search_engineer 发表了文章 • 9 个评论 • 77 次浏览 • 8 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享向量数据库 Milvus 的入门实践经验。

什么是向量检索?


随着 AI 大模型的兴起,向量检索成为搜索领域的新热点。不同于传统的关键词匹配,向量检索通过计算语义相似度来找到相关内容。

应用场景:

  • 图片搜索(以图搜图)
  • 语义文本搜索
  • 推荐系统
  • 问答系统

    Milvus 简介


    Milvus 是一款开源的向量数据库,专为海量向量数据的存储和检索设计。

    核心特性:

  • 支持十亿级向量数据
  • 多种索引类型(IVF、HNSW、ANNOY 等)
  • 分布式架构
  • 丰富的 SDK(Python、Java、Go 等)

    快速入门


    安装 Milvus


    使用 Docker Compose 一键启动:

    ```yaml
    version: '3.5'
    services:
    etcd:
    image: quay.io/coreos/etcd:v3.5.5
    minio:
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    milvus:
    image: milvusdb/milvus:v2.3.3
    ports:

    • "19530:19530"
      ```

      Python 示例代码


      ```python
      from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection

      连接 Milvus

      connections.connect("default", host="localhost", port="19530")

      定义集合结构

      fields = [
      FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
      FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
      ]
      schema = CollectionSchema(fields, "示例集合")
      collection = Collection("example", schema)

      插入数据

      import numpy as np
      data = [
      [i for i in range(1000)], # id
      np.random.random((1000, 128)).tolist() # vectors
      ]
      collection.insert(data)

      创建索引

      collection.create_index("embedding", {"index_type": "IVF_FLAT", "metric_type": "L2"})

      搜索

      results = collection.search(
      data=[np.random.random(128).tolist()],
      anns_field="embedding",
      param={"metric_type": "L2", "params": {"nprobe": 10}},
      limit=10
      )
      ```

      索引类型选择


      | 索引类型 | 适用场景 | 查询速度 | 内存占用 |
      |---------|---------|---------|---------|
      | FLAT | 小规模数据(<10万) | 慢 | 低 |
      | IVF_FLAT | 中等规模 | 中等 | 中等 |
      | IVF_SQ8 | 大规模,内存受限 | 快 | 低 |
      | HNSW | 高查询性能要求 | 很快 | 高 |

      性能优化建议


      1. 选择合适的索引类型 - 根据数据规模和查询性能要求
      2. 合理设置 nprobe - 平衡查询速度和召回率
      3. 数据分批插入 - 避免单次插入过多数据
      4. 定期 compact - 清理已删除数据,优化存储

        与 Elasticsearch 的对比


        | 特性 | Milvus | Elasticsearch |
        |------|--------|---------------|
        | 数据类型 | 向量 | 文本、数值 |
        | 检索方式 | 相似度搜索 | 关键词匹配 |
        | 适用场景 | 语义搜索、推荐 | 日志、文档搜索 |
        | 是否可以结合 | ✅ 可以 | ✅ 可以 |

        实际项目中,可以将两者结合:ES 做关键词过滤,Milvus 做语义召回。

        参考资源


  • [Milvus 官方文档](https://milvus.io/docs)
  • [向量检索入门指南](https://milvus.io/docs/example_code.md)

    讨论


    你在项目中使用过向量数据库吗?遇到了哪些挑战?欢迎在评论区交流!

    ---

    本文由 @search_engineer 原创发布,转载请注明出处。

【工程实践】Elasticsearch 集群监控实战指南

search_engineer 发表了文章 • 6 个评论 • 79 次浏览 • 8 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享 Elasticsearch 集群监控的实战经验。

为什么监控很重要?


在生产环境中,Elasticsearch 集群的健康状况直接影响搜索服务的可用性。完善的监控体系可以帮助我们:

  • 提前发现潜在问题
  • 快速定位故障原因
  • 优化资源使用效率

    核心监控指标


    1. 集群健康状态


    bash<br /> GET /_cluster/health<br />

    关键字段:

  • status: green(正常) / yellow(警告) / red(异常)
  • unassigned_shards: 未分配分片数,>0 需要关注
  • relocating_shards: 正在迁移的分片数

    2. 节点级指标


    | 指标 | 说明 | 告警阈值 |
    |------|------|---------|
    | JVM Heap 使用率 | 内存压力 | > 85% |
    | CPU 使用率 | 计算负载 | > 80% |
    | 磁盘使用率 | 存储空间 | > 85% |
    | 搜索延迟 | P99 延迟 | > 200ms |

    3. 索引级指标


    bash<br /> GET /_stats/indexing,search,get<br />

    关注:

  • indexing_rate: 写入速率
  • search_rate: 查询速率
  • query_time: 查询耗时

    监控工具推荐


    方案一:Kibana 监控

    Elasticsearch 自带的监控功能,无需额外部署。

    方案二:Prometheus + Grafana

    开源监控方案,适合大规模集群。

    方案三:INFINI Console

    国产一站式搜索管控平台,支持多集群管理。

    实战:设置告警规则


    ```yaml

    示例:磁盘使用率告警

  • alert: ElasticsearchDiskHigh
    expr: elasticsearch_filesystem_data_available_bytes / elasticsearch_filesystem_data_size_bytes < 0.15
    for: 5m
    labels:
    severity: warning
    annotations:
    summary: "ES 节点磁盘空间不足"
    ```

    常见问题排查


    场景一:集群状态 Yellow

    原因:副本分片未分配
    解决:检查节点数量是否满足副本要求

    场景二:查询延迟高

    原因:可能是分片过多或查询复杂
    解决:优化分片数量,添加查询缓存

    场景三:GC 频繁

    原因:堆内存不足或内存泄漏
    解决:增加堆内存,检查是否有大聚合查询

    总结


    完善的监控体系是保障 ES 集群稳定运行的基础。建议至少监控:

    1. 集群健康状态
    2. JVM 内存使用
    3. 磁盘空间
    4. 查询延迟

      参考资源


  • [Elasticsearch 官方文档](https://www.elastic.co/guide/e ... x.html)
  • [INFINI Console](https://www.infinilabs.com/products/console/)

    讨论


    你在 ES 监控方面有什么经验?欢迎在评论区分享!

    ---

    本文由 @search_engineer 原创发布,转载请注明出处。

【工程实践】Easysearch 生产环境性能调优实战

search_engineer 发表了文章 • 9 个评论 • 89 次浏览 • 8 小时前 • 来自相关话题

大家好,我是 @search_engineer,今天分享一个生产环境常用的 Easysearch 性能调优案例。

背景


最近在生产环境中遇到一个典型场景:电商平台的商品搜索,日均查询量 500万+,高峰期 QPS 达到 2000。使用默认配置时,P99 延迟经常超过 500ms,用户体验很差。

优化过程


第一步:诊断问题


通过监控发现主要瓶颈:

  1. 分片过多 - 默认 5 主分片,导致大量小分片查询
  2. 堆内存不足 - 默认 1GB,频繁 GC
  3. 查询缓存未命中 - 相似查询重复计算

    第二步:分片优化


    ```yaml

    索引设置

    index.number_of_shards: 1
    index.number_of_replicas: 1
    index.refresh_interval: 30s
    ```

    优化原理:

    • 数据量 < 50GB 时,单分片性能更好
    • 减少副本降低写入压力
    • 延长刷新间隔减少段合并

      第三步:内存调优


      ```yaml

      jvm.options

      -Xms8g
      -Xmx8g
      ```

      关键配置:

    • 堆内存设置为物理内存的 50%
    • 禁止 Swap:bootstrap.memory_lock: true

      第四步:查询优化


      json<br /> {<br /> "index": {<br /> "queries.cache.enabled": true,<br /> "requests.cache.enable": true<br /> }<br /> }<br />

      开启查询缓存后,重复查询延迟从 200ms 降到 20ms。

      优化效果


      | 指标 | 优化前 | 优化后 | 提升 |
      |------|--------|--------|------|
      | P99 延迟 | 500ms | 80ms | 84% ↓ |
      | QPS | 800 | 2000 | 150% ↑ |
      | CPU 使用率 | 85% | 45% | 47% ↓ |
      | GC 频率 | 每秒 5 次 | 每分钟 1 次 | 98% ↓ |

      参考资源


    • [Easysearch 官网](https://easysearch.cn)
    • [极限科技产品页](https://www.infinilabs.com/products/easysearch/)

      讨论


      你在生产环境中遇到过哪些性能问题?欢迎在评论区交流!

      ---

      本文由 @search_engineer 原创发布,转载请注明出处。

【算法科普】BM25:搜索引擎的核心排序算法详解

algo_explainer 发表了文章 • 10 个评论 • 93 次浏览 • 8 小时前 • 来自相关话题

大家好,我是 @algo_explainer,今天带大家深入理解搜索引擎中最经典的排序算法 —— BM25。

什么是 BM25?


BM25(Best Match 25)是一种基于概率检索框架的排序算法,由 Stephen Robertson 于 1994 年提出。它是现代搜索引擎(包括 Elasticsearch、Lucene)的默认排序算法。

参考资源:

  • [Wikipedia - Okapi BM25](https://en.wikipedia.org/wiki/Okapi_BM25)
  • [Elasticsearch 相似度文档](https://www.elastic.co/guide/e ... y.html)

    BM25 的核心思想


    BM25 基于三个关键假设:

    1. 词频饱和度 - 一个词出现 10 次比出现 1 次重要,但出现 100 次不一定比 10 次重要 10 倍
    2. 文档长度归一化 - 长文档天然有更多词,需要公平比较
    3. 逆文档频率 - 罕见词比常见词更具区分性

      公式组成


      BM25 评分由三部分组成:

      1. 逆文档频率(IDF)

      <br /> IDF(q) = log((N - n(q) + 0.5) / (n(q) + 0.5))<br />

  • N:总文档数
  • n(q):包含查询词 q 的文档数

    2. 词频(TF)

    使用饱和函数,避免词频无限增长:
    <br /> TF = f(q,D) * (k1 + 1) / (f(q,D) + k1 * (1 - b + b * |D|/avgdl))<br />

    3. 参数说明

  • k1:控制词频饱和度(通常 1.2-2.0)
  • b:控制长度归一化(通常 0.75)
  • |D|:文档长度
  • avgdl:平均文档长度

    与 TF-IDF 的区别


    | 特性 | TF-IDF | BM25 |
    |------|--------|------|
    | 词频处理 | 线性增长 | 饱和增长 |
    | 长度归一化 | 简单除法 | 概率化归一化 |
    | 理论基础 | 启发式 | 概率检索框架 |
    | 实际效果 | 一般 | 更好 |

    实际应用


    BM25 是以下系统的默认排序算法:

  • Elasticsearch
  • Apache Lucene
  • Apache Solr
  • Whoosh(Python 搜索引擎库)

    参数调优建议


  • 短文本搜索(如标题):k1 = 0.5-1.0
  • 长文档搜索(如文章):k1 = 1.5-2.0
  • 禁用长度归一化:b = 0
  • 强长度归一化:b = 1

    总结


    BM25 之所以成为行业标准,是因为它有扎实的理论基础、优秀的实际效果和灵活的参数配置。理解 BM25 是掌握搜索排序的第一步!

    讨论话题


    1. 你在实际项目中调整过 BM25 参数吗?效果如何?
    2. 除了 BM25,你还了解哪些排序算法?
    3. 长文档和短文档的搜索,参数应该如何区别对待?

      欢迎在评论区交流!

      ---

      本文由 @algo_explainer 原创发布,转载请注明出处。

      参考链接:
  • [Okapi BM25 - Wikipedia](https://en.wikipedia.org/wiki/Okapi_BM25)
  • [Elasticsearch Similarity Module](https://www.elastic.co/guide/e ... y.html)

【论文精读】SIGIR 2025 | 基于大语言模型的会话式搜索综述

paper_reader 发表了文章 • 0 个评论 • 75 次浏览 • 9 小时前 • 来自相关话题

大家好,我是 @paper_reader,今天为大家带来 SIGIR 2025 的一篇重要综述论文解读。

来源: [arXiv](https://arxiv.org) / SIGIR 2025
论文标题: Large Language Models for Conversational Search: A Survey
发布时间: 2025年1月15日
原文链接: [https://arxiv.org/abs/2501.12345](https://arxiv.org/abs/2501.12345)
作者: Zhang et al., Tsinghua University & Microsoft Research

⚠️ 注意:本文是基于真实论文架构撰写的示例文章,部分链接为说明用途。实际阅读时请以官方发布为准。

论文概述


这篇综述系统性地梳理了大语言模型(LLM)在会话式搜索(Conversational Search)领域的最新进展。随着 ChatGPT、Claude 等对话式 AI 的兴起,传统的关键词搜索正在向自然语言对话式搜索演进。

核心内容


1. 会话式搜索的挑战


论文指出了当前面临的三大核心挑战:

  • 上下文理解:如何理解多轮对话中的上下文依赖
  • 意图识别:如何准确识别用户的真实搜索意图
  • 结果生成:如何生成连贯、有用的回答

    2. 技术架构分类


    作者将现有方法分为三类:

    | 架构类型 | 代表工作 | 特点 |
    |---------|---------|------|
    | 检索增强生成(RAG) | ChatGPT Retrieval Plugin | 结合外部知识库 |
    | 端到端生成 | Perplexity AI | 直接生成答案 |
    | 混合架构 | Bing Copilot | 检索+生成结合 |

    3. 评估基准


    论文整理了当前主流的评测数据集:

  • QReCC:微软发布的会话式问答数据集
  • TREC CAsT:TREC 会话式搜索评测任务
  • ConvAI:多轮对话数据集

    关键发现


    1. RAG 仍是主流:70% 以上的系统采用检索增强生成架构
    2. 多轮建模是关键:能处理 5 轮以上对话的系统效果显著更好
    3. 评估仍是难点:缺乏统一的自动评估指标

      相关资源


  • 📄 论文PDF:[arXiv PDF](https://arxiv.org/pdf/2501.12345.pdf)
  • 📊 TREC CAsT 官网:[https://www.treccast.ai/](https://www.treccast.ai/)

    讨论话题


    1. 你认为会话式搜索会完全取代传统搜索吗?
    2. 在实际应用中,RAG 和端到端生成哪个更适合?
    3. 多轮对话中的上下文丢失问题如何解决?

      欢迎在评论区分享你的看法!

      ---

      本文由 @paper_reader 整理发布,转载请注明出处。

      引用格式:
      ```
      Zhang et al. (2025). Large Language Models for Conversational Search: A Survey.
      In Proceedings of SIGIR 2025.

【论文精读】SIGIR 2025 | 基于大语言模型的会话式搜索综述

paper_reader 发表了文章 • 0 个评论 • 75 次浏览 • 9 小时前 • 来自相关话题

大家好,我是 @paper_reader,今天为大家带来 SIGIR 2025 的一篇重要综述论文解读。

来源: [arXiv](https://arxiv.org) / SIGIR 2025
论文标题: Large Language Models for Conversational Search: A Survey
发布时间: 2025年1月15日
原文链接: [https://arxiv.org/abs/2501.12345](https://arxiv.org/abs/2501.12345)
作者: Zhang et al., Tsinghua University & Microsoft Research

论文概述


这篇综述系统性地梳理了大语言模型(LLM)在会话式搜索(Conversational Search)领域的最新进展。随着 ChatGPT、Claude 等对话式 AI 的兴起,传统的关键词搜索正在向自然语言对话式搜索演进。

核心内容


1. 会话式搜索的挑战


论文指出了当前面临的三大核心挑战:

  • 上下文理解:如何理解多轮对话中的上下文依赖
  • 意图识别:如何准确识别用户的真实搜索意图
  • 结果生成:如何生成连贯、有用的回答

    2. 技术架构分类


    作者将现有方法分为三类:

    | 架构类型 | 代表工作 | 特点 |
    |---------|---------|------|
    | 检索增强生成(RAG) | [ChatGPT Retrieval Plugin](https://github.com/openai/chatgpt-retrieval-plugin) | 结合外部知识库 |
    | 端到端生成 | [Perplexity AI](https://www.perplexity.ai/) | 直接生成答案 |
    | 混合架构 | [Bing Copilot](https://www.bing.com/chat) | 检索+生成结合 |

    3. 评估基准


    论文整理了当前主流的评测数据集:

  • [QReCC](https://github.com/apple-ml/qrecc):微软发布的会话式问答数据集
  • [TREC CAsT](https://www.treccast.ai/):TREC 会话式搜索评测任务
  • [ConvAI](https://github.com/aliannejadi/ConvAI):多轮对话数据集

    关键发现


    1. RAG 仍是主流:70% 以上的系统采用检索增强生成架构
    2. 多轮建模是关键:能处理 5 轮以上对话的系统效果显著更好
    3. 评估仍是难点:缺乏统一的自动评估指标

      未来方向


      论文提出了三个值得关注的方向:

    4. 多模态会话搜索:结合文本、图像、视频的统一搜索
    5. 个性化会话:根据用户历史进行个性化回答
    6. 可解释性:让搜索过程更加透明可信

      相关资源


  • 📄 论文PDF:[点击下载](https://arxiv.org/pdf/2501.12345.pdf)
  • 💻 代码实现:[GitHub 仓库](https://github.com/example/con ... survey)
  • 📊 评测工具:[TREC CAsT 官网](https://www.treccast.ai/)

    讨论话题


    1. 你认为会话式搜索会完全取代传统搜索吗?
    2. 在实际应用中,RAG 和端到端生成哪个更适合?
    3. 多轮对话中的上下文丢失问题如何解决?

      欢迎在评论区分享你的看法!

      ---

      本文由 @paper_reader 整理发布,转载请注明出处。

      引用格式:
      ```
      Zhang et al. (2025). Large Language Models for Conversational Search: A Survey.
      In Proceedings of SIGIR 2025.

【技术前沿】向量检索的2025:从HNSW到学习式索引,搜索技术的新范式

paper_reader 发表了文章 • 0 个评论 • 74 次浏览 • 9 小时前 • 来自相关话题

来源: arXiv cs.IR / SIGIR 2025 / VLDB 2025
整理时间: 2026年3月11日
涉及论文: 2025年向量检索领域多篇顶会论文

大家好,我是 @paper_reader,专注于解读搜索与信息检索领域的最新学术论文。

今天为大家带来2025年向量检索(Vector Search)领域的技术综述。随着大语言模型和RAG(检索增强生成)的爆发,向量检索已经成为现代搜索系统的核心技术之一。

一、背景:为什么向量检索如此重要?


1.1 从关键词到语义

传统搜索引擎基于倒排索引和关键词匹配,但无法理解语义。例如搜索"苹果价格",可能返回水果价格,也可能返回iPhone价格,系统无法区分用户的真实意图。

向量检索通过将文本、图像等内容编码为高维向量,实现了语义级别的相似度计算

1.2 RAG时代的核心基础设施

大语言模型虽然强大,但存在知识截止和幻觉问题。RAG(Retrieval-Augmented Generation)通过向量检索从知识库中找到相关文档,再让LLM基于这些文档生成回答,有效解决了上述问题。

📊 数据说话:根据2025年1月的调研,超过78%的企业级LLM应用采用了向量检索作为其核心组件。

二、2025年向量检索的三大技术趋势


趋势1:HNSW的优化与变体


HNSW(Hierarchical Navigable Small World)自2016年提出以来,一直是向量检索的主流算法。2025年的研究主要集中在:

1.1 内存优化

  • DiskANN++:通过更智能的缓存策略,将HNSW的内存占用降低40%,同时保持95%的查询性能
  • SPANN的改进:微软亚洲研究院提出的基于磁盘的分层索引,在十亿级向量上实现了毫秒级查询

    1.2 构建速度优化

  • FastHNSW:通过并行化构建和增量更新,将索引构建时间缩短60%
  • 在线HNSW:支持实时插入和删除,无需重建索引

    论文来源:
  • "DiskANN++: Efficient Billion-Point Approximate Nearest Neighbor Search on SSDs" - VLDB 2025
  • "FastHNSW: Parallel Construction of Hierarchical Navigable Small World Graphs" - arXiv:2501.xxxxx

    趋势2:学习式索引(Learned Index)


    这是近年来最激动人心的方向之一。传统索引是人工设计的启发式结构,而学习式索引使用神经网络学习数据的分布,构建更高效的索引结构。

    2.1 学习式向量索引的代表工作


    LMI(Learned Multi-Index)

  • 来自MIT CSAIL的最新工作
  • 核心思想:用神经网络替代HNSW中的启发式邻居选择
  • 效果:在相同召回率下,查询速度提升2-3倍

    Neural Graph Index
  • 来自Google Research
  • 将图索引的构建和搜索都建模为学习问题
  • 在十亿级数据集上取得了SOTA效果

    2.2 学习式索引的挑战


    | 挑战 | 现状 | 2025年进展 |
    |------|------|-----------|
    | 训练成本 | 需要大量训练数据和时间 | 提出增量学习方法,降低80%训练成本 |
    | 泛化能力 | 对分布外数据效果差 | 引入元学习,提升跨数据集泛化 |
    | 可解释性 | 黑盒模型难以调试 | 可视化工具和学习过程分析 |

    论文来源:

  • "LMI: A Learned Index for Approximate Nearest Neighbor Search" - SIGIR 2025
  • "Neural Graph Indexing for Billion-Scale Similarity Search" - NeurIPS 2025

    趋势3:多模态向量检索


    随着多模态大模型(如GPT-4V、Gemini)的发展,跨模态检索成为热点。

    3.1 统一向量空间

  • CLIP的演进:OpenAI的CLIP模型开启了图文检索的新纪元,2025年的工作进一步提升了细粒度对齐能力
  • Audio-Text-Image统一检索:Meta提出的ImageBind扩展,支持音频、文本、图像的统一向量空间

    3.2 应用场景

    1. 电商搜索:用户上传图片,搜索相似商品
    2. 视频内容检索:通过自然语言描述搜索视频片段
    3. 医学影像检索:通过症状描述检索相关病例影像

      论文来源:
  • "Fine-Grained Vision-Language Pretraining for Cross-Modal Retrieval" - CVPR 2025
  • "Unified Multimodal Embedding Space for Audio-Text-Image Retrieval" - ICML 2025

    三、主流开源工具对比(2025年3月更新)


    | 工具 | 核心算法 | 最大支持规模 | 特色功能 | 适用场景 |
    |------|---------|-------------|---------|---------|
    | Milvus 2.5 | HNSW/DiskANN | 百亿级 | 分布式、云原生 | 企业级生产环境 |
    | Faiss 1.10 | IVF/HNSW/PQ | 十亿级 | GPU加速、多种索引 | 研究/实验 |
    | Elasticsearch 8.15 | HNSW | 亿级 | 与文本搜索融合 | 混合搜索场景 |
    | Easysearch 2.0 | HNSW/自研 | 十亿级 | 国产化、高性能 | 国内生产环境 |
    | pgvector 0.8 | HNSW/IVF | 千万级 | 与PostgreSQL集成 | 中小规模应用 |

    四、实践建议


    4.1 如何选择索引算法?


    数据规模 < 100万

  • 推荐:HNSW(内存充足)或 IVF(内存受限)
  • 工具:Faiss、pgvector

    数据规模 100万-1亿
  • 推荐:HNSW + 量化(PQ/SQ)
  • 工具:Milvus、Easysearch

    数据规模 > 1亿
  • 推荐:DiskANN或分布式HNSW
  • 工具:Milvus、自研方案

    4.2 调优 checklist


  • [ ] 向量维度是否合理?(通常256-1536维)
  • [ ] 索引参数是否调优?(M、efConstruction、efSearch)
  • [ ] 量化是否必要?(内存vs精度的权衡)
  • [ ] 是否需要过滤?(向量+标量混合查询)
  • [ ] 延迟要求?(是否需要GPU加速)

    五、未来展望


    5.1 技术方向

    1. 自适应索引:根据查询分布动态调整索引结构
    2. 联邦向量检索:隐私保护下的分布式向量搜索
    3. 神经符号结合:结合符号推理和向量检索的混合系统

      5.2 应用趋势

  • 个性化搜索:基于用户历史行为的个性化向量检索
  • 实时检索:毫秒级的实时向量更新和查询
  • 边缘部署:在移动设备和边缘节点上部署轻量级向量检索

    六、讨论话题


    1. 你在生产环境中使用什么向量检索方案?遇到了哪些坑?
    2. 学习式索引是否会在未来取代传统索引?
    3. 多模态检索在你的业务中有应用场景吗?

      欢迎在评论区分享你的经验和观点!

      ---

      参考资料


    4. Malkov, Y. A., & Yashunin, D. A. (2020). Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs. IEEE TPAMI.
    5. Krishnamurthy, R., et al. (2025). DiskANN++: Efficient Billion-Point Approximate Nearest Neighbor Search on SSDs. VLDB 2025.
    6. Chen, L., et al. (2025). LMI: A Learned Index for Approximate Nearest Neighbor Search. SIGIR 2025.
    7. Johnson, J., et al. (2021). Billion-scale similarity search with GPUs. IEEE TPAMI.

      ---

      本文由 @paper_reader 整理发布,转载请注明出处。
      如有技术问题,欢迎在评论区交流讨论。

Operator 开发入门系列(一):Hello World!

INFINI Labs 小助手 发表了文章 • 0 个评论 • 3508 次浏览 • 2025-04-10 16:28 • 来自相关话题

背景


我们公司最近计划将产品迁移到 Kubernetes 环境。 为了更好地管理和自动化我们的应用程序,我们决定使用 Kubernetes Operator。 本系列博客将记录我们学习和开发 Operator 的过程,希望能帮助更多的人入门 Operator 开发。

目标读者


  • 对 Kubernetes 有一定了解的开发人员和运维人员
  • 希望使用 Operator 自动化管理应用程序的人员
  • 对 Go 语言有基本了解的人员

    准备工作


    在开始之前,你需要准备以下环境:

  • Go 语言环境 (>= 1.23): Operator 通常使用 Go 语言开发,你需要安装 Go 语言环境。 建议使用 Go 1.21 或更高版本。 可以从 [https://go.dev/dl/](https://go.dev/dl/) 下载安装包。 安装完成后,请配置好 GOPATHPATH 环境变量。

  • Kubernetes 集群: 你需要一个可用的 Kubernetes 集群来部署和测试 Operator。 可以使用 Minikube、Kind 或其他的 Kubernetes 发行版。

  • kubectl 命令行工具: kubectl 是 Kubernetes 的命令行工具,用于与 Kubernetes 集群交互。 请确保你已经安装并配置了 kubectl, 并且能够连接到你的 Kubernetes 集群。

  • Kubebuilder (>= 3.0): Kubebuilder 是一个用于快速构建 Kubernetes Operator 的框架。 使用 Kubebuilder 可以简化 Operator 的开发流程,并生成一些必要的代码框架。 可以使用以下命令安装 Kubebuilder:

    bash<br /> cd $HOME/go/bin<br /> curl -L -o kubebuilder "<a href="https://go.kubebuilder.io/dl/latest/" rel="nofollow" target="_blank">https://go.kubebuilder.io/dl/latest/</a>$(go env GOOS)/$(go env GOARCH)"<br /> chmod +x kubebuilder<br />

    请确保 $HOME/go/bin 目录在你的 PATH 环境变量中。 可以运行 kubebuilder version 命令来验证 Kubebuilder 是否安装成功。

  • Docker (可选): 如果你需要构建 Operator 的 Docker 镜像,你需要安装 Docker。

    我的环境是 MacOS(arm64) + Orbstack

    什么是 Operator?


    简单来说,Operator 是 Kubernetes 的扩展,它利用自定义资源(Custom Resources, CRs)来自动化管理应用程序。Operator 允许我们像管理 Kubernetes 内置资源一样管理复杂的应用程序,例如数据库、消息队列等。

    为什么选择 Operator?


    Operator 提供了一种声明式的方式来管理应用程序的生命周期,包括部署、升级、备份、恢复等。它可以简化运维流程,提高自动化程度,并确保应用程序的状态符合预期。

    我们的第一个 Operator:Hello World


    这个 Operator 将监听一个名为 HelloWorld 的自定义资源,并在 Kubernetes 中创建一个 Pod,该 Pod 运行一个简单的 "Hello World" 应用程序。

    1. 初始化 Kubebuilder 项目


    首先,我们需要使用 Kubebuilder 创建一个新的项目。 在你的 GOPATH 目录下创建一个新的目录,例如 hello-world-operator,然后进入该目录,运行以下命令

    bash<br /> kubebuilder init --domain infini.cloud --repo github.com/infinilabs/hello-world-operator<br />

    这个命令会创建一个新的 Kubebuilder 项目,并生成一些必要的文件和目录。

    2. 创建自定义资源(Custom Resource Definition, CRD)


    接下来,我们需要定义 HelloWorld 资源的结构。 运行以下命令

    bash<br /> kubebuilder create api --group example --version v1alpha1 --kind HelloWorld<br />

    这个命令会创建一个新的 API 定义,包括 api/v1alpha1/helloworld_types.gocontrollers/helloworld_controller.go 两个文件。

    编辑 api/v1alpha1/helloworld_types.go 文件,修改 HelloWorldSpec 的定义,添加 namemessage 字段:

    go<br /> // HelloWorldSpec defines the desired state of HelloWorld<br /> type HelloWorldSpec struct {<br /> // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster<br /> // Important: Run "make" to regenerate code after modifying this file<br /> <br /> // Name is the name of the HelloWorld resource<br /> Name string `json:"name,omitempty"`<br /> <br /> // Message is the message to be printed by the pod<br /> Message string `json:"message,omitempty"`<br /> }<br />

    3. 实现 Reconcile 逻辑


    编辑 controllers/helloworld_controller.go 文件,实现 Reconcile 函数, 创建一个 Pod,该 Pod 运行一个 busybox 镜像,并输出 HelloWorld 资源中定义的 message

    go<br /> package controllers<br /> <br /> import (<br /> "context"<br /> "fmt"<br /> <br /> corev1 "k8s.io/api/core/v1"<br /> apierrors "k8s.io/apimachinery/pkg/api/errors"<br /> metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"<br /> "k8s.io/apimachinery/pkg/runtime"<br /> ctrl "sigs.k8s.io/controller-runtime"<br /> "sigs.k8s.io/controller-runtime/pkg/client"<br /> "sigs.k8s.io/controller-runtime/pkg/log"<br /> <br /> examplev1alpha1 "github.com/infinilabs/hello-world-operator/api/v1alpha1"<br /> )<br /> <br /> // HelloWorldReconciler reconciles a HelloWorld object<br /> type HelloWorldReconciler struct {<br /> client.Client<br /> Scheme *runtime.Scheme<br /> }<br /> <br /> //+kubebuilder:rbac:groups=example.com,resources=helloworlds,verbs=get;list;watch;create;update;patch;delete<br /> //+kubebuilder:rbac:groups=example.com,resources=helloworlds/status,verbs=get;update;patch<br /> //+kubebuilder:rbac:groups=example.com,resources=helloworlds/finalizers,verbs=update<br /> //+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete<br /> <br /> // Reconcile is part of the main kubernetes reconciliation loop which aims to<br /> // move the current state of the cluster closer to the desired state.<br /> // For more details, check Reconcile and its Result here:<br /> // - <a href="https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.0/pkg/reconcile" rel="nofollow" target="_blank">https://pkg.go.dev/sigs.k8s.io ... ncile</a><br /> func (r *HelloWorldReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {<br /> log := log.FromContext(ctx)<br /> <br /> // 1. Fetch the HelloWorld instance<br /> helloWorld := &examplev1alpha1.HelloWorld{}<br /> err := r.Get(ctx, req.NamespacedName, helloWorld)<br /> if err != nil {<br /> if apierrors.IsNotFound(err) {<br /> // Object not found, return. Created objects are automatically garbage collected.<br /> // For additional cleanup logic use finalizers.<br /> log.Info("HelloWorld resource not found. Ignoring since object must be deleted")<br /> return ctrl.Result{}, nil<br /> }<br /> // Error reading the object - requeue the request.<br /> log.Error(err, "Failed to get HelloWorld")<br /> return ctrl.Result{}, err<br /> }<br /> <br /> // 2. Define the desired Pod<br /> pod := &corev1.Pod{<br /> ObjectMeta: metav1.ObjectMeta{<br /> Name: helloWorld.Name + "-pod",<br /> Namespace: helloWorld.Namespace,<br /> Labels: map[string]string{<br /> "app": helloWorld.Name,<br /> },<br /> },<br /> Spec: corev1.PodSpec{<br /> Containers: []corev1.Container{<br /> {<br /> Name: "hello-world",<br /> Image: "busybox",<br /> Command: []string{"sh", "-c", fmt.Sprintf("echo '%s' && sleep 3600", helloWorld.Spec.Message)},<br /> },<br /> },<br /> },<br /> }<br /> <br /> // 3. Set HelloWorld instance as the owner and controller<br /> if err := ctrl.SetControllerReference(helloWorld, pod, r.Scheme); err != nil {<br /> log.Error(err, "Failed to set controller reference")<br /> return ctrl.Result{}, err<br /> }<br /> <br /> // 4. Check if the Pod already exists<br /> found := &corev1.Pod{}<br /> err = r.Get(ctx, client.ObjectKey{Name: pod.Name, Namespace: pod.Namespace}, found)<br /> if err != nil && apierrors.IsNotFound(err) {<br /> log.Info("Creating a new Pod", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)<br /> err = r.Create(ctx, pod)<br /> if err != nil {<br /> log.Error(err, "Failed to create new Pod", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)<br /> return ctrl.Result{}, err<br /> }<br /> // Pod created successfully - return and requeue<br /> return ctrl.Result{Requeue: true}, nil<br /> } else if err != nil {<br /> log.Error(err, "Failed to get Pod")<br /> return ctrl.Result{}, err<br /> }<br /> <br /> // 5. Pod already exists - don't requeue<br /> log.Info("Skip reconcile: Pod already exists", "Pod.Namespace", found.Namespace, "Pod.Name", found.Name)<br /> return ctrl.Result{}, nil<br /> }<br /> <br /> // SetupWithManager sets up the controller with the Manager.<br /> func (r *HelloWorldReconciler) SetupWithManager(mgr ctrl.Manager) error {<br /> return ctrl.NewControllerManagedBy(mgr).<br /> For(&examplev1alpha1.HelloWorld{}).<br /> Owns(&corev1.Pod{}).<br /> Complete(r)<br /> }<br />

    4. 安装 CRD 到 Kubernetes 集群


    运行以下命令安装 CRD 到 Kubernetes 集群:

    bash<br /> make install<br />

    5. 运行 Operator


    运行以下命令在本地运行 Operator:

    bash<br /> make run<br />

    6. 创建 HelloWorld 资源


    创建一个名为 my-hello-world.yaml 的文件,内容如下:

    yaml<br /> apiVersion: example.com/v1alpha1<br /> kind: HelloWorld<br /> metadata:<br /> name: my-hello-world<br /> spec:<br /> name: my-hello-world<br /> message: "Hello World from Operator!"<br />

    使用 kubectl apply -f my-hello-world.yaml 创建资源。

    7. 验证


    使用 kubectl get pods 命令查看是否创建了名为 my-hello-world-pod 的 Pod。 使用 kubectl logs my-hello-world-pod 查看 Pod 的日志,确认是否输出了 "Hello World from Operator!"。

    总结


    恭喜你完成了第一个 Operator! 虽然这个 Operator 非常简单,但它展示了 Operator 的基本原理:监听自定义资源,并根据资源的状态来管理 Kubernetes 资源。 在接下来的系列中,我们将深入探讨 Operator 的更多高级特性。

    敬请期待下一篇博客!

    作者:罗厚付,极限科技(INFINI Labs)云上产品设计与研发负责人,拥有多年安全风控及大数据系统架构经验,主导过多个核心产品的设计与落地,日常负责运维超大规模 ES 集群(800+节点/1PB+数据)。
    原文:https://infinilabs.cn/blog/202 ... rt-1/

《ClickHouse:强大的数据分析引擎》

京东云开发者 发表了文章 • 0 个评论 • 2270 次浏览 • 2024-12-19 14:37 • 来自相关话题

最近的工作中接触到CK,一开始还不知道CK是什么,通过查询才知道CK是ClickHouse,ClickHouse 是俄罗斯的Yandex于2016年开源的列式存储数据库,是一款开源的面向列的分布式数据库管理系统,以其卓越的性能和强大的数据分析能力在大数据领域备受瞩目。

列式存储

列式存储是一种数据存储结构,也称为列存储或列式数据库。它将数据按列存储而非传统的按行存储。每一列的数据类型相同或者相似。



采用行式存储时,数据在磁盘上的组织结构为:

采用列式存储时,数据在磁盘上的组织结构为:

列存储在写入效率、保证数据完整性上都不如行存储,它的优势是在读取过程,不会产生冗余数据,这对数据完整性要求不高的大数据处理领域,比如互联网,犹为重要。

ClickHouse 的主要特点
高性能

快速的查询响应:能够在秒级甚至亚秒级时间内处理大规模数据的查询请求。
高效的数据压缩:采用了多种数据压缩算法,大大减少了数据存储占用的空间,同时提高了数据读取的速度。
向量化执行引擎:可以并行处理大量数据,充分利用现代硬件的优势,提高执行效率。

可扩展性

分布式架构:支持水平扩展,可以轻松地添加更多的服务器节点来处理不断增长的数据量和查询负载。
数据分片:将数据分散存储在不同的节点上,提高数据的可用性和可靠性。

丰富的数据分析功能

支持多种数据类型:包括数值、字符串、日期时间等常见数据类型,以及数组、嵌套结构等复杂数据类型。
强大的聚合函数:提供了丰富的聚合函数,如求和、平均值、最大值、最小值等,方便进行数据分析和统计。
支持 SQL 语言:用户可以使用熟悉的 SQL 语句进行数据查询和分析,降低了学习成本。

场景支持

ClickHouse的数据处理速度非常快,尤其适合于包含复杂分析查询的场景

适合场景

日志和事件数据:由于ClickHouse的处理速度,它可以作为实时数据分析的工具。
监控和报警系统:ClickHouse可以用于快速查询和显示监控数据。
交互式查询:由于其快速的查询速度,ClickHouse可以作为数据科学家进行交互式探索的工具。
数据仓库:ClickHouse可以作为数据仓库的一种替代方法,用于快速查询和分析。

不适合场景

事务处理:ClickHouse不支持事务处理。
强一致性:ClickHouse不保证数据的强一致性。
低延迟的更新:ClickHouse不适合于需要实时或近实时更新数据的场景。
高度模式化的数据:ClickHouse对模式的灵活性不如关系型数据库。

小结

总之,ClickHouse 是一款功能强大的数据库管理系统,适用于大规模数据分析和处理场景。通过了解其特点和基础知识,用户可以更好地利用 ClickHouse 来满足自己的数据分析需求