开源分布式配置中心选型

一、目标

实现分布式配置中心:
(1)集中管理外部依赖的服务配置和服务内部配置
(2)提供web管理平台进行配置和查询
(3)支持服务注册与发现
(4)支持客户端拉取配置
(5)支持订阅与发布,配置变更主动通知到client,实时变更配置

备注:client为nodeJS,java等

二、开源解决方案调研

2.1 disconf

百度开源
与spring集成的很好,有web管理,client只支持java。

2.1.1 介绍

https://github.com/knightliao/disconf/wiki

2.1.2 源码

https://github.com/knightliao/disconf

2.2 diamond

阿里开源
阿里内部应用广泛,由http server(nameservers), diamond-server ,web组成,diamond-server连接同一个mysql,数据同步通过mysql dump文件同步(同步效率?),支持订阅发布,client只支持java。

2.2.1 介绍

http://code.taobao.org/p/diamond/wiki/index/

2.2.2 源码

http://code.taobao.org/svn/diamond/trunk

2.3 doozer

已停止更新,设计倾向于实时的数据变更通知,数据全部放于内存,不会持久化文件。(有独立工具支持,不知支持性怎样?)

2.4 etcd

CoreOS开源。
轻量级分布式key-value数据库,同时为集群环境的服务发现和注册而设计。
它提供了数据TTL失效(通过TTL更新来判断机器下线,来避免一定的网络分区问题)、数据改变监视、多值、目录监听、分布式锁原子操作等功能,来管理节点状态。

2.4.1 特性

  • 简单: curl可访问的用户的API(HTTP+JSON)
  • 安全: 可选的SSL客户端证书认证
  • 快速: 单实例每秒 1000 次写操作
  • 可靠: 使用Raft保证一致性
    注:zookeeper使用的比较复杂基于Paxos的Zab协议,etcd使用的Standford新的一致性算法Raft,概念上会简单些,0.4.6版本依赖于go-raft,0.5.0以上重新设计。

2.4.2 目前版本

网上的介绍文章基本停留到稳定版0.4.6上。目前版本已从0.x直接跳到了2.0版本。(2015-1-28)
https://coreos.com/blog/etcd-2.0-release-first-major-stable-release/
2.0介绍(需要翻墙):
https://www.youtube.com/watch?v=z6tjawXZ71E

使用go语言,部署简单,同时项目较年轻。

2.4.3 介绍

从实现原理到应用场景多方位解读(2015-1-30)
http://www.infoq.com/cn/articles/etcd-interpretation-application-scenario-implement-principle

2.4.4 源码

https://github.com/coreos/etcd

2.5 zookeeper

成熟的分布式配置解决方案,待续。。

2.6 比较etcd和zookeeper

Jason Wilder的一篇博客分别对常见的服务发现开源项目Zookeeper、Doozer、etcd进行了总结。
http://jasonwilder.com/blog/2014/02/04/service-discovery-in-the-cloud/

重点关注etcd是否能取代zookeeper。

2.6.1 性能

只从实现语言上考虑,golang性能近c,java在大型集群的多线程能力较好,总体相差不多。都能支持上千节点。

2.6.2 功能性:关注订阅发布、ttl特性

2.6.2.1 订阅发布

etcd 可以使用递归的Watcher,递归式的监控应用(主题)目录下所有信息的变动。这样就实现了机器IP(消息)变动的时候,能够实时通知到收集器调整任务分配。

递归订阅

1
2
3
etcd递归 watcher
$ etcdctl watch /foo-service --recursive
$ curl -L http://127.0.0.1:4001/v2/keys/foo-service?wait=true\&recursive=true

订阅通知,在/foo-service增加container2,返回:

1
2
3
4
5
etcd 递归监听 返回
$ etcdctl watch /foo-service --recursive
localhost:2222
$ curl -L http://127.0.0.1:4001/v2/keys/foo-service?wait=true\&recursive=true
{"action":"set","node":{"key":"/foo-service/container2","value":"localhost:2222","modifiedIndex":23,"createdIndex":23}}

2.6.2.2 TTL机制

更新方式

1
2
3
4
5
etcd ttl更新
$ etcdctl set /foo "Expiring Soon" --ttl 20
Expiring Soon
$ curl -L -X PUT http://127.0.0.1:4001/v2/keys/foo?ttl=20 -d value=bar
{"action":"set","node":{"key":"/foo","value":"bar","expiration":"2014-02-10T19:54:49.357382223Z","ttl":20,"modifiedIndex":31,"createdIndex":31}}

get ttl过期的数据,返回errorCode:100

1
2
3
4
5
etcd ttl 过期数据返回
$ etcdctl get /foo
Error: 100: Key not found (/foo) [32]
$ curl -L http://127.0.0.1:4001/v2/keys/foo
{"errorCode":100,"message":"Key not found","cause":"/foo","index":32}

2.6.3 部署结构

etcd支持普通节点模式和proxy模式两种:
启动设置集群大小,超过集群大小的etcd节点自动转化为proxy模式。

2.6.3.1 proxy模式

etcd作为一个反向代理把客户的请求转发给可用的etcd集群。这样,你就可以在每一台机器都部署一个Proxy模式的etcd作为本地服务,如果这些etcd Proxy都能正常运行,那么你的服务发现必然是稳定可靠的。
如图:

etcd-proxy

2.6.4 总结

etcd特性略胜于zookeeper两点:
(1)etcd在订阅发布机制上能提供的功能与zookeeper相似。但是更轻量级,使用api更简单,依赖少,可直接使用curl/http+json或etcdctl的方式。
(2)etcd的TTL机制能避免一定的网络分区问题(如网络间断误认为注册服务下线)

zookeeper胜于etcd两点:
(1)成熟,稳定性高,多数坑已被踩过。
(2)配套工具:etcd没有web监控平台,client有node-etcd 3.0,较年轻。zookeeper有简单易用的exhibitor监控,java client的curator替代zkclient,非常成熟易用,避免掉坑。

2.6.4.1 综合实际情况

线上已有zookeeper集群,考虑部署成本,避免踩坑,和zookeeper稳定和成熟配套工具,风险等,建议基于zookeeper进行封装开发。
如果小型集群,也是可以尝试etcd,毕竟架构部署简单省事。


参考:

(转载本站文章请注明作者和出处 Vernon Zheng(郑雪峰) – vernonzheng.com ,请勿用于任何商业用途)