
过去八九年我们一直在做一件事把向量数据库从一个很小众的系统方向做成 AI 基础设施里的关键组件。这中间我们听过很多建议也得到了很多成长。当然也有很多人试图劝我们立刻原地倒闭比如传统数据库不是已经能存int、string、json了吗现在不过多了一种 vector 字段。传统数据库加一个向量类型再配一个ANN索引你们就要完蛋了的确很多传统数据库也是这么做的加一列 vector接一个索引demo 能跑也有很多企业在语义检索初期会选择这样的产品。但跑到一定规模以后就一定会发现传统数据库补丁的方式根本无法解决AI时代的新问题。向量不只是一种新的字段类型更是一种新的数据形态。比如单从存储模型设计来看它有表结构有 row有主键所以像数据库。它规模巨大要被 Spark、Ray、DuckDB、训练 pipeline 和评估系统反复读取和改写所以像数据湖。它的原始对象往往是视频、图片、PDF、音频继续留在 S3、GCS、OSS 里所以也像对象存储。但它还多了一层传统系统没有处理好的东西embedding、sparse vector、caption、vector index、text index、delete log、stats、外部对象引用以及这些对象之间不断变化的版本关系。更不用提当一份 AI 数据集持续演进、被多个系统共同读写、同时服务在线检索和离线分析时旧的存储模型还能不能承担作为数据事实来源的责任。因此沿用传统数据库、数据湖、对象存储的任何一种传统管理方式最后都会半路失灵。接下来本文将重点讲解传统存储模型在AI时代面临的三个典型问题写放大、读路径冲突、多引擎协作。以及解决为了解决这些问题我们是如何推出Loon存储引擎用混合文件格式、row id 对齐和 Manifest 重新组织数据解决海量向量数据的高效存储的。01AI时代的生产场景是怎么使用数据的我们最近和一个多模态训练数据团队聊过他们的工作流大概是这样的video → clips → metadata → aesthetic_score → caption → embedding → search / dedup / training data filtering一段长视频先上传到对象存储。pipeline 按“换镜头”“换场景”把它切成约 10 秒的片段去掉过长、过短或者质量太低的片段。剩下的片段会跑美学打分再让 caption 模型生成文本描述。最后给每个片段算一份 embedding写进向量库用来做去重、检索和训练数据筛选。这个过程中真正的麻烦其实体现在时间维度上。第一周只跑了切帧和元数据表里大致是 clip_id / video_id / start_offset / duration 这几列。第二周加上美学打分每个片段补一列 aesthetic_score。第三周caption 模型跑通每个片段补一列 caption平均 200 字。第四周第一版 embedding 上线每个片段补一列 768 维 CLIP 向量。一个月后换模型重新算了一份 embedding_v21024 维。两个月后要支持 hybrid search补一列 sparse vector。三个月后caption 做了一轮人工修订要回填那一列。发现没有这份数据永远不会真正“写完”。这就是向量数据和传统业务数据的关键差异。传统业务表里一行订单写完以后状态可能变化但它不会每隔几周长出一个几 KB 的新字段。向量数据不是这样模型会换特征会加caption 会修标签会补索引会重建。同一批 row 会不断被重新解释。而且规模向量数据的规模通常不是百万级多模态训练数据动辄亿级片段。参照 LAION-5B 这种 58 亿图文对的规模非结构化训练数据从一开始就不是小数据。所以向量存储的压力不在第一次 insert而在后续持续演进。以下是几个典型需求与变化。02需求一降低长字段带来的写放大我们先来分析写入和回填。过去十年lakehouse 生态里最常见的存储选择是 Parquet 这一类列存格式。它适合分析型负载字段稳定数据多读少改扫描时只读需要的列压缩率高生态成熟。问题是向量数据打破了少改多读这个前提。先看数据形状。结构化数据里TPC-H 是一个典型参照过去几十年分析型存储格式基本都是围着它做优化的。它最大的表 lineitem 有 16 列包括 4 个整数键、4 个 decimal、3 个日期、若干短字符串还有一个 44 字节以内的 comment。一行未压缩大约 150 字节压缩后通常在 60 到 80 字节之间。TPC-H 1GB scale 的 lineitem 大约 600 万行。这就是 Parquet 这类分析型存储格式假设的世界。默认 64 MB row group在这种行宽下可以装下 40 万到 100 万行按列压缩后一整列的物理体积通常在几 MB 到几十 MB。非结构化数据经过向量化以后形状完全不同。LAION 是非结构化数据图文对经过向量化之后的代表AI 工作流里很多 dataset 都是这个形状。LAION-5B 的每条记录包含一个 URL、一段 caption几十到一百多字节、几个数值字段width、height、相似度、NSFW 标签等加上一份 CLIP embedding。社区最常用的 ViT-L/14 是 768 维fp16 存 1.5 KBfp32 存 3 KB。对比一下TPC-H lineitemLAION-5B 风格单行未压缩字节~150~1.5–3 KB64 MB row group 装下的行40 万–100 万2 万–4 万单看一行的字节数LAION 就比 TPC-H 大了 20 倍上下这 20 倍里向量列就贡献了 95% 以上。如果换成 OpenAI text-embedding-3-large 这种 3072 维 fp32 embedding一行向量直接到 12 KB。多模态训练里常见的 1024 到 2048 维 embedding单条也有 4 到 8 KB。视频切帧场景里每个片段除了 embedding还会有 caption、aesthetic_score、原始视频引用、parser 版本、模型版本。结构化字段不一定少向量列却贡献了绝大部分体积。行的形状一变列存原来的账就算不下去。Parquet 这一类格式的核心假设有两条列基本不可变schema 演进低频。在 TPC-H 这种“行宽 150 字节、列数固定”的世界里这两条假设几乎不付代价。加一列就是写一个新文件每个 row group 64 MB总共也就几 GB——分析任务里几乎属于是背景噪声。改一行靠 delete log compaction重写的也只是 64 MB 这个量级每行才 150 字节搬几十万行成本都还在可控范围内。到向量数据这里代价直接放大。第一加一列向量本身就是 TB 级工程假设有 1 亿个 clip。给每个 clip 补一列 1024 维 fp32 embedding原始向量数据就是约 400 GB。这还只是数据本身。真实系统里还要写对象存储更新一份 stats建立索引更新元数据校验覆盖范围。如果每个月新增一到两列向量字段比如 embedding_v2、sparse_vector、rerank feature那么每次 schema 演进都意味着一次大型数据工程。前文中那个团队每个月加一到两列向量类型的字段意味着每个月有 TB 级的写入和回填。第二改一行也不再便宜列存系统里删除或修改旧数据通常不是原地改而是通过 delete log 加 compaction 完成。删除日志写进去compaction 时把活着的行搬到新文件。列存里删除或更新旧数据通常会暴力的简单重写文件因为一行不大重新生成数据——例如制作一张宽表——的成本不高。在 TPC-H 那种列上一行也就几十到几百字节搬一批 row 成本也不算高。但向量数据不一样。一条 768 维 fp32 embedding 就有 3 KB1024 到 2048 维 embedding 常见于多模态场景单条就是 4 到 8 KB如果是 3072 维 fp32单条可以到 12 KB。这意味着一次 caption 人工修订表面上只是回填几百字节的文本但在旧的统一存储布局里它可能会触发上百万 row id 的物理重写。整体数据量可达 GB 级别相当于大规模重新写入数据。如果文本、向量和其他派生特征共享同一批物理文件或 compaction 生命周期那么修一列文本就可能让同一批 row 上的 embedding、embedding_v2、sparse_vector 也被顺带重写。几百字节的更新最后变成 GB 级 I/O。这就是为什么说写放大问题在面对向量数据时需要被格外重视。第三加列和改行 在向量数据里是高频动作传统分析表的 schema 可能一年改几次。向量数据不是。caption 模型会升级embedding 模型会换sparse vector 会后补rerank feature 会增加人工标注会修订数据治理会补标签。这些动作都不是简单追加新行每一件都同时是改一列和针对一批 row 重写。lakehouse 生态过去十年的优化方向是读得更快不是改得更便宜。当主要写入模式从append-only 追加新行变成高频回填已有 row 的某几列原本可控的写放大就会被向量列的长度放大成主导成本。所以一个矛盾就出现了结构化数据上列存几乎没有写放大问题同一种列存放在向量数据上写放大却成了主导成本。03需求二一份数据既要能扫也要能点查写完以后读路径也会分裂。同一份向量数据业务侧可以有两种完全不同的读法。第一种是列式扫描。比如WHERE aesthetic_score 0.8 AND duration 5或者COUNT GROUP BY 离线分析 全量 embedding 评估 BM25 统计 bitmap 构建 数据质量检查这种读法的特点是读很多行每行只看少数几列。它喜欢连续 I/O、大 row group、列压缩、批量解码和向量化执行。Parquet 很适合这条路径。第二种是行级点查。ANN 检索返回一批 candidate row id 后系统要回表拿读取caption embedding rerank feature video_uri metadata这种读法的特点是读的行不多几百到几千但要按 row id 精确拿到几列。它需要低延迟随机访问希望直接定位到某一行某一列只读需要的 byte range而不是拉一个完整 row group。这两种读法对底层格式的要求几乎相反。扫描希望 row group 大多列在物理上挨在一起做向量化执行省 cache miss。这样一次 I/O 可以拉很多连续数据压缩率好吞吐高。点查希望读取粒度小。最好不用依赖大 row group而是能按 row id 找到 segment 或 byte range。扫描喜欢重压缩因为数据量大少传输很重要。点查必须能在压缩块中间挑出一条记录重压缩反而是负担。扫描可以靠并发掩盖对象存储延迟。点查在对象存储上很敏感因为每一次随机读都可能变成一次远程 range GET。row group 越大、单条 row 的位置越模糊读放大越严重。标量要的是宽和压缩向量要的是窄和点查。一个文件格式不可能同时满足这两种需求。如果所有列都放进 Parquet标量扫描会很舒服但 ANN 召回后的向量回表会很麻烦。系统可能只想拿几百条向量底层却要拉很多无关 row group。数据在本地 SSD 上时还可以靠 cache 和 mmap 缓解。一旦数据上 S3每一次 cache miss 都会变成远程读取一次 ANN 查询触发几十 MB 的网络流量。一次召回要回表读 1000 条 row可能要触发上千次 row group 拉取每次几十 MB——总流量直接上 GB。如果为了点查把 row group 切得很小点查变好了但扫描又变差。大量小片段会拖垮连续读和压缩效率。更现实的是hybrid search 会在同一次查询里同时触发两种读法。先用标量字段过滤aesthetic_score 0.8 AND duration 5再做 ANN 召回。再按 row id 回表取 caption、vector 和 metadata。也就是说同一份数据在同一个查询里既像分析表又像低延迟随机访问。同一份数据被同一个用户在 200 毫秒内两种读法各走一遍。这不是调 row group size 能解决的问题。04需求三让外部系统围绕同一份数据工作前两个问题发生在数据库内部怎么写怎么读。第三个问题发生在系统边界上以视频切帧场景为例它从头到尾几乎没有一个环节只发生在向量数据库内部。向量数据库只是整条链路中间的一段。它负责在线检索但数据生产、数据修订、数据分析和数据治理都发生在外部。其中原始视频在 S3 上切帧在 PySpark 或者 Ray 里跑美学打分用一个独立的 GPU 服务caption 由一个 LLM inference pipeline 算embedding 在另一个 GPU 池里算sparse vector 在 SPLADE 服务上算。此外检索完成后检索结果要喂给训练数据筛选 pipeline同一份数据要进入离线评估跟人工标注比对rerank model 要拿这批 vector 重新训练caption 要做人工审核然后回填数据治理要审计敏感内容。这些工作也都不在向量数据库里。数据库本身只占整条链路的中间一段——服务在线检索。它前面是 ML pipeline后面是分析、评估、治理、回填。如果向量数据库的物理格式只有自己能读写那么每次外部系统参与都要导出、转换、复制、再导入。这就导致同一份 collection 可能同时存在于数据库里、在 Spark 的临时目录里、在评估 pipeline 的本地拷贝里。那么谁是 source of truth哪一份对应的是上个月那个 caption 模型版本人工修订之后哪一批 row 已经被回填哪一批还没数据小的时候我们只需要付出一些额外的时间成本靠 Excel 和命名规范解决数据规模大到亿级片段、TB 级 embedding以后它会变成一致性问题。这时候能解决它的只有存储格式它要回答的是当前这份数据集是什么版本、有哪些列、覆盖哪些 row range、哪些 index 还有效、哪些原始对象还活着。这也是 lakehouse 生态过去十年解决的问题。从 Hive 表到 Iceberg、Delta Lake、Hudi核心不是怎么把文件压得更小而是多个引擎如何围绕同一份数据安全工作。向量数据库现在也走到了同一个路口只是它要管理的对象更多。除了列和分区还包括了 vector index、text index、sparse feature、删除日志以及指向原始视频的 Blob 引用。所以问题不在于Spark 能不能读 Milvus 的文件。真正的问题是Spark 在外部补完一列 sparse vector 以后Milvus 怎么知道这列属于哪个版本覆盖哪些 row用了哪个模型什么时候可以被线上查询使用。05如何解决三大需求需要重构表的格式回头看这三个向量数据的特性以及对应的挑战。向量字段长又频繁演进——列存的写放大被放大。同一份数据上的两种读法天生相反——单一文件格式没法两边讨好。数据在数据库之外被参与改写——私有格式成了系统级的债务。听起来是三个独立的工程问题。可以一个一个打补丁比如写放大上一些 batching访问模式上做一个 cache 层外部协作做一个导出工具。这条路过去几年向量数据库行业基本都走过但都走不远。因为真正的问题是一份向量数据集里住着有长有短、有冷有热、有适合扫描有适合点查的几种完全不同的数据以视频切帧为例clip_id / video_id / duration 是短标量字段适合过滤和分析。 caption 是文本字段可能要做 BM25、审核、修订和回填。 embedding 是长向量字段ANN 召回后需要低延迟点查。 embedding_v2 是新模型产生的新向量列可能后补。 sparse_vector 服务 hybrid search访问模式又不同。 raw video 应该继续留在对象存储里数据库只记录引用。 vector index / text index / stats / delete log 是围绕数据产生的派生结构和版本语义。它们只是共享同一个 row id但需要的处理方式天差地别。如果把它们硬当成一张普通表写放大会失控如果把它们硬塞进同一种列存格式点查会付出高读放大如果把它们当成一堆对象文件多引擎协作会变成版本噩梦。所以重新设计向量存储这件事我们需要先承认一份向量数据集天生是异构的混合文件格式承认不同列的访问模式不同。标量列适合扫描向量列适合点查原始大对象适合留在对象存储。行对齐承认这些列虽然物理上分开但逻辑上仍然共享同一批 row。Manifest 承认这份数据不是一次性写完的而是会被多个系统、多个版本、多个任务持续修改。基于这一判断给现有引擎打补丁这条路已经走不通我们需要的是一套全新的存储引擎。06我们推出了Loon 一举解决三大困境这个全新的存储模型。落到设计上其实就是三个动作把不同列放进不同物理格式混合文件格式让分散的列在逻辑上拼回一张表行对齐用一份声明出来的元数据描述整个数据集Manifest。能力上它要允许一张逻辑 collection 在物理上拆成多个列组允许每个列组选择合适的文件格式允许这些列组通过 row id 对齐允许索引、stats、delete log、外部对象引用都进入同一个版本视图允许外部计算系统围绕同一份数据安全写入和读取。为此我们推出了Loon新一代存储引擎。它延续了 Zilliz 的鸟类命名传统Loon 是生活在湖泊上的潜水鸟。这个名字直接对应技术目标向量数据库不该每次查询、回填、建索引都搬起整片数据湖它应该先看清当前数据集由哪些版本、列、索引和对象引用组成再潜下去读取真正需要的那一小部分。它替换的是 Milvus 原有的 segment binlog 存储层。上层组件——Proxy 路由、QueryCoord/DataCoord 调度、IndexNode 索引构建——接口没变改变的是 DataNode写路径、QueryNode 与 segcore读路径、Compaction以及外部 Spark / Ray connector都改为通过同一份 storage abstraction 落到 Loon。架构上Loon 是分层的。从上到下依次是Manifest 是数据集的版本视图ColumnGroup 把逻辑表映射到符合访问模式的物理布局格式层支持四种物理格式按列组挑选下面是统一的 Filesystem 抽象。07优化一混合文件格式既然不同列的访问模式不同就不应该再用一种文件格式管理所有列。一份向量数据集应该按访问模式拆成多个 ColumnGroup。第一类是标量列、过滤字段、业务键、统计字段。这些字段经常用于过滤、扫描、聚合、分析喜欢宽 row group、重压缩、向量化执行。Parquet 的压缩、列裁剪和生态互通正好适合它们。第二类是向量列、稀疏特征、rerank feature。访问模式是 ANN 召回后的行级点查要的是低延迟随机访问、按 byte range 拉取、按需解码。这一组适合走段式segment-based的格式。Vortex 是当前正在成熟的一个方向每段都有 offset 和 length对象存储上可以直接 range GET。第三类是原始大对象原始视频、PDF、图片。这些对象本身不应该进入向量数据库的数据文件。它们应该继续留在对象存储里。数据库里记录的是 URI、checksum、mime type、parser version 和对应关系。对上层应用来说它仍然是一张 clips 表。对存储层来说不同列住在不同物理格式里。原则只有一个用对的格式装对的列。具体实践中Loon 目前支持这几种文件格式Parquet——标量列、过滤字段、生态互通。Vortex——向量、稀疏特征。当前用社区开源的。Lance只读——兼容已有 Lance 数据集直接 mount 成一个 ColumnGroup。视频切帧场景对应过来clip_id / video_id / start_offset / duration / aesthetic_score 进 Parquet 列组caption 也进 Parquet 列组embedding、embedding_v2、sparse_vector 各自进段式列组原始视频文件还在 S3每个 clip_id 对应一个引用。加 embedding_v2 只是新增一个段式列组、登记 row id 范围、commit Manifest——既不动 caption 列组里的字段也不动 embedding 列组里已有的 400 GB 向量。Parquet 这一边Loon 没有用社区默认配置row group 收紧到 1 MB默认 64 MB 在向量列上等于每次回表都至少拉 64 MB向量列上关掉 dict 等对随机数据没收益的编码。这些调整加起来比起社区默认行为已经是相当大的优化。Vortex优化才是真正为向量存储做的重点工作。我们基于社区开源 Vortex 实现了一个行存与列存平衡的 layout同一 row group 内各列的 segment 在文件中物理相邻scan 时可以连续读新增 sub-segment 读取让 take 只拉 segment 内部的一段字节而不是整段。向量列上的三组关键数字对比如下动作VortexParquetVortex 优势Take索引回表K1000 随机行5.8 ms144 ms25×Scan向量列全表扫描21 ms142 ms6.76×文件大小约 21 MB 原始数据6.62 MB7.16 MB小 7%三组差距背后是不同的存储机制Take 的优势来自新的 layout 只需要访问命中的 row group 内部数据而 Parquet 则要解析命中行所在的整个 row groupScan 的优势来自 vortex 压缩算法和工程实现的优化。[1] 测试环境8 vCPU Ubuntu 22.04 KVM。单文件 40,000 行schema 为{id: int64, name: utf8, value: float64, vector: list[128]}row group 1 MB。基于本地文件系统测试。S3 上的性能由网络 IO 主导Vortex 段式布局的读放大更小相对 Parquet 的优势会被进一步放大。08优化二行对齐混合文件格式解决了怎么拆。拆开以后还要回答一个问题怎么把它们重新看成一张表答案是 row id。每个列组在元数据里登记自己覆盖的 row id 范围——start_index / end_index。同一个 row id 空间里多个列组分别管一部分列。这样row id 12345 的字段可以分散在多个文件、多个格式、多个列组里但逻辑上通过 row id仍然是一行。这带来几个能力升级。第一加列不动原始列新增 embedding_v2 时只需要写一个新的向量列组并登记它覆盖哪些 row id。老的 caption、metadata、embedding_v1 不需要重写。第二删除可以先进入 delete log当前版本里哪些 row 不可见可以先由 delete log 表达。真正的物理清理推迟到 compaction阶段。更重要的是compaction 可以只触及相关列组而不是每次都搬动整张表。第三hybrid search 可以稳定回表ANN 召回 row id 后系统可以从不同列组里分别取 caption、metadata、vector、video URI再拼成结果。row id 在这里不是业务主键更像是存储层的坐标系。没有这个坐标系混合格式只是一堆散文件。有了 row id对象存储上的多个文件、多种格式、多个列组才能重新组成一张逻辑 collection。要解决以上三个行对齐需求落到Loon里我们主要做了两件事。ColumnGroupFile 的结构——每个物理文件登记 path / start_index / end_index 三个数字外加一段可选 metadata。start_index / end_index 是行对齐的全部秘密不同列组、不同文件、不同格式通过同一套 row id 范围对齐。Packed Reader——上层读到的是统一的 Arrow RecordBatch stream下面可能跨好几个列组。Packed Reader 干三件事屏蔽下层格式差异不管下面是 Parquet 还是别的列格式按 row id 范围把多个列组拼齐用最小堆调度多文件 I/O 控制内存。它还有另一个入口——按 row id 直接 take定位到对应的 ColumnGroupFile发起 range read 拿到具体数据。视频切帧场景下ANN 召回回表读 caption embedding 视频引用Packed Reader 拆成两次 range GET一次标量列组、一次向量列组不动其他列组任何字节。09优化三Manifest混合文件格式解决物理布局row id 解决逻辑对齐Manifest 解决的则是事实来源问题。当一份数据横跨多个文件、多种格式、多个版本、多个写入者时目录结构已经不能再说明真相。对象存储目录里可能有旧版本文件、新版本文件、失败任务留下的文件、仍被旧 snapshot 引用的文件、还没清理的 delete log、临时输出文件文件存在不代表它属于当前版本。所以需要 Manifest。Manifest 描述的是数据集在某个版本上长什么样有哪些列组、各自覆盖什么 row id 范围、用什么格式、文件落在哪。有哪些 delta log 生效是按主键删PRIMARY_KEY、按位置删POSITIONAL还是按值删EQUALITY。有哪些统计可用——bloom filter、min/max。有哪些索引覆盖到哪些列。引用了哪些外部 Blob对应哪个 source object 版本。Manifest 的形式是一个版本号 一份二进制结构每次更新就是写一个新版本的 Manifest 文件。读者读到哪一版 Manifest就看到哪一版数据集——读者之间互不打扰。这层优化的核心关键不在于结构本身而在于谁能写。如果只有数据库内部能写 Manifest那它仍然是一份内部元数据只是换了个名字。但如果 Manifest 的写入路径是开放的——Spark 跑完一列 sparse vector backfill 之后能生成新的列组、新的 stats、新的 Manifest再通过乐观并发提交进同一个版本视图——那它就成了多引擎协作的接口。在线查询继续读旧版本不受影响提交成功之后新版本立刻成为事实来源。这套思路和 Iceberg、Delta Lake 类似。但向量数据库的 Manifest 管得更多。不只是表文件和分区还包括 vector index、text index、sparse feature、delete log、stats、Blob 引用和 row id 范围。一定程度上没有 Manifest多格式、多列组、多引擎写入都会退化成文件约定和人工对账。而人工对账在 TB 级向量数据面前没有未来。具体来说每个 Loon 数据集在对象存储上的目录是这样组织的_metadata/ 放版本化的 Manifest 文件、_data/ 放列组数据文件、_delta/ 放删除日志、_stats/ 放统计文件、_index/ 放索引文件。这几个目录里的内容是否属于当前版本全部由当前 Manifest 决定——读者不去 list 目录推测。Manifest body 用 Apache Avro 编码按顺序排四块ColumnGroups——列、格式、文件、覆盖的 row id 范围。DeltaLogs——删除日志。三种语义对应三种典型来源PRIMARY_KEY客户端 delete、POSITIONALcompaction 内部位置删、EQUALITYSpark 等外部引擎按 predicate 删。Stats——bloom filter、BM25、min/max 这一类。查询规划器在打开数据文件之前先用 Stats 做 pruning。Indexes——每个 index 记录覆盖列、类型HNSW、IVF、inverted、bitmap 等、参数、覆盖的 row id 范围。每提交一次写一份新版本旧版本继续在那里。这条性质让乐观并发提交能用最小语义实现写者基于版本 N 生成新内容提交时写入 manifest-{N1}.avro——通过对象存储的 conditional write / generation match 能力保证该版本已存在就失败。冲突重试的代价远低于走强一致 CAS。10Loon 现在走到了哪一步未来会走向何方Loon 目前已经进入 Milvus 主干。已经完成的部分主要集中在三层第一层是 Manifest。Manifest 已经完成包含 ColumnGroups、DeltaLogs、Stats、Indexes 四个 section。每次写入、回填、删除、索引更新都会形成新的版本视图。写者基于旧版本生成新内容再通过乐观并发提交新的 Manifest。读者只需要读到某一个 Manifest 版本就能看到一份稳定的数据集。第二层是 ColumnGroup 和格式层。文件格式方面Parquet 、Vortex 已经支持我们会逐渐用 Vortex 替换 Parquet 最终成为默认的格式Lance 以只读方式接入用来兼容已有 Lance 数据集。第三层是 Index on Lake。标量 stats、过滤索引、文本倒排索引已经可以按 row range 进入 Manifest 规划。向量索引的 lake-native 路径还在继续推进。HNSW / IVF 这类索引在对象存储上的访问模式不同尤其是 HNSW 对随机访问和缓存更敏感不能简单照搬本地 SSD 上的布局。发布节奏会跟随 Milvus release。具体启用版本和能力边界以对应 release note 为准。放眼未来我们还将在四个方面做重点优化升级多引擎写入 SDK——Spark / Ray 端给出 first-class 的 Manifest 写入路径让外部 backfill 不需要走 C/C 接口。Iceberg / Delta Lake 互通——把向量列组对接到 lakehouse 的现有 catalog 体系让 Trino / DuckDB / Athena 这一族引擎能围绕同一份数据工作。索引支持——图索引在对象存储上的延迟特性和 IVF 不同需要单独的 layout 缓存策略。这是当前最直接的瓶颈HNSW 在线召回还吃本地缓存对象存储优势暂时主要兑现在 batch 路径上。LOB类型支持——原始视频、PDF、音频等大对象的引用、版本化、删除连带语义。尾声如何使用Loon对应用层来说Loon 不应该成为一个新的概念负担。因此在我们的设计中collection、insert、search、hybrid search 这些 API 表面不会变。应用不需要知道 Manifest、ColumnGroup、row id range这些内部概念。变化发生在存储层。新建 collection 时在启用 Loon 的 Milvus 版本里Loon 会作为默认存储引擎对用户透明。存量 Milvus 2.x collection 可以通过迁移工具接入。迁移过程走后台 compaction把旧存储布局逐步转换为 Loon 的列组布局业务层读写接口保持不变。Zilliz Cloud 里的 Vector Lakebase 也是基于这套存储模型构建。同一份数据集可以被线上 ANN 查询消费也可以被 Spark / Ray 等外部引擎围绕同一份 Manifest 协作。它会随着 Milvus 版本在新集群上逐步默认启用。换句话说Loon 对用户暴露的不是一组新 API而是一组原来很难做、现在可以自然发生的动作。看几个最常见的动作会更直观。以前给一批老数据补一列 embedding_v2要导出旧 collection跑模型生成新向量再把数据重新导入或者通过 SDK 批量 update。中间要处理版本、失败重试、索引重建还要尽量不影响线上查询。在 Loon 里这件事变成通过 schema evolution 添加字段物理上写一个新列组老列零搬动以前对老 row 做 backfill往往要走 client SDK 批量 update写放大严重在 Loon 里Spark / Ray 这样的外部引擎可以直接生成新的列组和 stats再通过 Manifest 提交。数据库不再是所有数据改写的唯一入口而是和外部计算系统共享同一份版本视图。以前做离线评估或数据分析往往要先 dump 到 Parquet。线上 collection 是一份分析目录里又是一份。只要中间有人工修订、模型换版、delete log 没同步就会出现到底哪份数据是准的的问题。在 Loon 里分析引擎可以直接读 Manifest 和相关列组。只读需要的 projection只扫需要的 row range。以前删除一批 row也会遇到类似问题。delete log 可以先表达逻辑删除但 compaction 时常常会牵动整批数据。只要 caption、embedding、sparse vector 被绑在同一个生命周期里删改短字段也可能拖着长向量一起重写。在 Loon 里delete log 仍然存在但 compaction 可以只触及相关列组。没有被影响的列组不需要重写。这样删除、回填、修订这些日常动作不会每次都演变成一次大规模数据搬迁。更重要的是它把很多过去需要 ops、ETL、停机窗口和人工对账的基础设施级动作变成了围绕 Manifest 的普通 commit。而创新的加速也往往是从这些看似不起眼地方开始的。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】