Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. As CollectionAlias works as an extra pointer to the existing collection in the RootCoordinator, we can implement collection hot reloading at a low cost.
  2. When AddAlias, DropAlias and AlterAlias, the change of relationship between alias and collection should not affect the operations online, i.e. these operations shoud use the relationship when the task begin to excute.
  3. When AddAlias, DropAlias and AlterAlias, all proxy should receive the change in the same timestamp to ensure the atomicity between the proxy cache and the rootcoord data.
  4. Users can't drop the collection if the collection is referenced by an alias, which can simplify the operation and make it easier to ensure the atomicity property about alias changes.

Public Interfaces

Change to Existing APIs

Design Details

Changes to the MetaTable

...

Code Block
func build(im * immutablemap_string2string) Builder{
    builder := &Builder{
        reference: im
        mutable:   nil
    }
    return builder
}

//struct to bulid a new immutablemap according to the exist version
type Builder struct{
    reference    immutablemap_string2string
    mutable      map[string]string
}

func (bdr *Builder) maybeClone(){
    if bdr.reference != nil{
        bdr.mutable = make(map[string]string)
        for k,v := range bdr.reference.storemap{
            bdr.mutable[k] = v
        }
        
        bdr.reference = nil
    }
}

func (bdr *Builder) getnamefromalias(key string) (string, bool){
    bdr.maybeClone()
    return bdr.mutable[key]
}

func(bdr *Builder) putalias2name(key string, val string) (string, bool){
    bdr.maybeclone()
    var pre string
    if v,ok = bdr.mutable[key], ok{
        pre = v
    }else{
        pre = nil
    }
    bdr.mutable[key] = val
    return pre, ok
}

func(bdr *Builder) removealias2name(key string) (string, bool){
    bdr.maybeclone()
    var pre string
    if v,ok = bdr.mutable[key], ok{
        pre = v
        delete(bdr.mutable, key)
    }else{
        pre = nil
    }
    return pre, ok
}

func (bdr *Builder) build() immutablemap_string2string{
    if bdr.reference != nil{
        reference := bdr.reference
        bdr.reference = nil
        return reference
    }else{
        mutable = bdr.mutable
        bdr.mutable = nil
        res := & immutablemap_string2string{
            storemap:mutable
        }
        return res
    }
}

func (mt * metatable) addAlias(collectionAlias string, collectionName string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.putalias2name(collectionAlias, collectionName)
    if ok{
        return pre, fmt.Errorf("alias already exist when add alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return nil, nil
}

func (mt * metatable) dropAlias(collectionAlias string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.removealias2id(collectionAlias)
    if !ok{
        return nil, fmt.Errorf("alias not exist when drop alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return pre, nil
}

func (mt * metatable) alterAlias(collectionAlias string, collectionName string) (string, error){
    mt.ddLock.Lock()
    defer mt.ddLock.Unlock()
    ...
    ts = getTimestamp()
    tspre = mt.newestAliasTs
    Bdr = build(mt.ts2alias2name[tspre])
    pre,ok := Bdr.putalias2name(collectionAlias, collectionName)
    if !ok{
        return nil, fmt.Errorf("alias not exist when alter alias") 
    }
    mt.ts2alias2name[ts] = Bdr.build()
    mt.newestAliasTs = ts
    ...
    return pre, nil
}

Change to globalMetaCache

  • Add a function fetchAliasCache to fetch the newestAliasTs and the corresponding alias2name from rootcoord into proxy if newestAliasTs is different with the stored timestamp in globalMetaCache.
  • When each proxy task begin to excute, running fetchAliasCache