作者回复: 是的,一定会查,这性能开销很低的。正如我文章中所介绍的,有两类watcher, 一类是监听一个key的watcher,这种直接使用map来保存,也就是检查这个key是否有相关watcher,时间复杂度是o(1),另一类是监听整个区间的watcher,查找这个key落在了哪些watcher监听的范围,一般情况下,时间复杂度o(log n), n是你创建的watcher数。而你建议的方案,使用key结构体记录一个watcher id数组,这在key非常多的情况下,内存开销是非常大,假设一个watcher监听了一个非常大的key范围,那么etcd创建此watcher的时候,还需要遍历这个key范围,给key增加相应的watcher id, 不仅内存,cpu开销也是不可忽略的。 在哪些场景下watcher事件通知性能会非常慢呢?如果你成千上万个watcher,监听同一个key或者范围时,就会导致性能极差。
作者回复: 好问题,整个watch链路的可靠性,不能光靠server,从业务逻辑正确使用watch api到client watch中断重试机制,再到本讲介绍的server推送机制,层层相连才能尽量保证watch事件可靠性。如果机器重启了,这时就依赖client库的重试机制了,client收到每个watch事件时,会记录收到的版本号,连接到新节点后,再次创建watcher时会带上这个版本号,然后就会进入历史数据同步逻辑。
作者回复: etcd clientv3 watch库有中断重连、恢复机制,它会记录上次已收到的watch事件版本号,重启到新节点后,创建watcher的时候会带上这个版本,这样就可以尽量避免event重复发送哈,你可以使用etcd 3.4.9版本自己测试体验下。
作者回复: 版本号是集群的逻辑时间,参考07,监听key时,你可以指定任意一个时间点,过去、未来的版本号都可以。
作者回复: 目前没有,你可以通过版本号信息来判断对比key的创建、修改时间等,它是个逻辑时间