Go语言对etcd的基本操作

  本文简单介绍Go语言对etcd v3的基本操作。

1. Import package
1
2
3
4
import (
    "github.com/coreos/etcd/clientv3"
    "github.com/coreos/etcd/mvcc/mvccpb"
)

 

2. Declare Variables
1
2
3
4
5
6
7
8
9
10
11
var cli *clientv3.Client
 
var serverList = []string{
    "192.168.3.102:2379",
    "192.168.3.105:2379",
    "192.168.3.103:2379",
}
var userName = "root"
var password = "shiajun666"
var dialTimeout = 5
var opTimeout = 5

 

3. Connect to etcd server
1
2
3
4
5
6
7
8
9
10
11
var err error
cli, err := clientv3.New(clientv3.Config{
    Endpoints:   serverList,
    DialTimeout: time.Duration(dialTimeout) * time.Second,
    Username:    userName,
    Password:    password,
})
if err != nil {
    fmt.Println("Connect etcd server failed: ", err)
    return
}

 

4. Get
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
key := "name"
resp, err := cli.Get(ctx, key)
if err != nil {
    fmt.Printf("Get key[%s] failed: %v\n", key, err)
    return
}
if len(resp.Kvs) == 0 {
    fmt.Printf("Key[%s] not exists.\n", key)
    return
}
 
fmt.Println("value: ", string(resp.Kvs[0].Value))
Get 方法的返回值如下:
其中 Header *ResponseHeader 几乎是etcd所有方法返回值中都会包含的,它包含了集群ID、etcd节点成员ID、key全局版本号、raft任期号:
Kvs []*mvccpb.KeyValue 包含多个键值对的信息,几乎etcd所有方法返回的键值对信息都由 mvccpb.KeyValue 表示,其结构如下:
 
5. Get values according to key prefix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
prefix := "name"
resp, err := cli.Get(ctx, prefix, clientv3.WithPrefix())
if err != nil {
    fmt.Printf("Get key prefix[%s] failed: %v\n", prefix, err)
    return
}
if len(resp.Kvs) == 0 {
    fmt.Printf("Key prefix[%s] not exists.\n", prefix)
    return
}
 
fmt.Println("values: ", resp.Kvs)

 

6. put
1
2
3
4
5
6
7
8
9
10
11
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
key := "name"
value := "shiajun"
_, err = cli.Put(ctx, key, value)
if err != nil {
    fmt.Printf("Put key[%s] value[%s] failed: %v\n", key, value, err)
    return
}
fmt.Println("put success")
Put 方法返回值如下:
prevKv 表示当前Put操作执行之前该key的键值对信息,Put方法第四个参数加上 clientv3.WithPrevKV() 即可返回该信息,如下一个例子所示。
 
7. put new value and get prev value
1
2
3
4
5
6
7
8
9
10
11
12
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
key := "name"
value := "shiajun"
opts := []clientv3.OpOption{clientv3.WithPrevKV()}
resp, err := cli.Put(ctx, key, value, opts...)
if err != nil {
    fmt.Printf("Put key[%s] value[%s] failed: %v\n", key, value, err)
    return
}
fmt.Println("prev value: ", string(resp.PrevKv.Value))

 

8. put with lease
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
//grant lease
var ttl int64 = 10
lease, err := cli.Grant(ctx, ttl)
if err != nil {
    fmt.Printf("Grant lease failed: %v\n", err)
}
 
//put with lease
key := "name"
value := "shiajun"
_, err = cli.Put(ctx, key, value, clientv3.WithLease(lease.ID))
if err != nil {
    fmt.Printf("Put key[%s] value[%s] with lease[%s] failed: %v\n", key, value, lease.ID, err)
}
 
fmt.Println("put with lease success")
Grant 方法返回值如下:
 
 
9. put with lease and keep alive
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
//grant lease
var ttl int64 = 10
lease, err := cli.Grant(ctx, ttl)
if err != nil {
    fmt.Printf("Grant lease failed: %v\n", err)
}
 
//put with lease
key := "name"
value := "shiajun"
_, err = cli.Put(ctx, key, value, clientv3.WithLease(lease.ID))
if err != nil {
    fmt.Printf("Put key[%s] value[%s] with lease[%s] failed: %v\n", key, value, lease.ID, err)
}
 
//keep alive
kaCh, err := cli.KeepAlive(context.Background(), lease.ID)
if err != nil {
    fmt.Printf("Keep alive key[%s] value[%s] with lease[%s] failed: %v\n", key, value, lease.ID, err)
}
for {
    kaResp := <-kaCh
    fmt.Println("ttl: ", kaResp.TTL)
}
KeepAlive 方法返回值为一个channel:<-chan *LeaseKeepAliveResponse,接收每一次 keep alive 的结果返回:
 
10. delete
1
2
3
4
5
6
7
8
9
10
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
key := "name"
_, err = cli.Delete(ctx, key)
if err != nil {
    fmt.Printf("Delete key[%s] failed: %v\n", key, err)
    return
}
fmt.Println("delete success")
Delete 方法返回值如下:
 
11. watch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
key := "name"
opts := []clientv3.OpOption{clientv3.WithPrevKV(), clientv3.WithPrefix()}
wCh := cli.Watch(context.Background(), key, opts...)
for resp := range wCh {
    for _, event := range resp.Events {
        if event.Type == mvccpb.PUT {
            fmt.Println("put happens")
        } else if event.Type == mvccpb.DELETE {
            fmt.Println("delete happens")
        }
        fmt.Println("prev value: ", event.PrevKv)
        fmt.Println("value: ", event.Kv)
    }
}
Watch 方法返回值为一个Channel:<-chan WatchResponse,接收watch的结果信息:
对watch的key进行put、delete操作,watch操作即可获得变更结果,示例如下:
 
12. compare and set - transation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(opTimeout)*time.Second)
defer cancel()
 
key := "number"
kvc := clientv3.NewKV(cli)
resp, err := kvc.Txn(ctx).
    If(clientv3.Compare(clientv3.Value(key), ">", "0")).
    Then(clientv3.OpPut(key, "100")).
    Else(clientv3.OpPut(key, "99")).
    Commit()
if err != nil {
    fmt.Errorf("Compare and set transation failed: %v\n", err)
}
 
fmt.Println(resp.Succeeded)
这是使用etcd事务实现的一个先比较再赋值的简单例子:若 number 的值大于0,则将number赋值为100,否则赋值为99。
 
 

posted @   疯一样的狼人  阅读(992)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示