CreatePartition API执行流程_milvus源码解析

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
简介: CreatePartition API执行流程_milvus源码解析

CreatePartition API执行流程源码解析

milvus版本:v2.3.2

整体架构:

architecture.png

CreatePartition 的数据流向:

create_partition数据流向.jpg

1.客户端sdk发出CreatePartition API请求。

from pymilvus import (
    connections,
    Collection, Partition,
)

print("start connecting to Milvus")
connections.connect(db_name="default", host="192.168.230.71", port="19530")

hello_milvus = Collection("hello_milvus")

print("create a partition")
partition = Partition(hello_milvus, name="part01", description="this is a partition")

客户端SDK向proxy发送一个CreatePartition API请求,在hello_milvus这个collection下创建一个名为part01的partition。

exam_partition.jpg

2.客户端接受API请求,将request封装为createPartitionTask,并压入ddQueue队列。

代码路径:internal\proxy\impl.go

// CreatePartition create a partition in specific collection.
func (node *Proxy) CreatePartition(ctx context.Context, request *milvuspb.CreatePartitionRequest) (*commonpb.Status, error) {
   
   
    ......
    // request封装为task
    cpt := &createPartitionTask{
   
   
        ctx:                    ctx,
        Condition:              NewTaskCondition(ctx),
        CreatePartitionRequest: request,
        rootCoord:              node.rootCoord,
        result:                 nil,
    }

    ......
    // 将task压入ddQueue队列
    if err := node.sched.ddQueue.Enqueue(cpt); err != nil {
   
   
        ......
    }

    ......
    // 等待cct执行完
    if err := cpt.WaitToFinish(); err != nil {
   
   
        ......
    }

    ......
}

3.执行createPartitionTask的3个方法PreExecute、Execute、PostExecute。

PreExecute()一般为参数校验等工作。

Execute()一般为真正执行逻辑。

代码路径:internal\proxy\task.go

func (t *createPartitionTask) Execute(ctx context.Context) (err error) {
   
   
    t.result, err = t.rootCoord.CreatePartition(ctx, t.CreatePartitionRequest)
    if err != nil {
   
   
        return err
    }
    if t.result.ErrorCode != commonpb.ErrorCode_Success {
   
   
        return errors.New(t.result.Reason)
    }
    return err
}

从代码可以看出调用了rootCoord的CreatePartition接口。

4.进入rootCoord的CreatePartition接口。

代码路径:internal\rootcoord\root_coord.go

继续将请求封装为rootcoord里的createDatabaseTask

// CreatePartition create partition
func (c *Core) CreatePartition(ctx context.Context, in *milvuspb.CreatePartitionRequest) (*commonpb.Status, error) {
   
   
    ......
    // 封装为createPartitionTask
    t := &createPartitionTask{
   
   
        baseTask: newBaseTask(ctx, c),
        Req:      in,
    }
    // 加入调度
    if err := c.scheduler.AddTask(t); err != nil {
   
   
        ......
    }
    // 等待task完成
    if err := t.WaitToFinish(); err != nil {
   
   
        ......
    }

    ......
}

5.执行createPartitionTask的Prepare、Execute、NotifyDone方法。

Execute()为核心方法。

代码路径:internal\rootcoord\create_partition_task.go

func (t *createPartitionTask) Execute(ctx context.Context) error {
   
   
    for _, partition := range t.collMeta.Partitions {
   
   
        if partition.PartitionName == t.Req.GetPartitionName() {
   
   
            log.Warn("add duplicate partition", zap.String("collection", t.Req.GetCollectionName()), zap.String("partition", t.Req.GetPartitionName()), zap.Uint64("ts", t.GetTs()))
            return nil
        }
    }

    cfgMaxPartitionNum := Params.RootCoordCfg.MaxPartitionNum.GetAsInt()
    if len(t.collMeta.Partitions) >= cfgMaxPartitionNum {
   
   
        return fmt.Errorf("partition number (%d) exceeds max configuration (%d), collection: %s",
            len(t.collMeta.Partitions), cfgMaxPartitionNum, t.collMeta.Name)
    }
    // 分配partID
    partID, err := t.core.idAllocator.AllocOne()
    if err != nil {
   
   
        return err
    }
    // 构建partition结构体
    // 包含partID,partName,collectID等
    partition := &model.Partition{
   
   
        PartitionID:               partID,
        PartitionName:             t.Req.GetPartitionName(),
        PartitionCreatedTimestamp: t.GetTs(),
        Extra:                     nil,
        CollectionID:              t.collMeta.CollectionID,
        State:                     pb.PartitionState_PartitionCreating,
    }

    undoTask := newBaseUndoTask(t.core.stepExecutor)
    // 分为多个step执行,每一个undoTask由todoStep和undoStep构成
    // 执行todoStep,报错则执行undoStep
    undoTask.AddStep(&expireCacheStep{
   
   
        baseStep:        baseStep{
   
   core: t.core},
        dbName:          t.Req.GetDbName(),
        collectionNames: []string{
   
   t.collMeta.Name},
        collectionID:    t.collMeta.CollectionID,
        ts:              t.GetTs(),
    }, &nullStep{
   
   })
    // 添加partition元数据
    undoTask.AddStep(&addPartitionMetaStep{
   
   
        baseStep:  baseStep{
   
   core: t.core},
        partition: partition,
    }, &removePartitionMetaStep{
   
   
        baseStep:     baseStep{
   
   core: t.core},
        dbID:         t.collMeta.DBID,
        collectionID: partition.CollectionID,
        partitionID:  partition.PartitionID,
        ts:           t.GetTs(),
    })

    undoTask.AddStep(&nullStep{
   
   }, &releasePartitionsStep{
   
   
        baseStep:     baseStep{
   
   core: t.core},
        collectionID: t.collMeta.CollectionID,
        partitionIDs: []int64{
   
   partID},
    })

    undoTask.AddStep(&syncNewCreatedPartitionStep{
   
   
        baseStep:     baseStep{
   
   core: t.core},
        collectionID: t.collMeta.CollectionID,
        partitionID:  partID,
    }, &nullStep{
   
   })

    undoTask.AddStep(&changePartitionStateStep{
   
   
        baseStep:     baseStep{
   
   core: t.core},
        collectionID: t.collMeta.CollectionID,
        partitionID:  partID,
        state:        pb.PartitionState_PartitionCreated,
        ts:           t.GetTs(),
    }, &nullStep{
   
   })

    return undoTask.Execute(ctx)
}

创建partition涉及多个步骤,可以看出这里依次分为expireCacheStep、addPartitionMetaStep、syncNewCreatedPartitionStep、changePartitionStateStep这几个步骤,关于etcd元数据的操作,这里重点关注addPartitionMetaStep。其余step另用篇幅进行讲解。

6.进入addCollectionMetaStep,执行其Execute()方法。

代码路径:internal\rootcoord\step.go

func (s *addPartitionMetaStep) Execute(ctx context.Context) ([]nestedStep, error) {
   
   
    err := s.core.meta.AddPartition(ctx, s.partition)
    return nil, err
}

在这里重点研究s.core.meta.AddPartition()这个方法做了什么事情。

调用栈如下:

s.core.meta.AddPartition()
  |--AddPartition()(internal\rootcoord\meta_table.go)
    |--mt.catalog.CreatePartition()(同上)
      |--CreatePartition()(internal\metastore\kv\rootcoord\kv_catalog.go)
        |--kc.Snapshot.Save()

create_partition堆栈.jpg

在etcd产生partition相关的key:

==root-coord/partitions/445762854989594797/445766775506484222==

value的值的结构为etcdpb.PartitionInfo,然后进行protobuf序列化后存入etcd。

因此etcd存储的是二进制数据。

&pb.PartitionInfo{
   
   
    PartitionID:               partition.PartitionID,
    PartitionName:             partition.PartitionName,
    PartitionCreatedTimestamp: partition.PartitionCreatedTimestamp,
    CollectionId:              partition.CollectionID,
    State:                     partition.State,
}

partitionInfo2.jpg

可以看出partition由partitionID、partitionName、collectionID等组成。

func (kc *Catalog) CreatePartition(ctx context.Context, dbID int64, partition *model.Partition, ts typeutil.Timestamp) error {
   
   
    collMeta, err := kc.loadCollection(ctx, dbID, partition.CollectionID, ts)
    if err != nil {
   
   
        return err
    }

    if partitionVersionAfter210(collMeta) {
   
   
        // save to newly path.
        // 走这条路径
        // 构建key的规则
        k := BuildPartitionKey(partition.CollectionID, partition.PartitionID)

        partitionInfo := model.MarshalPartitionModel(partition)
        // 序列化
        v, err := proto.Marshal(partitionInfo)
        if err != nil {
   
   
            return err
        }
        // 写入etcd
        return kc.Snapshot.Save(k, string(v), ts)
    }

    ......
}

跟踪BuildPartitionKey()函数,不难得出key的规则。整理如下:

key规则:

  • 前缀/root-coord/partitions/{collectionID}/{partitionID}
  • 前缀/snapshots/root-coord/partitions/{collectionID}/{partitionID}_ts{时间戳}

根据路径能够反映出partition属于哪个collection。一个collection可以包含多个partition。

默认partition名为:_default。

可配置(milvus.yml):common.defaultPartitionName

使用etcd-manager查看etcd:

partition.jpg

总结:

1.CreatePartition由proxy传递给协调器rootCoord操作etcd。

2.CreatePartition最终会在etcd上写入一种类型的key

  • 前缀/root-coord/partitions/{collectionID}/{partitionID}
  • 前缀/snapshots/root-coord/partitions/{collectionID}/{partitionID}_ts{时间戳}
目录
相关文章
|
2天前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。
|
1天前
|
JSON 自然语言处理 Java
OpenAI API深度解析:参数、Token、计费与多种调用方式
随着人工智能技术的飞速发展,OpenAI API已成为许多开发者和企业的得力助手。本文将深入探讨OpenAI API的参数、Token、计费方式,以及如何通过Rest API(以Postman为例)、Java API调用、工具调用等方式实现与OpenAI的交互,并特别关注调用具有视觉功能的GPT-4o使用本地图片的功能。此外,本文还将介绍JSON模式、可重现输出的seed机制、使用代码统计Token数量、开发控制台循环聊天,以及基于最大Token数量的消息列表限制和会话长度管理的控制台循环聊天。
24 7
|
2天前
|
域名解析 弹性计算 安全
阿里云服务器租用、注册域名、备案及域名解析完整流程参考(图文教程)
对于很多初次建站的用户来说,选购云服务器和注册应及备案和域名解析步骤必须了解的,目前轻量云服务器2核2G68元一年,2核4G4M服务器298元一年,域名注册方面,阿里云推出域名1元购买活动,新用户注册com和cn域名2年首年仅需0元,xyz和top等域名首年仅需1元。对于建站的用户来说,购买完云服务器并注册好域名之后,下一步还需要操作备案和域名绑定。本文为大家展示阿里云服务器的购买流程,域名注册、绑定以及备案的完整流程,全文以图文教程形式为大家展示具体细节及注意事项,以供新手用户参考。
|
14天前
|
机器学习/深度学习 搜索推荐 API
淘宝/天猫按图搜索(拍立淘)API的深度解析与应用实践
在数字化时代,电商行业迅速发展,个性化、便捷性和高效性成为消费者新需求。淘宝/天猫推出的拍立淘API,利用图像识别技术,提供精准的购物搜索体验。本文深入探讨其原理、优势、应用场景及实现方法,助力电商技术和用户体验提升。
|
7天前
|
供应链 搜索推荐 数据挖掘
1688搜索词推荐API接口:开发应用与收益全解析
在电商数据驱动时代,1688搜索词推荐API接口为开发者、供应商及电商从业者提供强大工具,优化业务流程,提升竞争力。该接口基于1688平台的海量数据,提供精准搜索词推荐,助力电商平台优化搜索体验,提高供应商商品曝光度与销售转化率,同时为企业提供市场分析与商业洞察,促进精准决策与成本降低。通过集成此API,各方可实现流量增长、销售额提升及运营优化,推动电商行业的创新发展。
19 0
|
13天前
|
监控 搜索推荐 测试技术
电商API的测试与用途:深度解析与实践
在电子商务蓬勃发展的今天,电商API成为连接电商平台、商家、消费者和第三方开发者的重要桥梁。本文深入探讨了电商API的核心功能,包括订单管理、商品管理、用户管理、支付管理和物流管理,并介绍了有效的测试技巧,如理解API文档、设计测试用例、搭建测试环境、自动化测试、压力测试、安全性测试等。文章还详细阐述了电商API的多样化用途,如商品信息获取、订单管理自动化、用户数据管理、库存同步、物流跟踪、支付处理、促销活动管理、评价管理、数据报告和分析、扩展平台功能及跨境电商等,旨在为开发者和电商平台提供有益的参考。
22 0
|
6天前
|
人工智能 自然语言处理 API
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
谷歌推出的Multimodal Live API是一个支持多模态交互、低延迟实时互动的AI接口,能够处理文本、音频和视频输入,提供自然流畅的对话体验,适用于多种应用场景。
43 3
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
|
1天前
|
前端开发 API 数据库
Next 编写接口api
Next 编写接口api
|
8天前
|
XML JSON 缓存
阿里巴巴商品详情数据接口(alibaba.item_get) 丨阿里巴巴 API 实时接口指南
阿里巴巴商品详情数据接口(alibaba.item_get)允许商家通过API获取商品的详细信息,包括标题、描述、价格、销量、评价等。主要参数为商品ID(num_iid),支持多种返回数据格式,如json、xml等,便于开发者根据需求选择。使用前需注册并获得App Key与App Secret,注意遵守使用规范。
|
7天前
|
JSON API 开发者
淘宝买家秀数据接口(taobao.item_review_show)丨淘宝 API 实时接口指南
淘宝买家秀数据接口(taobao.item_review_show)可获取买家上传的图片、视频、评论等“买家秀”内容,为潜在买家提供真实参考,帮助商家优化产品和营销策略。使用前需注册开发者账号,构建请求URL并发送GET请求,解析响应数据。调用时需遵守平台规定,保护用户隐私,确保内容真实性。

推荐镜像

更多