Current state: Disccusion completed
ISSUE: https://github.com/milvus-io/milvus/issues/17131
PRs: TODO
Keywords: Collection Alias, Atomic Switching
Released: TODO
RootCoordinator
, Proxy
, and all the key components, CollectionName
and CollectionAlias
are equal. MetaTable.GetCollectionByName(collectionName string, ts typeutil.Timestamp)
can receive CollectionAlias
and return corresponding CollectionInfo.
CollectionAlias
∧ CollectionName
= ∅ . CollectionAlias
cannot collide with existing CollectionName
s.CollectionAlias
works as an extra pointer to the existing collection in the RootCoordinator
, we can implement collection hot reloading at a low cost.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.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.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.Metatable
now add ts2alias2name
and newestAliasTs
member variablestype immutablemap_string2string struct{ storemap map[string]string } func (imstr2str * immutablemap_string2string) get(key string) (string, error){ rstr,ok := imstr2str.storemap[key] if(!ok){ return nil, fmt.Errorf("key not exist") } return rstr, nil } func (imstr2str * immutablemap_string2string) put(key string, val string) (string, error){ return nil, fmt.Errorf("not allowed put in immutablemap") } type metatable struct{ ... ts2alias2name map[Timestamp]immutablemap_string2string newestAliasTs Timestamp ... } |
GetCollectionByName
add alias timestamp as parameter to select which alias2name
map will be used in ts2alias2name
.alias2name
immutable map in ts2alias2name
.func build(im * immutablemap_string2string) Builder{ builder := &Builder{ reference: im mutable: nil } return builder } 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 } |