mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-08 01:58:34 +08:00
clean up meta interface (#24729)
Signed-off-by: yiwangdr <yiwangdr@gmail.com>
This commit is contained in:
parent
691809065f
commit
37c02c9927
@ -426,15 +426,9 @@ type MetaKv interface {
|
|||||||
TxnKV
|
TxnKV
|
||||||
GetPath(key string) string
|
GetPath(key string) string
|
||||||
LoadWithPrefix(key string) ([]string, []string, error)
|
LoadWithPrefix(key string) ([]string, []string, error)
|
||||||
LoadWithPrefix2(key string) ([]string, []string, []int64, error)
|
|
||||||
LoadWithRevision(key string) ([]string, []string, int64, error)
|
|
||||||
Watch(key string) clientv3.WatchChan
|
Watch(key string) clientv3.WatchChan
|
||||||
WatchWithPrefix(key string) clientv3.WatchChan
|
WatchWithPrefix(key string) clientv3.WatchChan
|
||||||
WatchWithRevision(key string, revision int64) clientv3.WatchChan
|
WatchWithRevision(key string, revision int64) clientv3.WatchChan
|
||||||
SaveWithLease(key, value string, id clientv3.LeaseID) error
|
|
||||||
Grant(ttl int64) (id clientv3.LeaseID, err error)
|
|
||||||
KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error)
|
|
||||||
CompareValueAndSwap(key, value, target string, opts ...clientv3.OpOption) error
|
|
||||||
CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) error
|
CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,18 +67,6 @@ func (mm *metaMemoryKV) GetPath(key string) string {
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *metaMemoryKV) LoadWithPrefix2(key string) ([]string, []string, []int64, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) LoadWithRevisionAndVersions(key string) ([]string, []string, []int64, int64, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) LoadWithRevision(key string) ([]string, []string, int64, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) Watch(key string) clientv3.WatchChan {
|
func (mm *metaMemoryKV) Watch(key string) clientv3.WatchChan {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
@ -91,26 +79,6 @@ func (mm *metaMemoryKV) WatchWithRevision(key string, revision int64) clientv3.W
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mm *metaMemoryKV) SaveWithLease(key, value string, id clientv3.LeaseID) error {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) SaveWithIgnoreLease(key, value string) error {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) Grant(ttl int64) (id clientv3.LeaseID, err error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) CompareValueAndSwap(key, value, target string, opts ...clientv3.OpOption) (bool, error) {
|
|
||||||
panic("implement me")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mm *metaMemoryKV) CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
func (mm *metaMemoryKV) CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import (
|
|||||||
datanodeclient "github.com/milvus-io/milvus/internal/distributed/datanode/client"
|
datanodeclient "github.com/milvus-io/milvus/internal/distributed/datanode/client"
|
||||||
indexnodeclient "github.com/milvus-io/milvus/internal/distributed/indexnode/client"
|
indexnodeclient "github.com/milvus-io/milvus/internal/distributed/indexnode/client"
|
||||||
rootcoordclient "github.com/milvus-io/milvus/internal/distributed/rootcoord/client"
|
rootcoordclient "github.com/milvus-io/milvus/internal/distributed/rootcoord/client"
|
||||||
|
"github.com/milvus-io/milvus/internal/kv"
|
||||||
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
||||||
"github.com/milvus-io/milvus/internal/metastore/kv/datacoord"
|
"github.com/milvus-io/milvus/internal/metastore/kv/datacoord"
|
||||||
"github.com/milvus-io/milvus/internal/proto/datapb"
|
"github.com/milvus-io/milvus/internal/proto/datapb"
|
||||||
@ -105,7 +106,7 @@ type Server struct {
|
|||||||
|
|
||||||
etcdCli *clientv3.Client
|
etcdCli *clientv3.Client
|
||||||
address string
|
address string
|
||||||
kvClient *etcdkv.EtcdKV
|
kvClient kv.MetaKv
|
||||||
meta *meta
|
meta *meta
|
||||||
segmentManager Manager
|
segmentManager Manager
|
||||||
allocator allocator
|
allocator allocator
|
||||||
|
|||||||
@ -134,10 +134,6 @@ package indexnode
|
|||||||
// loadWithPrefix2 func(key string) ([]string, []string, []int64, error)
|
// loadWithPrefix2 func(key string) ([]string, []string, []int64, error)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (mk *mockETCDKV) LoadWithPrefix2(key string) ([]string, []string, []int64, error) {
|
|
||||||
// return mk.loadWithPrefix2(key)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIndexBuildTask_loadIndexMeta(t *testing.T) {
|
// func TestIndexBuildTask_loadIndexMeta(t *testing.T) {
|
||||||
// t.Run("load empty meta", func(t *testing.T) {
|
// t.Run("load empty meta", func(t *testing.T) {
|
||||||
// indexTask := &IndexBuildTask{
|
// indexTask := &IndexBuildTask{
|
||||||
|
|||||||
@ -159,49 +159,6 @@ func (kv *EmbedEtcdKV) LoadBytesWithPrefix(key string) ([]string, [][]byte, erro
|
|||||||
return keys, values, nil
|
return keys, values, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadWithPrefix2 returns all the keys and values with versions by the given key prefix
|
|
||||||
func (kv *EmbedEtcdKV) LoadWithPrefix2(key string) ([]string, []string, []int64, error) {
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
log.Debug("LoadWithPrefix ", zap.String("prefix", key))
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
versions := make([]int64, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
versions = append(versions, kv.Version)
|
|
||||||
}
|
|
||||||
return keys, values, versions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (kv *EmbedEtcdKV) LoadWithRevisionAndVersions(key string) ([]string, []string, []int64, int64, error) {
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
log.Debug("LoadWithPrefix ", zap.String("prefix", key))
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, 0, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
versions := make([]int64, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
versions = append(versions, kv.Version)
|
|
||||||
}
|
|
||||||
return keys, values, versions, resp.Header.Revision, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadBytesWithPrefix2 returns all the keys and values with versions by the given key prefix
|
// LoadBytesWithPrefix2 returns all the keys and values with versions by the given key prefix
|
||||||
func (kv *EmbedEtcdKV) LoadBytesWithPrefix2(key string) ([]string, [][]byte, []int64, error) {
|
func (kv *EmbedEtcdKV) LoadBytesWithPrefix2(key string) ([]string, [][]byte, []int64, error) {
|
||||||
key = path.Join(kv.rootPath, key)
|
key = path.Join(kv.rootPath, key)
|
||||||
@ -328,26 +285,6 @@ func (kv *EmbedEtcdKV) MultiLoadBytes(keys []string) ([][]byte, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadWithRevision returns keys, values and revision with given key prefix.
|
|
||||||
func (kv *EmbedEtcdKV) LoadWithRevision(key string) ([]string, []string, int64, error) {
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
log.Debug("LoadWithPrefix ", zap.String("prefix", key))
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, 0, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
}
|
|
||||||
return keys, values, resp.Header.Revision, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadBytesWithRevision returns keys, values and revision with given key prefix.
|
// LoadBytesWithRevision returns keys, values and revision with given key prefix.
|
||||||
func (kv *EmbedEtcdKV) LoadBytesWithRevision(key string) ([]string, [][]byte, int64, error) {
|
func (kv *EmbedEtcdKV) LoadBytesWithRevision(key string) ([]string, [][]byte, int64, error) {
|
||||||
key = path.Join(kv.rootPath, key)
|
key = path.Join(kv.rootPath, key)
|
||||||
@ -386,26 +323,6 @@ func (kv *EmbedEtcdKV) SaveBytes(key string, value []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveWithLease is a function to put value in etcd with etcd lease options.
|
|
||||||
func (kv *EmbedEtcdKV) SaveWithLease(key, value string, id clientv3.LeaseID) error {
|
|
||||||
log.Debug("Embedded Etcd saving with lease", zap.String("etcd_key", key))
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
_, err := kv.client.Put(ctx, key, value, clientv3.WithLease(id))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveWithIgnoreLease updates the key without changing its current lease.
|
|
||||||
func (kv *EmbedEtcdKV) SaveWithIgnoreLease(key, value string) error {
|
|
||||||
log.Debug("Embedded Etcd saving with ignore lease", zap.String("etcd_key", key))
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
_, err := kv.client.Put(ctx, key, value, clientv3.WithIgnoreLease())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveBytesWithLease is a function to put value in etcd with etcd lease options.
|
// SaveBytesWithLease is a function to put value in etcd with etcd lease options.
|
||||||
func (kv *EmbedEtcdKV) SaveBytesWithLease(key string, value []byte, id clientv3.LeaseID) error {
|
func (kv *EmbedEtcdKV) SaveBytesWithLease(key string, value []byte, id clientv3.LeaseID) error {
|
||||||
key = path.Join(kv.rootPath, key)
|
key = path.Join(kv.rootPath, key)
|
||||||
@ -580,56 +497,6 @@ func (kv *EmbedEtcdKV) MultiSaveBytesAndRemoveWithPrefix(saves map[string][]byte
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grant creates a new lease implemented in etcd grant interface.
|
|
||||||
func (kv *EmbedEtcdKV) Grant(ttl int64) (id clientv3.LeaseID, err error) {
|
|
||||||
resp, err := kv.client.Grant(context.Background(), ttl)
|
|
||||||
return resp.ID, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeepAlive keeps the lease alive forever with leaseID.
|
|
||||||
// Implemented in etcd interface.
|
|
||||||
func (kv *EmbedEtcdKV) KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error) {
|
|
||||||
ch, err := kv.client.KeepAlive(context.Background(), id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareValueAndSwap compares the existing value with compare, and if they are
|
|
||||||
// equal, the target is stored in etcd.
|
|
||||||
func (kv *EmbedEtcdKV) CompareValueAndSwap(key, value, target string, opts ...clientv3.OpOption) (bool, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Txn(ctx).If(
|
|
||||||
clientv3.Compare(
|
|
||||||
clientv3.Value(path.Join(kv.rootPath, key)),
|
|
||||||
"=",
|
|
||||||
value)).
|
|
||||||
Then(clientv3.OpPut(path.Join(kv.rootPath, key), target, opts...)).Commit()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return resp.Succeeded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareValueAndSwapBytes compares the existing value with compare, and if they are
|
|
||||||
// equal, the target is stored in etcd.
|
|
||||||
func (kv *EmbedEtcdKV) CompareValueAndSwapBytes(key string, value, target []byte, opts ...clientv3.OpOption) (bool, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Txn(ctx).If(
|
|
||||||
clientv3.Compare(
|
|
||||||
clientv3.Value(path.Join(kv.rootPath, key)),
|
|
||||||
"=",
|
|
||||||
string(value))).
|
|
||||||
Then(clientv3.OpPut(path.Join(kv.rootPath, key), string(target), opts...)).Commit()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return resp.Succeeded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareVersionAndSwap compares the existing key-value's version with version, and if
|
// CompareVersionAndSwap compares the existing key-value's version with version, and if
|
||||||
// they are equal, the target is stored in etcd.
|
// they are equal, the target is stored in etcd.
|
||||||
func (kv *EmbedEtcdKV) CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
func (kv *EmbedEtcdKV) CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
||||||
|
|||||||
@ -20,12 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cockroachdb/errors"
|
"github.com/cockroachdb/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
clientv3 "go.etcd.io/etcd/client/v3"
|
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
|
|
||||||
embed_etcd_kv "github.com/milvus-io/milvus/internal/kv/etcd"
|
embed_etcd_kv "github.com/milvus-io/milvus/internal/kv/etcd"
|
||||||
@ -122,19 +120,6 @@ func TestEmbedEtcd(te *testing.T) {
|
|||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
||||||
assert.Equal(t, test.expectedError, err)
|
assert.Equal(t, test.expectedError, err)
|
||||||
|
|
||||||
actualKeys, actualValues, versions, err := metaKv.LoadWithPrefix2(test.prefix)
|
|
||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
|
||||||
assert.NotZero(t, versions)
|
|
||||||
assert.Equal(t, test.expectedError, err)
|
|
||||||
|
|
||||||
actualKeys, actualValues, versions, revision, err := metaKv.LoadWithRevisionAndVersions(test.prefix)
|
|
||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
|
||||||
assert.NotZero(t, versions)
|
|
||||||
assert.NotZero(t, revision)
|
|
||||||
assert.Equal(t, test.expectedError, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTests := []struct {
|
removeTests := []struct {
|
||||||
@ -272,51 +257,6 @@ func TestEmbedEtcd(te *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
te.Run("EtcdKV LoadWithRevision", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/LoadWithRevision"
|
|
||||||
metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
defer metaKv.Close()
|
|
||||||
defer metaKv.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
prepareKV := []struct {
|
|
||||||
inKey string
|
|
||||||
inValue string
|
|
||||||
}{
|
|
||||||
{"a", "a_version1"},
|
|
||||||
{"b", "b_version2"},
|
|
||||||
{"a", "a_version3"},
|
|
||||||
{"c", "c_version4"},
|
|
||||||
{"a/suba", "a_version5"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range prepareKV {
|
|
||||||
err = metaKv.Save(test.inKey, test.inValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
loadWithRevisionTests := []struct {
|
|
||||||
inKey string
|
|
||||||
|
|
||||||
expectedKeyNo int
|
|
||||||
expectedValues []string
|
|
||||||
}{
|
|
||||||
{"a", 2, []string{"a_version3", "a_version5"}},
|
|
||||||
{"b", 1, []string{"b_version2"}},
|
|
||||||
{"c", 1, []string{"c_version4"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range loadWithRevisionTests {
|
|
||||||
keys, values, revision, err := metaKv.LoadWithRevision(test.inKey)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, test.expectedKeyNo, len(keys))
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, values)
|
|
||||||
assert.NotZero(t, revision)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("EtcdKV LoadBytesWithRevision", func(t *testing.T) {
|
te.Run("EtcdKV LoadBytesWithRevision", func(t *testing.T) {
|
||||||
rootPath := "/etcd/test/root/LoadBytesWithRevision"
|
rootPath := "/etcd/test/root/LoadBytesWithRevision"
|
||||||
_metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
_metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
||||||
@ -776,61 +716,6 @@ func TestEmbedEtcd(te *testing.T) {
|
|||||||
assert.True(t, resp.Created)
|
assert.True(t, resp.Created)
|
||||||
})
|
})
|
||||||
|
|
||||||
te.Run("Etcd Revision", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/watch"
|
|
||||||
metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
defer metaKv.Close()
|
|
||||||
defer metaKv.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
revisionTests := []struct {
|
|
||||||
inKey string
|
|
||||||
fistValue string
|
|
||||||
secondValue string
|
|
||||||
}{
|
|
||||||
{"a", "v1", "v11"},
|
|
||||||
{"y", "v2", "v22"},
|
|
||||||
{"z", "v3", "v33"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range revisionTests {
|
|
||||||
err = metaKv.Save(test.inKey, test.fistValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
_, _, revision, _ := metaKv.LoadWithRevision(test.inKey)
|
|
||||||
ch := metaKv.WatchWithRevision(test.inKey, revision+1)
|
|
||||||
|
|
||||||
err = metaKv.Save(test.inKey, test.secondValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
resp := <-ch
|
|
||||||
assert.Equal(t, 1, len(resp.Events))
|
|
||||||
assert.Equal(t, test.secondValue, string(resp.Events[0].Kv.Value))
|
|
||||||
assert.Equal(t, revision+1, resp.Header.Revision)
|
|
||||||
}
|
|
||||||
|
|
||||||
success, err := metaKv.CompareVersionAndSwap("a/b/c", 0, "1")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, success)
|
|
||||||
|
|
||||||
value, err := metaKv.Load("a/b/c")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, value, "1")
|
|
||||||
|
|
||||||
success, err = metaKv.CompareVersionAndSwap("a/b/c", 0, "1")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
|
|
||||||
success, err = metaKv.CompareValueAndSwap("a/b/c", "1", "2")
|
|
||||||
assert.True(t, success)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
success, err = metaKv.CompareValueAndSwap("a/b/c", "1", "2")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Revision Bytes", func(t *testing.T) {
|
te.Run("Etcd Revision Bytes", func(t *testing.T) {
|
||||||
rootPath := "/etcd/test/root/revision_bytes"
|
rootPath := "/etcd/test/root/revision_bytes"
|
||||||
_metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
_metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
||||||
@ -877,86 +762,6 @@ func TestEmbedEtcd(te *testing.T) {
|
|||||||
success, err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
|
success, err = metaKv.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.False(t, success)
|
assert.False(t, success)
|
||||||
|
|
||||||
success, err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
|
|
||||||
assert.True(t, success)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
success, err = metaKv.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Lease", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/lease"
|
|
||||||
metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
defer metaKv.Close()
|
|
||||||
defer metaKv.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
leaseID, err := metaKv.Grant(10)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
metaKv.KeepAlive(leaseID)
|
|
||||||
|
|
||||||
tests := map[string]string{
|
|
||||||
"a/b": "v1",
|
|
||||||
"a/b/c": "v2",
|
|
||||||
"x": "v3",
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range tests {
|
|
||||||
// SaveWithIgnoreLease must be used when the key already exists.
|
|
||||||
err = metaKv.SaveWithIgnoreLease(k, v)
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
err = metaKv.SaveWithLease(k, v, leaseID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = metaKv.SaveWithLease(k, v, clientv3.LeaseID(999))
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Lease Ignore", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/lease_ignore"
|
|
||||||
metaKv, err := embed_etcd_kv.NewMetaKvFactory(rootPath, ¶m.EtcdCfg)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
defer metaKv.Close()
|
|
||||||
defer metaKv.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
tests := map[string]string{
|
|
||||||
"a/b": "v1",
|
|
||||||
"a/b/c": "v2",
|
|
||||||
"x": "v3",
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range tests {
|
|
||||||
leaseID, err := metaKv.Grant(1)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = metaKv.SaveWithLease(k, v, leaseID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = metaKv.SaveWithIgnoreLease(k, "updated_"+v)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// Record should be updated correctly.
|
|
||||||
value, err := metaKv.Load(k)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "updated_"+v, value)
|
|
||||||
|
|
||||||
// Let the lease expire. 3 seconds should be pretty safe.
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
// Updated record should still expire with lease.
|
|
||||||
_, err = metaKv.Load(k)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
te.Run("Etcd WalkWithPagination", func(t *testing.T) {
|
te.Run("Etcd WalkWithPagination", func(t *testing.T) {
|
||||||
|
|||||||
@ -140,51 +140,6 @@ func (kv *EtcdKV) LoadBytesWithPrefix(key string) ([]string, [][]byte, error) {
|
|||||||
return keys, values, nil
|
return keys, values, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadWithPrefix2 returns all the the keys,values and key versions with the given key prefix.
|
|
||||||
func (kv *EtcdKV) LoadWithPrefix2(key string) ([]string, []string, []int64, error) {
|
|
||||||
start := time.Now()
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
versions := make([]int64, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
versions = append(versions, kv.Version)
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation load with prefix2", zap.Strings("keys", keys))
|
|
||||||
return keys, values, versions, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (kv *EtcdKV) LoadWithRevisionAndVersions(key string) ([]string, []string, []int64, int64, error) {
|
|
||||||
start := time.Now()
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, 0, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
versions := make([]int64, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
versions = append(versions, kv.Version)
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation load with prefix2", zap.Strings("keys", keys))
|
|
||||||
return keys, values, versions, resp.Header.Revision, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadBytesWithPrefix2 returns all the the keys,values and key versions with the given key prefix.
|
// LoadBytesWithPrefix2 returns all the the keys,values and key versions with the given key prefix.
|
||||||
func (kv *EtcdKV) LoadBytesWithPrefix2(key string) ([]string, [][]byte, []int64, error) {
|
func (kv *EtcdKV) LoadBytesWithPrefix2(key string) ([]string, [][]byte, []int64, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@ -312,27 +267,6 @@ func (kv *EtcdKV) MultiLoadBytes(keys []string) ([][]byte, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadWithRevision returns keys, values and revision with given key prefix.
|
|
||||||
func (kv *EtcdKV) LoadWithRevision(key string) ([]string, []string, int64, error) {
|
|
||||||
start := time.Now()
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Get(ctx, key, clientv3.WithPrefix(),
|
|
||||||
clientv3.WithSort(clientv3.SortByCreateRevision, clientv3.SortAscend))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, 0, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, resp.Count)
|
|
||||||
values := make([]string, 0, resp.Count)
|
|
||||||
for _, kv := range resp.Kvs {
|
|
||||||
keys = append(keys, string(kv.Key))
|
|
||||||
values = append(values, string(kv.Value))
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation load with revision", zap.Strings("keys", keys))
|
|
||||||
return keys, values, resp.Header.Revision, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadBytesWithRevision returns keys, values and revision with given key prefix.
|
// LoadBytesWithRevision returns keys, values and revision with given key prefix.
|
||||||
func (kv *EtcdKV) LoadBytesWithRevision(key string) ([]string, [][]byte, int64, error) {
|
func (kv *EtcdKV) LoadBytesWithRevision(key string) ([]string, [][]byte, int64, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@ -378,32 +312,6 @@ func (kv *EtcdKV) SaveBytes(key string, value []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveWithLease is a function to put value in etcd with etcd lease options.
|
|
||||||
func (kv *EtcdKV) SaveWithLease(key, value string, id clientv3.LeaseID) error {
|
|
||||||
log.Debug("Etcd saving with lease", zap.String("etcd_key", key))
|
|
||||||
start := time.Now()
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
CheckValueSizeAndWarn(key, value)
|
|
||||||
_, err := kv.client.Put(ctx, key, value, clientv3.WithLease(id))
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation save with lease", zap.String("key", key))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveWithIgnoreLease updates the key without changing its current lease. Must be used when key already exists.
|
|
||||||
func (kv *EtcdKV) SaveWithIgnoreLease(key, value string) error {
|
|
||||||
log.Debug("Etcd saving with ignore lease", zap.String("etcd_key", key))
|
|
||||||
start := time.Now()
|
|
||||||
key = path.Join(kv.rootPath, key)
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
CheckValueSizeAndWarn(key, value)
|
|
||||||
_, err := kv.client.Put(ctx, key, value, clientv3.WithIgnoreLease())
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation save with lease", zap.String("key", key))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveBytesWithLease is a function to put value in etcd with etcd lease options.
|
// SaveBytesWithLease is a function to put value in etcd with etcd lease options.
|
||||||
func (kv *EtcdKV) SaveBytesWithLease(key string, value []byte, id clientv3.LeaseID) error {
|
func (kv *EtcdKV) SaveBytesWithLease(key string, value []byte, id clientv3.LeaseID) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@ -669,64 +577,6 @@ func (kv *EtcdKV) MultiSaveBytesAndRemoveWithPrefix(saves map[string][]byte, rem
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grant creates a new lease implemented in etcd grant interface.
|
|
||||||
func (kv *EtcdKV) Grant(ttl int64) (id clientv3.LeaseID, err error) {
|
|
||||||
start := time.Now()
|
|
||||||
resp, err := kv.client.Grant(context.Background(), ttl)
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation grant")
|
|
||||||
return resp.ID, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeepAlive keeps the lease alive forever with leaseID.
|
|
||||||
// Implemented in etcd interface.
|
|
||||||
func (kv *EtcdKV) KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error) {
|
|
||||||
start := time.Now()
|
|
||||||
ch, err := kv.client.KeepAlive(context.Background(), id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation keepAlive")
|
|
||||||
return ch, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareValueAndSwap compares the existing value with compare, and if they are
|
|
||||||
// equal, the target is stored in etcd.
|
|
||||||
func (kv *EtcdKV) CompareValueAndSwap(key, value, target string, opts ...clientv3.OpOption) (bool, error) {
|
|
||||||
start := time.Now()
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Txn(ctx).If(
|
|
||||||
clientv3.Compare(
|
|
||||||
clientv3.Value(path.Join(kv.rootPath, key)),
|
|
||||||
"=",
|
|
||||||
value)).
|
|
||||||
Then(clientv3.OpPut(path.Join(kv.rootPath, key), target, opts...)).Commit()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation compare value and swap", zap.String("key", key))
|
|
||||||
return resp.Succeeded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareValueAndSwapBytes compares the existing value with compare, and if they are
|
|
||||||
// equal, the target is stored in etcd.
|
|
||||||
func (kv *EtcdKV) CompareValueAndSwapBytes(key string, value, target []byte, opts ...clientv3.OpOption) (bool, error) {
|
|
||||||
start := time.Now()
|
|
||||||
ctx, cancel := context.WithTimeout(context.TODO(), RequestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := kv.client.Txn(ctx).If(
|
|
||||||
clientv3.Compare(
|
|
||||||
clientv3.Value(path.Join(kv.rootPath, key)),
|
|
||||||
"=",
|
|
||||||
string(value))).
|
|
||||||
Then(clientv3.OpPut(path.Join(kv.rootPath, key), string(target), opts...)).Commit()
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
CheckElapseAndWarn(start, "Slow etcd operation compare value and swap", zap.String("key", key))
|
|
||||||
return resp.Succeeded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareVersionAndSwap compares the existing key-value's version with version, and if
|
// CompareVersionAndSwap compares the existing key-value's version with version, and if
|
||||||
// they are equal, the target is stored in etcd.
|
// they are equal, the target is stored in etcd.
|
||||||
func (kv *EtcdKV) CompareVersionAndSwap(key string, source int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
func (kv *EtcdKV) CompareVersionAndSwap(key string, source int64, target string, opts ...clientv3.OpOption) (bool, error) {
|
||||||
|
|||||||
@ -26,7 +26,6 @@ import (
|
|||||||
"github.com/cockroachdb/errors"
|
"github.com/cockroachdb/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
clientv3 "go.etcd.io/etcd/client/v3"
|
|
||||||
"golang.org/x/exp/maps"
|
"golang.org/x/exp/maps"
|
||||||
|
|
||||||
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
||||||
@ -131,19 +130,6 @@ func TestEtcdKV_Load(te *testing.T) {
|
|||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
||||||
assert.Equal(t, test.expectedError, err)
|
assert.Equal(t, test.expectedError, err)
|
||||||
|
|
||||||
actualKeys, actualValues, versions, err := etcdKV.LoadWithPrefix2(test.prefix)
|
|
||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
|
||||||
assert.NotZero(t, versions)
|
|
||||||
assert.Equal(t, test.expectedError, err)
|
|
||||||
|
|
||||||
actualKeys, actualValues, versions, revision, err := etcdKV.LoadWithRevisionAndVersions(test.prefix)
|
|
||||||
assert.ElementsMatch(t, test.expectedKeys, actualKeys)
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, actualValues)
|
|
||||||
assert.NotZero(t, versions)
|
|
||||||
assert.NotZero(t, revision)
|
|
||||||
assert.Equal(t, test.expectedError, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTests := []struct {
|
removeTests := []struct {
|
||||||
@ -287,52 +273,8 @@ func TestEtcdKV_Load(te *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
te.Run("EtcdKV LoadWithRevision", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/LoadWithRevision"
|
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
|
||||||
|
|
||||||
defer etcdKV.Close()
|
|
||||||
defer etcdKV.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
prepareKV := []struct {
|
|
||||||
inKey string
|
|
||||||
inValue string
|
|
||||||
}{
|
|
||||||
{"a", "a_version1"},
|
|
||||||
{"b", "b_version2"},
|
|
||||||
{"a", "a_version3"},
|
|
||||||
{"c", "c_version4"},
|
|
||||||
{"a/suba", "a_version5"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range prepareKV {
|
|
||||||
err = etcdKV.Save(test.inKey, test.inValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
loadWithRevisionTests := []struct {
|
|
||||||
inKey string
|
|
||||||
|
|
||||||
expectedKeyNo int
|
|
||||||
expectedValues []string
|
|
||||||
}{
|
|
||||||
{"a", 2, []string{"a_version3", "a_version5"}},
|
|
||||||
{"b", 1, []string{"b_version2"}},
|
|
||||||
{"c", 1, []string{"c_version4"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range loadWithRevisionTests {
|
|
||||||
keys, values, revision, err := etcdKV.LoadWithRevision(test.inKey)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, test.expectedKeyNo, len(keys))
|
|
||||||
assert.ElementsMatch(t, test.expectedValues, values)
|
|
||||||
assert.NotZero(t, revision)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("EtcdKV LoadBytesWithRevision", func(t *testing.T) {
|
te.Run("EtcdKV LoadBytesWithRevision", func(t *testing.T) {
|
||||||
rootPath := "/etcd/test/root/LoadWithRevision"
|
rootPath := "/etcd/test/root/LoadBytesWithRevision"
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
||||||
|
|
||||||
defer etcdKV.Close()
|
defer etcdKV.Close()
|
||||||
@ -711,59 +653,6 @@ func TestEtcdKV_Load(te *testing.T) {
|
|||||||
assert.True(t, resp.Created)
|
assert.True(t, resp.Created)
|
||||||
})
|
})
|
||||||
|
|
||||||
te.Run("Etcd Revision", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/revision"
|
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
|
||||||
defer etcdKV.Close()
|
|
||||||
defer etcdKV.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
revisionTests := []struct {
|
|
||||||
inKey string
|
|
||||||
fistValue string
|
|
||||||
secondValue string
|
|
||||||
}{
|
|
||||||
{"a", "v1", "v11"},
|
|
||||||
{"y", "v2", "v22"},
|
|
||||||
{"z", "v3", "v33"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range revisionTests {
|
|
||||||
err = etcdKV.Save(test.inKey, test.fistValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
_, _, revision, _ := etcdKV.LoadWithRevision(test.inKey)
|
|
||||||
ch := etcdKV.WatchWithRevision(test.inKey, revision+1)
|
|
||||||
|
|
||||||
err = etcdKV.Save(test.inKey, test.secondValue)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
resp := <-ch
|
|
||||||
assert.Equal(t, 1, len(resp.Events))
|
|
||||||
assert.Equal(t, test.secondValue, string(resp.Events[0].Kv.Value))
|
|
||||||
assert.Equal(t, revision+1, resp.Header.Revision)
|
|
||||||
}
|
|
||||||
|
|
||||||
success, err := etcdKV.CompareVersionAndSwap("a/b/c", 0, "1")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.True(t, success)
|
|
||||||
|
|
||||||
value, err := etcdKV.Load("a/b/c")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, value, "1")
|
|
||||||
|
|
||||||
success, err = etcdKV.CompareVersionAndSwap("a/b/c", 0, "1")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
|
|
||||||
success, err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2")
|
|
||||||
assert.True(t, success)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
success, err = etcdKV.CompareValueAndSwap("a/b/c", "1", "2")
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Revision Bytes", func(t *testing.T) {
|
te.Run("Etcd Revision Bytes", func(t *testing.T) {
|
||||||
rootPath := "/etcd/test/root/revision_bytes"
|
rootPath := "/etcd/test/root/revision_bytes"
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
||||||
@ -807,109 +696,6 @@ func TestEtcdKV_Load(te *testing.T) {
|
|||||||
success, err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
|
success, err = etcdKV.CompareVersionAndSwapBytes("a/b/c", 0, []byte("1"))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.False(t, success)
|
assert.False(t, success)
|
||||||
|
|
||||||
success, err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
|
|
||||||
assert.True(t, success)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
success, err = etcdKV.CompareValueAndSwapBytes("a/b/c", []byte("1"), []byte("2"))
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.False(t, success)
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Lease", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/lease"
|
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
|
||||||
|
|
||||||
defer etcdKV.Close()
|
|
||||||
defer etcdKV.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
leaseID, err := etcdKV.Grant(10)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
etcdKV.KeepAlive(leaseID)
|
|
||||||
|
|
||||||
tests := map[string]string{
|
|
||||||
"a/b": "v1",
|
|
||||||
"a/b/c": "v2",
|
|
||||||
"x": "v3",
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range tests {
|
|
||||||
// SaveWithIgnoreLease must be used when the key already exists.
|
|
||||||
err = etcdKV.SaveWithIgnoreLease(k, v)
|
|
||||||
assert.Error(t, err)
|
|
||||||
|
|
||||||
err = etcdKV.SaveWithLease(k, v, leaseID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = etcdKV.SaveWithLease(k, v, clientv3.LeaseID(999))
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Lease Ignore", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/lease_ignore"
|
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
|
||||||
|
|
||||||
defer etcdKV.Close()
|
|
||||||
defer etcdKV.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
tests := map[string]string{
|
|
||||||
"a/b": "v1",
|
|
||||||
"a/b/c": "v2",
|
|
||||||
"x": "v3",
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range tests {
|
|
||||||
leaseID, err := etcdKV.Grant(1)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = etcdKV.SaveWithLease(k, v, leaseID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = etcdKV.SaveWithIgnoreLease(k, "updated_"+v)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
// Record should be updated correctly.
|
|
||||||
value, err := etcdKV.Load(k)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "updated_"+v, value)
|
|
||||||
|
|
||||||
// Let the lease expire. 3 seconds should be pretty safe.
|
|
||||||
time.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
// Updated record should still expire with lease.
|
|
||||||
_, err = etcdKV.Load(k)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
te.Run("Etcd Lease Bytes", func(t *testing.T) {
|
|
||||||
rootPath := "/etcd/test/root/lease_bytes"
|
|
||||||
etcdKV := etcdkv.NewEtcdKV(etcdCli, rootPath)
|
|
||||||
|
|
||||||
defer etcdKV.Close()
|
|
||||||
defer etcdKV.RemoveWithPrefix("")
|
|
||||||
|
|
||||||
leaseID, err := etcdKV.Grant(10)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
etcdKV.KeepAlive(leaseID)
|
|
||||||
|
|
||||||
tests := map[string][]byte{
|
|
||||||
"a/b": []byte("v1"),
|
|
||||||
"a/b/c": []byte("v2"),
|
|
||||||
"x": []byte("v3"),
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range tests {
|
|
||||||
err = etcdKV.SaveBytesWithLease(k, v, leaseID)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = etcdKV.SaveBytesWithLease(k, v, clientv3.LeaseID(999))
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,17 +67,9 @@ type MetaKv interface {
|
|||||||
TxnKV
|
TxnKV
|
||||||
GetPath(key string) string
|
GetPath(key string) string
|
||||||
LoadWithPrefix(key string) ([]string, []string, error)
|
LoadWithPrefix(key string) ([]string, []string, error)
|
||||||
LoadWithPrefix2(key string) ([]string, []string, []int64, error)
|
|
||||||
LoadWithRevisionAndVersions(key string) ([]string, []string, []int64, int64, error)
|
|
||||||
LoadWithRevision(key string) ([]string, []string, int64, error)
|
|
||||||
Watch(key string) clientv3.WatchChan
|
Watch(key string) clientv3.WatchChan
|
||||||
WatchWithPrefix(key string) clientv3.WatchChan
|
WatchWithPrefix(key string) clientv3.WatchChan
|
||||||
WatchWithRevision(key string, revision int64) clientv3.WatchChan
|
WatchWithRevision(key string, revision int64) clientv3.WatchChan
|
||||||
SaveWithLease(key, value string, id clientv3.LeaseID) error
|
|
||||||
SaveWithIgnoreLease(key, value string) error
|
|
||||||
Grant(ttl int64) (id clientv3.LeaseID, err error)
|
|
||||||
KeepAlive(id clientv3.LeaseID) (<-chan *clientv3.LeaseKeepAliveResponse, error)
|
|
||||||
CompareValueAndSwap(key, value, target string, opts ...clientv3.OpOption) (bool, error)
|
|
||||||
CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error)
|
CompareVersionAndSwap(key string, version int64, target string, opts ...clientv3.OpOption) (bool, error)
|
||||||
WalkWithPrefix(prefix string, paginationSize int, fn func([]byte, []byte) error) error
|
WalkWithPrefix(prefix string, paginationSize int, fn func([]byte, []byte) error) error
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,6 @@ import (
|
|||||||
|
|
||||||
"github.com/milvus-io/milvus-proto/go-api/commonpb"
|
"github.com/milvus-io/milvus-proto/go-api/commonpb"
|
||||||
grpcquerynodeclient "github.com/milvus-io/milvus/internal/distributed/querynode/client"
|
grpcquerynodeclient "github.com/milvus-io/milvus/internal/distributed/querynode/client"
|
||||||
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
|
||||||
"github.com/milvus-io/milvus/internal/querynodev2/cluster"
|
"github.com/milvus-io/milvus/internal/querynodev2/cluster"
|
||||||
"github.com/milvus-io/milvus/internal/querynodev2/delegator"
|
"github.com/milvus-io/milvus/internal/querynodev2/delegator"
|
||||||
"github.com/milvus-io/milvus/internal/querynodev2/pipeline"
|
"github.com/milvus-io/milvus/internal/querynodev2/pipeline"
|
||||||
@ -118,7 +117,6 @@ type QueryNode struct {
|
|||||||
|
|
||||||
cacheChunkManager storage.ChunkManager
|
cacheChunkManager storage.ChunkManager
|
||||||
vectorStorage storage.ChunkManager
|
vectorStorage storage.ChunkManager
|
||||||
etcdKV *etcdkv.EtcdKV
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Pool for search/query
|
// Pool for search/query
|
||||||
@ -274,7 +272,6 @@ func (node *QueryNode) Init() error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
node.etcdKV = etcdkv.NewEtcdKV(node.etcdCli, paramtable.Get().EtcdCfg.MetaRootPath.GetValue())
|
|
||||||
log.Info("queryNode try to connect etcd success", zap.String("MetaRootPath", paramtable.Get().EtcdCfg.MetaRootPath.GetValue()))
|
log.Info("queryNode try to connect etcd success", zap.String("MetaRootPath", paramtable.Get().EtcdCfg.MetaRootPath.GetValue()))
|
||||||
|
|
||||||
node.scheduler = tasks.NewScheduler()
|
node.scheduler = tasks.NewScheduler()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user