今天这篇文章主要是从技术架构的角度,来介绍一下分布式时序数据库。给这个分布式时序数据库起个名字,暂时叫做SilverDB。
可以说一下:目前这个时序数据具备的主要功能还是在于存储和读写。关于时序数据库计算相关的东西,比如算子编排和调度,准备模拟分布式计算领域中的DAG算子编排和MR的思想来做。后面,要做一个和InfluxDB的性能对比测试,毕竟之前都是在本地开发环境跑。所以,找个服务器来跑一跑,”是骡子是马拉出来溜溜”。
这里主要关注下面几点:
1、在分布式架构方面,是如何考虑和选型的?
2、时序数据库的存储结构是如何设计的?
3、为什么引入了时序数据库元数据中心?
4、对于分布式存储来说,数据分片是如何做的?
5、对于数据维度组合的查询,数据索引是如何做的?
关于分布式时序数据库的技术架构需要分好几篇来介绍,理论与实践相结合的方式,来说设计。这一篇文章先介绍我这里所用到的分布式理论基础,理解了这些理论,在结合实际的工程设计,也就是知道怎么用,如何用了。
第一部分 分布式理论CAP
CAP作为分布式系统的基础理论,主要提出了分布式系统的三个基础特性:
1、一致性(Consistency)
2、可用性 (Availability)
3、分区容错性 (Partition tolerance)
对于任何一个分布式系统,最多只能满足以上两个特性,即CA、CP、AP,而无法同时满足CAP。如何理解呢?
一致性解析
在分布式环境中,一致性是指多个数据分片或者数据副本之间的的一致性,为什么会出现这种情况?因为当数据分片写入不同的集群节点的时候,首先需要保证数据写的一致性,不然数据分片之间可能存在重复的脏数据。当集群中存在数据副本的时候,多个数据副本之间的同步需要保证一致性。但是对于,数据副本之间、数据分片之间的一致性确实不同的协议来保证的。
通常,在当前的分布式存储领域,对于数据副本之间的一致性都是采用的最终一致性协议来保证。也就可以同时,勉强满足CAP理论的三个基本特性。
如果我们放弃一致性(强一致性)的话,那么整个系统是无法保证实的一致性的,在数据最终达到一致性之间,存在一个时间窗口,而在这个时间窗口内,数据就是不一致的。这里,可以看看Kafka、Zookeeper 在做数据副本同步的时候,就是通过最终一致性来保证数据可用性的。
可用性解析
对于分布式系统来说,整个集群的可用性,其实基本包含两个部分:一是系统服务的可用性;二是数据存储的可用性,也就是说只有这两点可以保证的情况下,整个分布式系统才是高可用的。对于数据存储来说,基本上可以使用数据副本来保证容错。而系统服务的可用性,在主流的分布式架构设计中,基本可以分为对称与非对称的网络模型。比如,HDFS,非对称网络模型,可以基于ZK做到主节点的高可用。而Greenplum,对称网络模型,每个节点的职责及角色对等。
我们在做分布式架构设计的时候,如果我们放弃可用性,那么在遇到网络故障、节点宕机的情况下。那么,对于整个服务在故障期间,将不可用。
分区容错性解析
对于分区容错性而言,意味着整个系统的节点可扩展性。也就说,放弃分区容错性,相当于放弃分布式。
ok,做一个小结。这里只是对CAP理论部分,结合工程实际经验,做了简单的解析。对于SilverDB来说,整个分布式架构设计,目前没有考虑数据副本,也就是说我们放弃了可用性A,实现了CP。( 在后期,SilverDB会参照Kafka、Zookeeper、HDFS的副本机制、或者类似于对象存储的冗余纠错码的方式,来进行设计和实现。)
而对于CP的实现,就需要介绍P2P对称网络模型的Gossip协议和分布式Hash一致性了。请大家系好安全带,进入第二部分P2P对称网络模型Gossip协议。
第二部分 P2P对称网络模型的Gossip协议
Gossip协议最早是在1987年发表在ACM上的论文中被提出的。主要用在分布式数据库系统中各个副本节点同步数据之用。而在这里,我们使用Gossip协议作为整个分布式集群节点通信的基础。这个协议还有一个昵称叫做”传染病协议”。为啥呢?
因为,对于Gossip的通信过程来说。通常会选择分布集群中的一个种子节点作为传染源,然后当种子节点有状态需要变化的时候,就会随机的选择周围几个节点进行消息传播。而收到消息的节点也会重复该过程,知道最终网络中所有节点都感染。
但是,这个过程可能需要一定的时间,理论上最终所有节点都会收到消息,因此本质上也是一个最终一致性协议。
那在SilverDB的分布式架构设计中,这个协议用来做什么呢?其实就是为了保持分布式集群环境中,每个节点的状态同步。比如,当有新的节点加入到集群的时候,可以基于Gossip协议,同步集群和新节点之间的状态,并且保持节点之间的心跳。用这个协议,可能几十行代码就可以做一个分布式的集群。
第三部分 分布式Hash一致性
OK,如果说基于Gossip协议,SilverDB构建了一个基本的分布式集群环境,最重要的就是保证了集群节点之间的状态同步。
那么对于分布式时序数据库SilverDB的数据写入,如何保证数据可以均衡的写入到每个节点呢?如何保证每个节点写入的数据在不同节点之间,同一时刻的一致性呢?这里就用到了分布式Hash一致性。对于Hash一致性的理解,我觉得这篇文章不错。想要详细了解去百度吧。我这里主要是结合SilverDB的工程实践,把关键的东西拿出来说一下就行了。
Hash一致性的算法,本质是Hash取模运算。可以根据取模运算的结果将SilverDB的写数据请求均衡分发到每个数据库节点。同时,也起到了很好的负载均衡的作用,是不是。
最简单的方式,是不是说SilverDB有几个节点,那写请求就根据节点个数取模就可以了呢?是的,最简单的方式确实是这样。但是这种普通的取模运算算法伸缩性较差。比如,SilverDB需要扩容的时候,新增的N个节点,那么之前写的数据和节点之间的映射关系就会失效。
而Hash一致性算法则是基于Hash环对其进行了改进。对于Hash一致性的算法实际上利用0到最大正整数构成数据环,来进行取模运算。通常,在实际工程中,可以将Hash进行预切分,也就是设置虚拟桶,减少由于某些集中式请求所造成的数据倾斜。
而其最大的好处在于,当分布式集群服务中的某个节点宕机之后,可以尽可能小得降低 数据和节点之间映射关系失效的比例。
比如,我们将Hash环切分成了3份:0-M、M-N、N-MaxInt ,分别表示节点1、节点2、节点3。当一个请求过来的时候,会计算数据得Hash值,看看这个数据会落到哪个Hash环区间。如果落到了 0-M这个区间范围,那么顺势正就会找到节点1这个节点。如果落到了M-N这个区间,则会将请求路由到节点2。
这个时候,当节点2宕机的时候,整个Hash环将划分的区间将会编程0-N、N-MazInt,这个时候失效的也仅仅只是节点2的数据与节点映射。
所以,对于基于Hash一致性的数据分片,通常在进行扩容或者缩容的时候,需要进行数据分片的均衡。
OK,基本上对于SilverDB分布式架构涉及到的相关理论做了一个简单的介绍,接下来,具体看一下技术架构。还是继续画个图,看起来更加直观和清晰一些。
所以,基于上面的所用到的协议,除了元数据服务之外。基本上就已经可以构建一个基本的分布式服务了。接下来的一篇分布式时序数据库SilverDB-技术架构2,主要会介绍SilverDB读写的核心流程和各个Module的功能。
来源:freebuf.com 2020-09-09 10:13:06 by: 龙渊实验室LongYuanLab
请登录后发表评论
注册