学习如何使用etcd-raft库

来源:互联网 发布:广告算法工程师招聘 编辑:程序博客网 时间:2024/05/16 02:33

菜鸟一枚,最近几天看了下etcd-raft库的官方使用示例,本来俺的代码能力较差,网上关于这个库的使用的资料不多,所以希望写此文章以给同学们带来一丢丢的帮助-------

首先俺觉得应该初步认识一下raft算法,看这儿,这是大婶们翻译的官方论文,比较详细。还有这个,里边有raft运行的动态图,官方示例在这里,好了,咱言归正传

以官方示例的主函数作为入口

    cluster := flag.String("cluster", "http://127.0.0.1:9021", "comma separated cluster peers")
    id := flag.Int("id", 1, "node ID")
    kvport := flag.Int("port", 9121, "key-value server port")
    join := flag.Bool("join", false, "join an existing cluster")
    flag.Parse()
join为true代表中途加入

这段的作用是执行示例程序时需要传入一些参数(集群信息)例如(编译好的可执行程序为etcd-raft):

./etcd-raft --id 1 --cluster http://127.0.0.1:12379,http://127.0.0.1:22379,http://127.0.0.1:32379 --port 12380



然后定义的两个channel
    proposeC := make(chan string) 
    defer close(proposeC)
    confChangeC := make(chan raftpb.ConfChange)
    defer close(confChangeC)

重要的来了

    var kvs *kvstore
    getSnapshot := func() ([]byte, error) { return kvs.getSnapshot() }
    commitC, errorC, snapshotterReady := newRaftNode(*id, strings.Split(*cluster, ","), *join, getSnapshot, proposeC, confChangeC)
    kvs = newKVStore(<-snapshotterReady, proposeC, commitC, errorC)
    // the key-value http handler will propose updates to raft
    serveHttpKVAPI(kvs, *kvport, confChangeC, errorC)


首先定义一个键值对存储和获取快照函数,以及proposeC和confChangeC等传入newRaftNode函数,


newRaftNode可以理解为初始化一堆配置然后启动raft,


newKVStore返回一个kvstore 

s := &kvstore{proposeC: proposeC, kvStore: make(map[string]string), snapshotter: snapshotter}.....return s

至于serveHttpKVAPI:serveHttpKVAPI starts a key-value server with a GET/PUT API and listens.启动键值服务

客户端的请求通过proposeC传递给raft内部,在httpapi.go:

func (h *httpKVAPI) ServeHTTP(w http.ResponseWriter, r *http.Request)中
通过调用
h.store.Propose(key, string(v))把客户端的请求放入proposeC,raft取出做处理,提交过后的请求(也就是说leader告知了所有的follower)封装到commitC,应用在kvstore.go:
func (s *kvstore) readCommits(commitC <-chan *string, errorC <-chan error)中遍历出commitC中的data,存储键值对(示例是放入内存)
confChangeC和proposeC类似,存放的是配置信息(客户端的更改集群配置请求例如增加节点),
至于snapshot:上面那个论文翻译里边有说,看了就懂了