etcd 的 cluster id

2020-07-27
etcd

找到生成 Cluster ID 的代码,其实不是某种随机法生成的,而是用所有 MemberID hash 出来的。

1func (c *RaftCluster) genID() {
2    mIDs := c.MemberIDs()
3    b := make([]byte, 8*len(mIDs))
4    for i, id := range mIDs {
5        binary.BigEndian.PutUint64(b[8*i:], uint64(id))
6    }
7    hash := sha1.Sum(b)
8    c.cid = types.ID(binary.BigEndian.Uint64(hash[:8]))
9}

那么 Member ID 又是怎么来的呢?

 1var b []byte
 2sort.Strings(m.PeerURLs)
 3for _, p := range m.PeerURLs {
 4    b = append(b, []byte(p)...)
 5}
 6
 7b = append(b, []byte(clusterName)...)
 8if now != nil {
 9    b = append(b, []byte(fmt.Sprintf("%d", now.Unix()))...)
10}
11
12hash := sha1.Sum(b)
13m.ID = types.ID(binary.BigEndian.Uint64(hash[:8]))

这个保证了 bootstrap 的时候,多个节点生成出来相同的 cluster id。

不过这导致一些问题,比如我用相同的配置多次启动集群,会看到 Cluster ID 不变。更麻烦的情况是,如果启动集群后销毁一半的节点,再用原来的配置新启动一套集群,前后两套集群是可以互相通信的。可以看看PD 的这个 issue

解决办法就是设置启动参数 --initial-cluster-token,保证每套集群都不一样。


欢迎加入技术讨论 QQ 群: 745157974