在一个分布式环境中,同类型的服务往往会部署很多实例。这些实例使用了一些配置,为了更好地维护这些配置就产生了配置管理服务。通过这个服务可以轻松地管理这些应用服务的配置问题。应用场景可概括为:
zookeeper的一种应用就是分布式配置管理(基于ZooKeeper的配置信息存储方案的设计与实现)。百度也有类似的实现:disconf。
Diamond则是淘宝开源的一种分布式配置管理服务的实现。Diamond本质上是一个Java写的Web应用,其对外提供接口都是基于HTTP协议的,在阅读代码时可以从实现各个接口的controller入手。
分布式配置管理
分布式配置管理的本质基本上就是一种推送-订阅模式的运用。配置的应用方是订阅者,配置管理服务则是推送方。概括为下图:
其中,客户端包括管理人员publish数据到配置管理服务,可以理解为添加/更新数据;配置管理服务notify数据到订阅者,可以理解为推送。
配置管理服务往往会封装一个客户端库,应用方则是基于该库与配置管理服务进行交互。在实际实现时,客户端库可能是主动拉取(pull)数据,但对于应用方而言,一般是一种事件通知方式。
Diamond中的数据是简单的key-value结构。应用方订阅数据则是基于key来订阅,未订阅的数据当然不会被推送。数据从类型上又划分为聚合和非聚合。因为数据推送者可能很多,在整个分布式环境中,可能有多个推送者在推送相同key的数据,这些数据如果是聚合的,那么所有这些推送者推送的数据会被合并在一起;反之如果是非聚合的,则会出现覆盖。
数据的来源可能是人工通过管理端录入,也可能是其他服务通过配置管理服务的推送接口自动录入。
架构及实现
Diamond服务是一个集群,是一个去除了单点的协作集群。如图:
图中可分为以下部分讲解:
服务之间同步
Diamond服务集群每一个实例都可以对外完整地提供服务,那么意味着每个实例上都有整个集群维护的数据。Diamond有两种方式保证这一点:
- 任何一个实例都有其他实例的地址;任何一个实例上的数据变更时,都会将改变的数据同步到mysql上,然后通知其他所有实例从mysql上进行一次数据拉取(
DumpService::dump
),这个过程只拉取改变了的数据 - 任何一个实例启动后都会以较长的时间间隔(几小时),从mysql进行一次全量的数据拉取(
DumpAllProcessor
)
实现上为了一致性,通知其他实例实际上也包含自己。以服务器收到添加聚合数据为例,处理过程大致为:
- DatumController::addDatum // /datum.do?method=addDatum
- PersistService::addAggrConfigInfo
- MergeDatumService::addMergeTask // 添加一个MergeDataTask,异步处理
- MergeTaskProcessor::process
- PersistService::insertOrUpdate
- EventDispatcher.fireEvent(new ConfigDataChangeEvent // 派发一个ConfigDataChangeEvent事件
- NotifyService::onEvent // 接收事件并处理
- TaskManager::addTask(..., new NotifyTask // 由此,当数据发生变动,则最终创建了一个NoticyTask
- // NotifyTask同样异步处理
- NotifyTaskProcessor::process
- foreach server in serverList // 包含自己
- notifyToDump // 调用 /notify.do?method=notifyConfigInfo 从mysql更新变动的数据
虽然Diamond去除了单点问题,不过问题都下降到了mysql上。但由于其作为配置管理的定位,其数据量就mysql的应用而言算小的了,所以可以一定程度上保证整个服务的可用性。
数据一致性
由于Diamond服务器没有master,任何一个实例都可以读写数据,那么针对同一个key的数据则可能面临冲突。这里应该是通过mysql来保证数据的一致性。每一次客户端请求写数据时,Diamond都将写请求投递给mysql,然后通知集群内所有Diamond实例(包括自己)从mysql拉取数据。当然,拉取数据则可能不是每一次写入都能拉出来,也就是最终一致性。
Diamond中没有把数据放入内存,但会放到本地文件。对于客户端的读操作而言,则是直接返回本地文件里的数据。
服务实例列表
Diamond服务实例列表是一份静态数据,直接将每个实例的地址存放在一个web server上。无论是Diamond服务还是客户端都从该web server上取出实例列表。
对于客户端而言,当其取出了该列表后,则是随机选择一个节点(ServerListManager.java
),以后的请求都会发往该节点。
数据同步
客户端库中以固定时间间隔从服务器拉取数据(ClientWorker::ClientWorker
,ClientWorker::checkServerConfigInfo
)。只有应用方关心的数据才可能被拉取。另外,为了数据推送的及时,Diamond还使用了一种long polling的技术,其实也是为了突破HTTP协议的局限性。如果整个服务是基于TCP的自定义协议,客户端与服务器保持长连接则没有这些问题。
数据的变更
Diamond中很多操作都会检查数据是否发生了变化。标识数据变化则是基于数据对应的MD5值来实现的。
容灾
在整个Diamond系统中,几个角色为了提高容灾性,都有自己的缓存,概括为下图:
每一个角色出问题时,都可以尽量保证客户端对应用层提供服务。
参考文档
http://blog.csdn.net/kevinlynx/article/details/40017109
相关推荐
Diamond -- 分布式配置中心一、简介Diamond是淘宝研发的分布式配置管理系统。使用Diamond可以让集群中的服务进程动态感知数据的变化,无需重启服务就可以实现配置数据的更新。具有简单、可靠、易用等特点二、使用...
淘宝Diamond是一款开源的分布式配置中心,它主要用于解决在大规模分布式系统中管理应用配置的问题。这款配置中心由淘宝团队开发,提供了统一的配置管理和推送服务,使得应用在运行时可以动态地获取和更新配置,极大...
在众多开源的分布式配置中心项目中,如淘宝的Diamond和Disconf,Apollo因其功能强大、社区活跃、持续维护以及清晰的文档而受到青睐。它不仅能满足基本的配置管理需求,还提供了丰富的扩展性和灵活性,是微服务架构下...
淘宝Diamond项目是一个专门为淘宝平台开发的分布式配置管理系统。它旨在解决大规模分布式系统中配置管理的难题,提供了一种集中化、动态化的配置更新机制。在本文中,我们将深入探讨Diamond的核心概念、工作原理以及...
淘宝Diamond是一款由阿里巴巴开源的分布式配置中心,它主要用于解决大规模分布式系统中的配置管理问题。在大型互联网企业中,随着系统的复杂度增加,配置的管理和更新变得越来越困难,Diamond为此提供了统一、高效且...
Diamond是淘宝内部自研的配置管理平台,它主要负责系统的动态配置管理和分发,使得开发者可以在不重启服务的情况下,实时更新配置,从而提高了系统的灵活性和稳定性。这一设计思想借鉴了分布式系统中的"发布/订阅...
Tair是一款由淘宝研发的分布式键值系统,其设计目标是提供高可用性、高性能的数据存储服务。Tair系统由中心控制节点(config server)和多个服务节点(Data server)构成,旨在解决大规模分布式环境下的数据存储和...
可分析的日志打印,日志流控,动态变更TDDL必须要依赖diamond配置中心(diamond是淘宝内部使用的一个管理持久配置的系统,目前淘宝内部绝大多数系统的配置,由diamond来进行统一管理,同时diamond也已开源)。...
Diamond用于存储静态配置并能动态推送;Notify是高可用的消息中间件,处理分布式事务;Meta则借鉴LinkedIn的Kafka,提供顺序保证的消息传递。此外,还有Eagleeye用于分布式跟踪,Pandora作为隔离容器解决二方包问题...