Botposter.com集群ETCD2.3.7升级至3.0实例分析

80次阅读
没有评论

共计 3836 个字符,预计需要花费 10 分钟才能阅读完成。

本篇文章为大家展示了 Botposter.com 集群 ETCD2.3.7 升级至 3.0 实例分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

Botposet.com 是一款与 HubSpot 类似的营销自动化 SAAS 产品,全部使用 golang 开发。

说明

在 Botposter.com 中,ETCD 主要用于以下两个职责:

master 选举

集群信息保存

早期曾使用 ETCD 的 TTL 来实现 master 心跳检测,由于性能原因在 Botposter.com 上个月的重构中取消了这种用法。这也恰好简化了升级难度,因为 ETCD v3 对 TTL 有重大改动。

准备资料准备

迁移工作的主要参考以下两篇资料:

https://github.com/coreos/etcd/blob/master/Documentation/op-guide/v2-migration.md

https://github.com/coreos/etcd/blob/master/Documentation/upgrades/upgrade_3_0.md

测试环境

开始升级前需要搭建测试环境,过程非常简单,这一点 ETCD 做得非常好,V3 版本与 V2 版本无论从安装方式和配置参数完全一致。

安装参考链接:https://github.com/coreos/etcd/releases

配置参考链接:https://github.com/coreos/etcd/blob/master/Documentation/op-guide/clustering.md

配置好测试环境后,使用 etcdctl 测试 ETCD V3 是否可以正常使用。这里需要注意,一定不要忘记在环境变量中加入 ETCDCTL_API=3。否则在操作 V3 时,无论使用 SET,GET 都没有任何数据返回,也没有错误返回。建议 ETCD V3 可以提供错误提示。我在这里耽误了一些时间,因为想当然的以为,使用 ETCD V3 和 ETCDCTL V3 是默认匹配的。ETCDCTL 的文档链接:https://github.com/coreos/etcd/blob/master/etcdctl/README.md#migrate-options

注意:我在第一次使用 etcdctl member list 命令 (所有的命令都会出错,此处以 member list 举例) 的时候,返回下面错误代码:

grpc: addrConn.resetTransport failed to create client transport: connection error: desc =  transport: dial tcp 127.0.0.1:22379: getsockopt: connection refused  Reconnecting to {127.0.0.1:22379   nil}

单独运行 etcdctl 命令,会返回 etcdctl 的使用帮助,其中有一行:

 --endpoints=[127.0.0.1:2379,127.0.0.1:22379,127.0.0.1:32379] gRPC endpoints

原来默认 gRPC 的 endpoints 有三个,解决这个问题的已知办法有两个:一是在 etcdctl 命令行中加入 –endpoints 参数

etcdctl --endpoints=127.0.0.1:2379 member list

二是在 etcd 启动参数中增加其它端口

-listen-client-urls http://127.0.0.1:2379,http://127.0.0.1:22379,http://127.0.0.1:32379

在 Botposter.com 中暂时使用第二种方法。因为迁移时间有限,没有继续查看是否可以修改 gRPC 的默认 –endpoints。

API V2 与 V3 区别

事务:ETCD V3 提供了多键条件事务(multi-key conditional transactions),应用各种需要使用事务代替原来的 Compare-And-Swap 操作。

平键空间(Flat key space):ETCD V3 不再使用目录结构,只保留键。例如:/a/b/c/ 是一个键,而不是目录。V3 中提供了前缀查询,来获取符合前缀条件的所有键值,这变向实现了 V2 中查询一个目录下所有子目录和节点的功能。

简洁的响应:像 DELETE 这类操作成功后将不再返回操作前的值。如果希望获得删除前的值,可以使用事务,来实现一个原子操作,先获取键值,然后再删除。

租约:租约代替了 V2 中的 TTL 实现,TTL 绑定到一个租约上,键再附加到这个租约上。当 TTL 过期时,租约将被销毁,同时附加到这个租约上的键也被删除。

与 Botposter.com 有关的改动只有平键空间,因为系统中使用 ETCD 目录结构保存了 master,node 和 task 的全部信息。从官方文档的表述看,事务和租约值得测试并用于优化 V2 的用法。

客户端代码升级平键空间

将原代码中包含以下代码的部分都修改为

client.GetOptions{Recursive: true}

都修改为

clientv3.WithPrefix()

数据类型

在 V2 版本中,resp.Node.ModifiedIndex 的数据类型为 uint64,V3 中 revision 为 int64。因为在 Botposter.com 使用了 resp.Node.ModifiedIndex 作为全局序列标识,所以,需要将原系统中的数据类型修改为 int64。

Compare-And-Swap

在 V2 的一种典型用法就是 Compare-And-Swap,在 Botposter.com 中也使用这种方法实现了分布式锁,实现方法是在 SET 操作时增加下面的操作:

client.SetOptions{PrevExist:  false})

即,只有当前 key 不存在时,才能写入成功。

在 V3 中,改为由事务实现。具体代码如下:

kvc := clientv3.NewKV(cli)
r, _ := kvc.Txn(context.Background()).
 If(clientv3.Compare(clientv3.CreateRevision(key),  = , 0)).
 Then(clientv3.OpPut(key, v)).
 Commit()

Txn 的具体用法参考:https://godoc.org/github.com/coreos/etcd/clientv3#example-KV–Txn

Node

在 V2 中,get 操作 response 回来的 value 保存在 response.node.value,如果是一个 directory,返回的结果集保存在 response.node.nodes 中。V3 做了大幅修改,因为 V3 中不再有 directory,所有的 key 都是 flat key,所以,所有 get 操作的返回值都保存在 GetResponse.Kvs(数据类型是 []*mvccpb.KeyValue)中。而且 V2 中,keynotfound 等错误在 V3 中都不再保留,V3 中,当查询的 key 不存在时,GetResponse.Count 为 0,len(GetResponse.Kvs) 也为 0,Get 操作返回的 error 为 nil。所以在 V2 中的代码如

response.Node.Value

需要改为

GetResponse.Kvs[0].Value

另外值得注意的是,V3 中的 key 和 value 的返回值都是[]byte 类型,这可以减少很多 string 与[]byte 的数据类型转换操作。

ETCD 升级

ETCD 升级很简单,先按照安装参考链接:https://github.com/coreos/etcd/releases,下载并解压文件。因为 Bostposter.com 集群有自动恢复机制,所以使用离线升级的方式,在所有服务器运行脚本:

service etcd stop
cp etcd /usr/local/bin
service etcd start

ETCD 的所有启动参数都不需要修改,升级时间不超过 1 秒。ETCD 升级后,升级集群服务的代码,只有在升级流程容器时需要重启 2000 多个流程,全部恢复时间大概在 1 分钟左右。

至此,升级工作全部完成。对系统功能和集群都做了测试,没有出现任何问题。

下面说说升级到 ETCD V3 后的感受,时间有限没有做精确测试,没有数据支撑略显不够严谨。

首先,V3 服务器端的内存比 V2 占用得更高,至少高 50%。尤其是压力增大时,内存占用飙升得很快,压力减小后几分钟内存会释放出来。

其次,Client 使用后一定要 Close,因为在 V2 时,Botposter.com 中使用了 sync.pool 来保存 Client。当升级到 V3 后,操作频繁时池化的 Client 会占用非常多的内存,因为没有做具体测试,还不清楚一个 Client 占用多少内存。目前的解决办法是 Client 不再池化,而且使用后立即 Close。

第三,V3 的 API 更加合理,直接的结果是代码量减少了,异常处理也变得更简单。

第四,从升级后的整体表现看,V3 的性能比 V2 要很多。

整体来说,在有条件的情况下,我建议升级至 ETCD V3。

上述内容就是 Botposter.com 集群 ETCD2.3.7 升级至 3.0 实例分析,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注丸趣 TV 行业资讯频道。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-04发表,共计3836字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)