etcd watch:etcd 如何实现 watch 机制?

举报
aoho 发表于 2022/04/22 00:11:54 2022/04/22
【摘要】 etcd watch:etcd 如何实现 watch 机制?你好,我是 aoho,今天我和你分享的主题是 etcd watch:etcd 如何实现 watch 机制?etcd v2 和 v3 版本之间的重要变化之一就是 watch 机制的优化。etcd v2 watch 机制采用的是基于 HTTP/1.x 协议的客户端轮询机制,历史版本存储则是通过滑动窗口。在大量的客户端连接的场景或者...

etcd watch:etcd 如何实现 watch 机制?

你好,我是 aoho,今天我和你分享的主题是 etcd watch:etcd 如何实现 watch 机制?

etcd v2 和 v3 版本之间的重要变化之一就是 watch 机制的优化。etcd v2 watch 机制采用的是基于 HTTP/1.x 协议的客户端轮询机制,历史版本存储则是通过滑动窗口。在大量的客户端连接的场景或者集群规模较大的场景,导致 etcd 服务端的扩展性和稳定性都无法保证。etcd v3 在此基础上进行优化,满足了 Kubernetes pods 部署和状态管理等业务场景诉求。

watch 是监听一个或一组 key,key 的任何变化都会发出消息。某种意义上讲,etcd 就是发布订阅模式。

Watch 的用法

在具体将讲解 Watch 的实现方式之前,我们先来体验下如何使用 Watch。通过 etcdctl 命令行工具实现键值对的检测:

$ etcdctl put hello aoho
$ etcdctl put hello boho
$ etcdctl watch hello -w=json --rev=1

{
	"Header": {
		"cluster_id": 14841639068965178418,
		"member_id": 10276657743932975437,
		"revision": 4,
		"raft_term": 4
	},
	"Events": [{
		"kv": {
			"key": "aGVsbG8=",
			"create_revision": 3,
			"mod_revision": 3,
			"version": 1,
			"value": "YW9obw=="
		}
	}, {
		"kv": {
			"key": "aGVsbG8=",
			"create_revision": 3,
			"mod_revision": 4,
			"version": 2,
			"value": "Ym9obw=="
		}
	}],
	"CompactRevision": 0,
	"Canceled": false,
	"Created": false
}

依次在命令行中输入上面三条命令,前面两条依次更新 hello 对应的值,第三条命令监测键为 hello 的变化,并指定版本号从 1 开始。结果输出了两条 watch 事件。我们接着在另一个命令行继续输入如下的更新命令:

$ etcdctl put hello coho

可以看到前一个命令行输出了如下的内容:

{
	"Header": {
		"cluster_id": 14841639068965178418,
		"member_id": 10276657743932975437,
		"revision": 5,
		"raft_term": 4
	},
	"Events": [{
		"kv": {
			"key": "aGVsbG8=",
			"create_revision": 3,
			"mod_revision": 5,
			"version": 3,
			"value": "Y29obw=="
		}
	}],
	"CompactRevision": 0,
	"Canceled": false,
	"Created": false
}

命令行输出的事件表明,键 hello 对应的键值对发生了更新,并输出了事件的详细信息。如上就是通过 etcdctl 客户端工具实现 watch 指定的键值对功能。接着我们看下,clientv3 中是如何实现 watch 功能。

func testWatch() {
    s := newWatchableStore()

    w := s.NewWatchStream()

    w.Watch(start_key: foo, end_key: nil)

    w.Watch(start_key: bar, end_key: nil)

    for {
        consume := <- w.Chan()
    }
}

etcd 的 mvcc 模块对外提供了两种访问键值对的实现,一种是键值存储 kvstore,另一种是 watchableStore。它们都实现了 KV 接口,KV 接口的具体实现则是 store 结构体。在上面的实现中,我们先调用了 watchableStore。

当我们要使用 Watch 功能时,我们创建了一个 watchStream。创建出来的 w 可以监听的键为 hello,之后我们就可以消费 w.Chan() 返回的 channel。键为 hello 的任何变化,都会通过这个 channel 发送给客户端。

可以看到 watchStream 实现了在大量 kv 的变化中,过滤出当前所监听的 key,将 key 的变化输出。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。