dataCoord的Compaction分析2

简介: dataCoord的Compaction分析2

dataCoord的Compaction分析2

milvus版本:2.3.2

流程图:

compaction数据流向.jpg

compaction用来合并对象存储的小文件,将小的segment合并为大的segment。

Compaction 有一个配置项来控制是否启用自动压缩。此配置是全局的,会影响系统中的所有集合。

dataCoord.enableCompaction = true
dataCoord.compaction.enableAutoCompaction = true

enableAutoCompaction生效的前提是enableCompaction为true。

增加了collection级别的控制。

compaction相关参数(全局):

dataCoord.enableCompaction = true
dataCoord.compaction.enableAutoCompaction = true
dataCoord.compaction.indexBasedCompaction = true
dataCoord.compaction.global.interval = 60 #默认60秒,触发compaction信号
dataCoord.compaction.check.interval = 10 #默认10秒,更新状态
dataCoord.segment.smallProportion = 0.5 #默认0.5
dataCoord.compaction.max.segment = 30 #默认30
dataCoord.compaction.min.segment = 3 #默认3

在collection级别设置属性:

collection.autocompaction.enabled = true

python设置代码:

hello_milvus.set_properties({
   
   "collection.autocompaction.enabled": True})

1.执行compaction的代码

func (t *compactionTrigger) start() {
   
   
    t.quit = make(chan struct{
   
   })
    t.globalTrigger = time.NewTicker(Params.DataCoordCfg.GlobalCompactionInterval.GetAsDuration(time.Second))
    t.wg.Add(2)
    go func() {
   
   
        defer logutil.LogPanic()
        defer t.wg.Done()

        for {
   
   
            select {
   
   
            case <-t.quit:
                log.Info("compaction trigger quit")
                return
            case signal := <-t.signals:
                switch {
   
   
                case signal.isGlobal:
                    // 处理全局compaction信号
                    t.handleGlobalSignal(signal)
                default:
                    // collection级别信号
                    t.handleSignal(signal)
                    // shouldn't reset, otherwise a frequent flushed collection will affect other collections
                    // t.globalTrigger.Reset(Params.DataCoordCfg.GlobalCompactionInterval)
                }
            }
        }
    }()
    // 触发全局compaction信号
    go t.startGlobalCompactionLoop()
}

t.handleGlobalSignal(signal) 用来处理全局信号。

t.handleSignal(signal) 用来处理collection级别的信号。

go t.startGlobalCompactionLoop() 定时触发全局信号。

collection信号在flush的时候触发。

2.触发全局

// triggerCompaction trigger a compaction if any compaction condition satisfy.
func (t *compactionTrigger) triggerCompaction() error {
   
   
    id, err := t.allocSignalID()
    if err != nil {
   
   
        return err
    }
    signal := &compactionSignal{
   
   
        id:       id,
        isForce:  false,
        isGlobal: true,
    }
    t.signals <- signal
    return nil
}

3.触发collection级别

// triggerSingleCompaction triger a compaction bundled with collection-partition-channel-segment
func (t *compactionTrigger) triggerSingleCompaction(collectionID, partitionID, segmentID int64, channel string) error {
   
   
    // If AutoCompaction disabled, flush request will not trigger compaction
    if !Params.DataCoordCfg.EnableAutoCompaction.GetAsBool() {
   
   
        return nil
    }

    id, err := t.allocSignalID()
    if err != nil {
   
   
        return err
    }
    signal := &compactionSignal{
   
   
        id:           id,
        isForce:      false,
        isGlobal:     false,
        collectionID: collectionID,
        partitionID:  partitionID,
        segmentID:    segmentID,
        channel:      channel,
    }
    t.signals <- signal
    return nil
}

调用堆栈:

SaveBinlogPaths()(internal\datacoord\services.go)
  |--s.compactionTrigger.triggerSingleCompaction()

当调用flush的时候触发。

// SaveBinlogPaths updates segment related binlog path
// works for Checkpoints and Flush
func (s *Server) SaveBinlogPaths(ctx context.Context, req *datapb.SaveBinlogPathsRequest) (*commonpb.Status, error) {
   
   
    ......

    if req.GetFlushed() {
   
   
        s.segmentManager.DropSegment(ctx, req.SegmentID)
        s.flushCh <- req.SegmentID

        if !req.Importing && Params.DataCoordCfg.EnableCompaction.GetAsBool() {
   
   
            err = s.compactionTrigger.triggerSingleCompaction(segment.GetCollectionID(), segment.GetPartitionID(),
                segmentID, segment.GetInsertChannel())
            if err != nil {
   
   
                log.Warn("failed to trigger single compaction")
            } else {
   
   
                log.Info("compaction triggered for segment")
            }
        }
    }
    return merr.Success(), nil
}

4.进入handleSignal()

// handleSignal processes segment flush caused partition-chan level compaction signal
func (t *compactionTrigger) handleSignal(signal *compactionSignal) {
   
   
    ......

    if !signal.isForce && !t.isCollectionAutoCompactionEnabled(coll) {
   
   
        log.RatedInfo(20, "collection auto compaction disabled",
            zap.Int64("collectionID", collectionID),
        )
        return
    }

    ......

    plans := t.generatePlans(segments, signal.isForce, isDiskIndex, ct)
    for _, plan := range plans {
   
   
        ......
    }
}

isCollectionAutoCompactionEnabled()判断是否设置collection级别。

func (t *compactionTrigger) isCollectionAutoCompactionEnabled(coll *collectionInfo) bool {
   
   
    enabled, err := getCollectionAutoCompactionEnabled(coll.Properties)
    if err != nil {
   
   
        log.Warn("collection properties auto compaction not valid, returning false", zap.Error(err))
        return false
    }
    return enabled
}

进入getCollectionAutoCompactionEnabled():

// getCollectionAutoCompactionEnabled returns whether auto compaction for collection is enabled.
// if not set, returns global auto compaction config.
func getCollectionAutoCompactionEnabled(properties map[string]string) (bool, error) {
   
   
    v, ok := properties[common.CollectionAutoCompactionKey]
    if ok {
   
   
        enabled, err := strconv.ParseBool(v)
        if err != nil {
   
   
            return false, err
        }
        return enabled, nil
    }
    return Params.DataCoordCfg.EnableAutoCompaction.GetAsBool(), nil
}

common.CollectionAutoCompactionKey=collection.autocompaction.enabled

目录
相关文章
|
SQL IDE Java
datagrip2022最新版安装破解与激活教程,亲测可用
Datagrip 应该是目前最好用的一款数据库连接工具,拥有智能查询控制台,搞笑的架构导航
11573 92
|
存储 Linux 数据安全/隐私保护
安装部署milvus单机版(快速体验)
安装部署milvus单机版(快速体验)
5763 0
|
消息中间件 Kubernetes 数据安全/隐私保护
milvus本地集群部署(非k8s)
milvus本地集群部署(非k8s)
1618 0
|
存储 Linux 开发工具
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
7037 1
成功解决centos7安装docker时 报缺 少container-selinux和fuse-overlayfs包
|
2月前
|
人工智能 分布式计算 Serverless
阿里云 EMR Serverless Spark 全托管 Ray 再进化:加速构建全模态数据处理新基建
阿里云 EMR Serverless Spark + Ray 双引擎构建全模态数据处理的新基建,通过极致内核优化和统一数据、算力底座,彻底打通了大数据工程与 AI 模型训练的割裂。结合 RayData、Daft、Data-Juicer 等多模态引擎,以及 CPFS、OSS 等高性能存储生态,阿里云正在为全球的 AI 开发者提供一套最具竞争力的数据新基建。
474 0
阿里云 EMR Serverless Spark 全托管 Ray 再进化:加速构建全模态数据处理新基建
|
2月前
|
存储 安全 开发工具
阿里云OSS防盗链与权限访问控制完全指南
本文系统讲解了阿里云OSS的防盗链与权限访问控制体系。首先深入剖析基于Referer的防盗链机制,包括白名单/黑名单配置、空Referer处理策略及QueryString截断规则,并提供控制台、Java SDK及ossutil三种配置方式。接着详细阐述OSS的四层权限控制架构:ACL提供基础的公开/私有控制,Bucket Policy实现基于资源的精细化授权(支持IP/VPC/时间条件),RAM Policy实现基于身份的跨账号权限管理,签名URL与STS临时凭证实现时效性访问控制。文章还深入分析了OSS扁平化存储结构对权限配置的影响、多策略并存时的鉴权流程(显式拒绝优先原则),并结合Pyth
|
5月前
|
存储 前端开发 Java
吃透 MinIO:从底层架构到全场景文件上传下载实战,一篇搞定企业级对象存储
MinIO是100%兼容S3协议的高性能、云原生对象存储系统,解决非结构化数据存储痛点。本文详解其架构原理、单/分布式部署、Spring Boot整合(含上传/下载/分片/秒传)、权限安全与生产最佳实践,助力企业构建高可用、低成本自建存储方案。
1076 4
|
6月前
|
存储 人工智能 弹性计算
阿里云/本地部署OpenClaw及永久记忆优化教程:Ollama+LanceDB+大模型API配置实战指南
在使用OpenClaw这类AI协作框架时,很多用户都会遇到相同问题:AI频繁遗忘上下文、重要偏好需要反复告知、长对话后响应变慢、隐私数据不敢上传云端,传统纯文本记忆文件随内容增大导致加载卡顿、Token消耗飙升,严重影响使用体验。本文基于Ollama本地大模型与LanceDB向量数据库,打造完全本地化、永久存储、智能检索的记忆增强方案,同时提供2026年阿里云ECS部署、本地MacOS/Linux/Windows11部署OpenClaw(Clawdbot)完整流程,以及阿里云千问大模型API、免费Coding Plan API配置方法与高频问题排查,让你的AI助手实现越用越快、越用越懂你。
2136 0