欢迎来到技术研发笔记

记录技术成长,分享实践经验

Elasticsearch 简介

Elasticsearch 是一个基于 Apache Lucene 构建的开源分布式搜索和分析引擎,由 Shay Banon 于 2010 年首次发布,目前由 Elastic 公司维护。它以 JSON 格式存储文档,通过 RESTful API 提供近实时的全文检索和数据分析能力,是当前最流行的企业级搜索引擎之一。

核心架构概念

Index(索引)

文档的逻辑集合,类似于关系数据库中的"数据库"。每个索引可独立配置分片数、副本数和映射规则。

Document(文档)

以 JSON 格式存储的基本数据单元,包含多个字段。每个文档有唯一 _id,属于某个索引。

Shard(分片)

索引的物理分区,分为主分片(Primary)和副本分片(Replica)。主分片数在索引创建后不可更改。

Node(节点)

运行中的 ES 实例。按角色分为 Master、Data、Coordinating 等类型,协同构成集群。

核心特性

  • 分布式架构 — 数据自动分片到多个节点,副本机制保障高可用,支持无缝水平扩展至数百节点
  • 近实时搜索 — 文档写入后约 1 秒即可被检索,通过内存 Buffer → Segment 刷新机制实现
  • 全文检索 — 内置多种分词器(Standard、IK、jieba 等),支持中英文混合分词、同义词、拼音搜索
  • 聚合分析 — 提供桶聚合(Terms、Histogram)、指标聚合(Avg、Max)、管道聚合等丰富能力
  • 倒排索引 — Lucene 倒排索引 + FST 有限状态转换器,实现高效词条查找和内存压缩
  • 多数据类型 — 支持文本、数值、日期、地理坐标、嵌套对象、数组等丰富字段类型

写入与查询流程

写入流程:客户端请求 → 协调节点路由 → 主分片写入 → 内存 Buffer + Translog → Refresh(每秒)生成 Segment → Flush 持久化。副本分片异步同步主分片数据。

查询流程:客户端请求 → 协调节点解析 → Query 阶段(各分片返回匹配文档 ID 和分数)→ Fetch 阶段(取回完整文档内容)→ 合并排序后返回结果。

典型使用场景

电商商品搜索 日志分析 (ELK) 指标监控 安全分析 (SIEM) 地理空间检索 应用性能监控 (APM) 知识库搜索

基本操作示例

PUT /products/_doc/1
{
  "name": "Elasticsearch实战",
  "category": "技术书籍",
  "price": 79.9
}

GET /products/_search
{
  "query": {
    "match": { "name": "实战" }
  }
}
ELK 生态:Elasticsearch 通常与 Logstash(数据采集与转换)和 Kibana(可视化仪表盘)组成 ELK Stack,形成完整的数据采集—存储—分析—可视化链路,是日志分析领域的事实标准方案。

Milvus 简介

Milvus 是一款开源的向量数据库,由 Zilliz 公司开发并于 2019 年开源,目前是 LF AI & Data 基金会的毕业项目。它专为海量向量的存储、索引和检索而设计,是 AI 和大模型时代的基础设施组件,广泛应用于相似性搜索和推荐系统等场景。

核心架构概念

Collection(集合)

向量的逻辑容器,类似关系数据库中的"表"。定义 Schema 包含向量字段和标量字段。

Partition(分区)

Collection 的物理子集,可按标量字段值自动分区或手动创建,加速查询时的数据裁剪。

Segment(段)

数据存储的最小单元,分为 Growing(增长中)和 Sealed(已封存)两种状态,封存后可构建索引。

Index(索引)

针对向量字段构建的索引结构,支持 IVF、HNSW、DiskANN 等多种算法,权衡速度与精度。

核心特性

  • 多索引支持 — 内置 FLAT、IVF_FLAT、IVF_SQ8、IVF_PQ、HNSW、SCANN、DiskANN 等索引类型,适配不同规模和延迟需求
  • 云原生架构 — 存算分离设计,Coordinator、Worker Node、Storage 三层解耦,支持独立扩缩容
  • 混合检索 — 向量相似度搜索与标量过滤可组合执行,先过滤再检索,兼顾精度与性能
  • 多语言 SDK — 提供 Python、Java、Go、Node.js 等 SDK,兼容 RESTful 和 gRPC 接口
  • 高可用 — 基于 etcd 的元数据管理,MinIO/S3 对象存储,支持多副本和故障自动恢复
  • GPU 加速 — 支持 NVIDIA GPU 加速索引构建和查询,大幅提升吞吐量

部署模式

模式适用场景特点
Milvus Lite本地开发、Jupyter Notebook嵌入式,零依赖,Python pip 安装即用
Milvus Standalone单机测试、小规模生产Docker 一键部署,含 etcd + MinIO
Milvus Cluster大规模生产环境存算分离,各组件独立扩缩,K8s 部署
Zilliz Cloud免运维全托管按需付费,自动扩容,内置监控告警

典型使用场景

RAG 检索增强生成 以图搜图 推荐系统 语义搜索 去重检测 生物特征识别 异常检测

基本操作示例(Python SDK)

from pymilvus import Collection, CollectionSchema, FieldSchema, DataType

fields = [
  FieldSchema("id", DataType.INT64, is_primary=True),
  FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=128),
  FieldSchema("title", DataType.VARCHAR, max_length=256)
]
schema = CollectionSchema(fields, "文章向量集合")
collection = Collection("articles", schema)

import numpy as np
data = [[i, np.random.rand(128).tolist(), f"文章{i}"] for i in range(1000)]
collection.insert(data)

collection.create_index("embedding", {"index_type": "IVF_FLAT", "metric_type": "L2"})
results = collection.search([query_vec], "embedding", {}, limit=5)
RAG 核心组件:Milvus 是 RAG(检索增强生成)架构中的关键向量存储层。文档经 Embedding 模型向量化后存入 Milvus,推理时先从 Milvus 检索相关文档片段,再送入 LLM 生成回答,有效缓解大模型幻觉问题。

Faiss 简介

Faiss(Facebook AI Similarity Search)是 Meta AI 团队于 2017 年开源的向量相似性搜索库,用 C++ 编写并提供 Python 绑定。它不是一个数据库,而是一个专注于高维向量高效检索的算法库,以极致的性能和灵活性著称,适合嵌入到应用中作为检索引擎使用。

核心架构概念

Index(索引)

Faiss 的核心抽象,封装了向量的存储和检索逻辑。不同 Index 实现不同算法,适用于不同场景。

IndexFlatIP / IndexFlatL2

暴力搜索索引,逐个计算相似度。精度最高但速度最慢,适合小数据集或作为 Baseline。

IndexIVFFlat

倒排文件索引,先用 K-Means 聚类将向量空间分区,查询时只搜索最近的 nprobe 个聚类中心。

IndexIVFPQ

在 IVF 基础上叠加乘积量化(PQ),将向量压缩为短编码,大幅降低内存占用,牺牲少量精度。

核心特性

  • 极致性能 — C++ 核心实现,支持单机十亿级向量检索,GPU 版本可达毫秒级延迟
  • 丰富的量化算法 — 支持 PQ(乘积量化)、SQ(标量量化)、OPQ(优化乘积量化)等压缩方案,内存可压缩 8-64 倍
  • GPU 加速 — 原生支持 CUDA,单卡可管理数亿向量,多卡并行进一步提升吞吐
  • 灵活组合 — Index 可自由嵌套组合(IVF + PQ + HNSW 等),精细调控精度/速度/内存的平衡
  • 多种距离度量 — 支持 L2 欧氏距离、内积(IP)、余弦相似度等常用度量方式
  • 轻量嵌入 — 纯库形式,无外部依赖,可直接集成到 Python/C++ 应用中

索引类型对比

索引类型内存占用检索速度召回率适用规模
IndexFlatL2高(原始向量)100%< 100万
IndexIVFFlat高(nprobe 可调)100万-1000万
IndexIVFPQ低(压缩)中-高1000万-10亿
IndexHNSW极快< 1000万
IndexIVFHNSW中-高极快1000万+

典型使用场景

大规模向量检索 推荐系统召回 图像特征匹配 文本 Embedding 检索 聚类分析 去重与近似匹配 GPU 批量推理

基本操作示例(Python)

import faiss
import numpy as np

dim = 128
nb = 100000
xb = np.random.rand(nb, dim).astype('float32')

# 构建索引index = faiss.IndexFlatL2(dim)
index.add(xb)

# 检索 Top-5k = 5
xq = np.random.rand(1, dim).astype('float32')
D, I = index.search(xq, k)
print("最近邻索引:", I)

# IVF + PQ 压缩索引(大规模场景)nlist = 100
m = 16 # PQ 子量化器数量quantizer = faiss.IndexFlatL2(dim)
index_ivfpq = faiss.IndexIVFPQ(quantizer, dim, nlist, m, 8)
index_ivfpq.train(xb)
index_ivfpq.add(xb)
Faiss vs 向量数据库:Faiss 是算法库而非数据库,不具备数据持久化、CRUD、权限管理等能力。生产环境中通常将 Faiss 作为检索引擎嵌入到应用或向量数据库(如 Milvus 底层即使用 Faiss 算法)中,再由上层系统负责存储管理和分布式协调。