大数据平台架构设计说明书.docx
《大数据平台架构设计说明书.docx》由会员分享,可在线阅读,更多相关《大数据平台架构设计说明书.docx(19页珍藏版)》请在冰豆网上搜索。
大数据平台架构设计说明书
大数据平台
总体架构规格说明书
V1.0版
●
目录
I.
简介
1.目的
本文详细描述了DreamData数据库系统。
介绍了系统的目标、功能、系统接口、系统行为、系统约束以及系统如何响应。
本文面向系统参与者以及系统开发人员。
2.词汇表
术语
定义
作者
提交被审查文档的人。
为了防止多个作者的情况出现,这个术语指全程参与文档制作的主要作者。
3.引用
II.
整体介绍
1.系统环境
图1–系统环境
2.软件介绍
DreamData是在从分布式数据库的基础上发展而来,同时加入一些NoSQL的基因的新一代大数据实时分析分布式数据库,并且支持内存计算。
DreamData最大的特色就是大而快,它能极快地导入和处理海量的数据,并在这个基础上能极快地进行用户所需数据统计和分析。
相对传统数据库Oracle而言,DreamData的单机性能要高出50倍以上,并且随着节点数量的增加,整体性能会同步提升。
3.用途
●实时决策能力;
●提高业务效率;
●快速智能发现新观点和商业机会;
●提供业务产出;
●提升IT效率;软件架构
4.简介
图2–系统架构图
5.核心技术
DreamData采用了大量最新的技术成果,最核心的技术包括:
大规模并行处理MPP、行列混合存储、数据库内压缩和内存计算。
这些技术之间并不是孤立存在,而是相互关联,形成一个高效的系统。
●大规模并行处理MPP
DreamData被设计为能在可用内核的数量,和跨越主机分配使用的并行执行上很好地进行扩展。
如图3所示。
图3.并行处理原理示意
一张大表拆分成多个Tablet,被复制分布存储在不同的节点上以便并行处理;通过内存本地化处理把大数据量和计算量分散到不同处理器;同时任何节点宕机将不影响数据完整和业务连续性,提供了系统的高可用性。
MPP系统不共享资源,处理单元可获得全部计算资源,处理效率高;处理单元之间互不影响,当通信占比较小时MPP优于传统的SMP数据库架构,更适合数据分析与决策的场景。
●行列混合存储
DreamData主要面向大数据的实时处理,为了提高数据处理效率,尤其是常用的聚合、扫描和快速搜索功能,系统采用行列混合存储的方式,按行分区保留数据的关联性,按列组织提高数据压缩效率和快速聚合能力。
从概念上来说,一张数据库表是一个二维的数据结构,以行和列形式组织单元。
而计算机内存则是以线性顺序组织。
对于存储至线性存储器中的表,如图3中所示,列式数据组织方式意味着更高的压缩效率和快速聚合能力。
图4.列式数据组织的优势
●数据库内压缩
采用经典的高效无损压缩算法技术,进一步提高性能,并极大地节省了数据存储空间。
用户可获得10倍以上的空间节省,并且同时获得相应有效I/O性能提升。
系统无需解压即可访问数据,轻量级压缩算法减少压缩/解压时间。
●内存计算
硬件上得益于近年来性能的提升,CPU普遍采用多核架构(每块CPU8Core),X86服务器硬件成本较低,可采用多服务器或多刀片大规模并行扩展。
同时加上DreamData软件技术上的创新,包括行列混合存储技术、高效压缩、数据分片、快速索引、增量插入等方法手段,允许系统实现内存计算:
◆将数据保存在内存中相比从磁盘上访问能够极大地提高应用的性能;
◆采用列式存储可以将更多的数据装进内存;
◆数据装进内存里的同时也会同步写入硬盘,即使宕机也不会丢失数据。
6.MasterNode
现在主要包括Control模块和SQL模块这两个部分,在这个基础上加入专门用于解析数据挖掘,并支持R语言的DataMining模块,为了可用性,安全性,以及性能,一个集群中可以有多个MasterNode,在SQL和DataMining这两个功能层面上,每个MasterNode之间会采用负载均衡的方式来进行调度,但在Control功能方面将会只有一个MasterNode处于Active状态,其他的MasterNode处于Passive模式。
7.DataNode
DataNode是实际对数据进行存储,并且能够对数据进行初步处理和过滤,以仅可能少的数据返回给MasterNode端,DataNode存储数据的单位是Tablet,并且一个DataNode会有多个Tablet,并且他们是扁平的,在底层存储数据的时候用到了行列混合存储以及深度压缩和浅度压缩技术。
还有DataNode提供多线程技术的设置,通过来进行加速。
III.
MasterNode
1.简介
MasterNode主要包括Control和SQL这两个模块,并且在多个MasterNode之间支持Active和Passive的备份方法。
2.Control模块
用于管理这个集群基础的元数据,包括表结构和DataNode信息,还有负责集群中异常事件的处理和DataNode注册信息,比如,某个DateNode突然离线或者宕机了,ControlServer会通过Lease机制来。
▪表分布策略
当Control模块收到建表的SQL命令后,会根据命令中的TabletGroup分片请求个数,从保持连接的DataNode中,根据一定策略选出最合适的符合分片请求个数的多个DataNode,如果挑选出的合格DataNode个数小于要求的分片个数,则报错返回,反之则在相应的DataNode上建立此分片。
如果副本数量要求大于1,则会以之前主分片为模板,在间隔步长为1的DataNode上建立相应的副本。
当分片数为1时,副本则被安排在其他选出的DataNode上。
3.SQL模块
本质是一个经过我们云人团队修改的PostgreSQL,版本号,它主要用于在这个集群的前段接收来自命令行YSQL的SQL指令,并且也接受通过JDBC/ODBC等方式调用的SQL指令。
当SQL模块接收到查询语句后,首先将其传递到查询分析模块,进行词法、语法和语义分析。
若是命令则将其分配到功能性命令处理模块;对于复杂命令则要为其构建查询树,然后交给查询重写模块。
查询重写模块接收到查询树后,按照规则和视图进行查询树的重写,生成新的查询树。
生成路径模块依据新的查询树,考虑访问方式等问题,生成最优访问路径。
最后最优路径生成可执行计划,并将其传递到查询执行模块执行。
在查询执行阶段,将根据执行计划进行数据提取、处理、存储等一系列活动,以完成整个查询执行过程。
查询执行器分为策略选择(Portal)、辅助处理(ProcessUtility)、执行器(Executor)和特定功能子模块。
查询执行器会首先在策略选择模块根据输入执行计划选择对应的处理方式(辅助处理、执行器)。
选择执行策略后,会将执行控制流程交给相应的处理模块。
执行器输入包含了一个查询计划树,用于实现针对于数据表中元组的增删查改等操作。
而辅助处理模块则处理其他各种情况。
执行过程中会涉及表达式计算、投影运算和元组操作等功能,并且整个查询执行中会被重复调用,把他们单独划分为特定功能子模块。
▪查询执行策略
执行流程进入查询执行阶段后,会为每种执行计划选择相应的处理过程,执行相应的处理,最后根据要求返回结果。
SQL语句会被查询编译器转换成两种基本类型的数据结构(执行计划树和非执行计划树),并在执行过程中为其选择合适的执行部件(执行器或者辅助处理)。
DML语句会被查询编译器转换成执行计划树,因为DML语句的执行过程十分相近,并且都可以使用统一的数据结构加以表示和处理,所以被作为一种特殊的方式,单独进行优化和处理。
其他类型的语句被归为非计划树操作,使用另一处理流程进行处理。
然而,有些复杂的SQL语句不能简单的归类为一种基本处理类型,会将其解析成两种基本类型数据结构的序列,并将其顺序执行来完成请求操作。
▪执行器
查询计划树会由执行器统一进行处理。
其输入时包含查询计划树的数据结构QueryDesc,输出则是相关执行信息和结果数据。
如果希望执行某个计划树,则仅需构造包含此计划树的QueryDesc,并依此调用ExecutorStart、ExecutorRun、ExecutorEnd三个过程即能完成相应的处理过程。
执行器对于查询计划树的处理,最终被转换为针对计划树上每一个节点的处理。
每种节点表示一种物理代数的操作。
节点的处理呗设计为需求驱动的模式,父节点使用孩子节点提供的数据作为输入,并向上层节点返回处理结果。
实际执行时,从根节点开始处理,每个节点的执行过程会根据需求自动调用孩子节点的执行过程来获取输入数据,从而层层递归执行,实现整个计划树的遍历执行过程。
▪计划节点
查询执行的主要内容是对各个节点进行处理,由于使用了节点表示、递归调用、统一接口等设计,计划节点的功能相对独立、代码总体流程相似。
计划节点分为,控制节点、扫描节点、物化节点、连接节点。
控制节点:
用于处理特殊情况的节点,用于实现特殊流程。
扫描节点:
用于扫描表等对象以获取元组。
物化节点:
这类节点种类比较复杂,主要特点是,能够缓存执行结果到辅助存储中。
物化节点会在第一次执行时生成其中的所有结果元组,然后将结果元组缓存起来,等待上层节点取用;二非物化节点则是每次被执行时生成一个结果元组并返回给上层。
例如:
Sort节点能够获取下层节点返回的所有元组并更具制定属性进行排序,并将结果缓存起来,等上层节点从Sort节点取元组。
连接节点:
此类节点对应于关系代数中的连接操作,可以实现多种连接方式,每种节点实现一种连接算法。
例如:
hashjoin。
▪元组操作
使用元组(HeapTuple)存储所有信息,包括各种系统信息、数据。
执行器在执行过程中需要进行投影和属性选择判断,此时需要快速获取元组数据。
另外物化节点缓存元组时,要求元组体积更小,以节省空间,因此定义了MinimalTuple去掉事务相关信息。
▪表达式计算
处理SQL语句中的函数调用、计算式和条件表达式时需要用到表达式计算。
表达式的表示方式与查询计划树的计划节点类似,用各种表达式计划节点来完成相应操作。
表达式状态公共根类为ExprState,定义了类型type、辅助表达式节点指针expr以及用于实现该节点操作的函数指针evalfunc。
▪投影操作
投影操作本身也是通过表达式计算来实现。
投影操作时一种属性过滤过程,该操作队元组的属性进行精简,把那些在上层计划节点中不需要用到的属性从元组中去掉,从而构造一个精简版本的元组。
投影操作中那些被保留下来的属性保存在查询计划的目标属性中,也被称为投影属性。
本节描述了对于各种SQL语句的一般执行流程。
对于用户输入的SQL语句,优化器将为可优化的语句生成计划树,最终策略选择器会通过判断选择执行器来处理,而数据描述语句则在执行过程中由策略选择器使其统一进入辅助处理器执行。
作为查询执行部分的入口,策略选择器提供对外的调用接口:
ProtalStart、ProtalRun、ProtalEnd,对内提供了执行流程和部件的选择。
外层通过调用Protal的接口,将计划器输出的执行计划传输给Protal,Protal通过对于链表中操作的类型和链表长度等信息来决定选择怎样的执行过程,对于简单的查询语句则直接调用执行器,对于需要缓存输出到直到执行完成的语句则需要为其增加缓存结构和输出过程,对于更为复杂的过程提供了更为通用的复杂处理流程。
无论哪种执行过程,可优化语句最终都会生成查询计划树并由执行器来处理,而其他数据描述语句的功能由辅助处理器来完成。
对于种类繁多的数据描述语句,每种都有一个Stmt类型的数据结构保存其语法分析的信息。
通过对Stmt类型的判断,辅助处理会为其调用相应的语法解析和执行处理过程。
可优化语句提供了Plan类型的子类对象构成的计划树,每个计划节点数据结构共同继承于Plan节点,计划树的每种节点对应了四类操作中的一种。
Plan只是一个查询计划,初始化过程中为这个计划中的每个节点生成状态节点并构造状态树,保存执行的相关信息。
最总通过执行器执行每种节点的执行函数来实现各种节点的功能操作,在执行中利用状态树中信息处理相关数据。
各个节点的执行过程中普遍包含了投影和选择操作,以及对下层节点的处理过程调用。
执行器通过迭代的调用每个节点处理过程,从下层计划节点对应的执行流程中获取数据,并经过各种节点的处理流程,得到最终的输出结果。
对于修改元组的相关操作则是在获取到元组后通过调用相关存储操作接口实现的。
4.Active-Passivesolution
图3–Active-Passiveoverview
Masternode可以被配置为主备模式。
分别在两台不同的主机上安装相同版本的软件(包括操作系统,PGPool-II,Control模块,SQL模块)。
主MasterNode通过控制虚拟IP对外提供服务。
MasterNode通过异步/同步数据流备份的方式在主MasterNode和副MasterNode之间进行数据复制。
图4–Masternode数据复制
Masternode数据流的复制分为同步复制和异步复制,大部分操作流程都相同,主要的区别在于同步模式是主Master节点会将每个操作在副Master节点操作成功后才返回结果,而异步模式则在主节点操作成功后就立即返回,随后在副节点上重复这个操作。
异步复制过程主要有如下几步:
当master节点启动后,发现自己处于副节点模式,会启动一个wal进程,其向主节点的接收wal日志信息,如果有新的操作发生,则在本节点上执行相应的操作。
当主节点接收到副节点需要wal日志信息的请求,则会开始检测主节点上的wal日志信息,根据副节点发过来的cursor信息,把新的操作日志发送过去。
因为MasterNode并不能自动进行主备切换,所以这里引入了PGPool-II。
PGPool-II在这里扮演一个看门口狗的角色,当PGPool-II发现本机的Masternode不能提供服务,或者副节点上的PGPool-II发现主节点PGPool-II已经宕机,会触发副节点上的MasterNode切换到主模式。
并且虚拟IP的所有权会从原来的主节点转让给原来的副节点。
此时原来的副节点顺利切换成主节点并继续提供一致的服务,原来的主节点则可以进行检测修复等操作。
对于用户而言,完全察觉不出任何的区别上。
IV.
DataNode
1.简介
是实际对数据进行存储,并且能够对数据进行初步处理和过滤,以仅可能少的数据返回给SQLServer端,DataNode存储数据的单位是Tablet,并且一个DataNode会有多个Tablet,并且他们是扁平的。
还有DataNode可以使用多线程技术来进行加速。
图5–DataNodeArchitecture
2.重要模块
▪DB
也就是数据库,其包含多个Table,DB这个概念还是偏管理的,资源隔离和用户管理,理论上来说,其实Table和DataNode都是属于某个DB的资源,也就是说,某些DataNode只能用于某个DB,并不能像现在那样全集群所有DB共享;
▪Table
在DreamData中,现在主要是通过Hash算法将一个Table分为多个TabletGroup,每个TabletGroup包含一定的HashSlot个数,这个HashSlot和这个Table的DistributedColumn相关,任何行到底属于具体HashSlot,都通过计算这个行的DistributedColumn列的Hash值获得的,一般选择比较常用和重复几率较低的列,比如主键。
还有具体每个Table的HashSlot个数虽然现在大多采用一个固定的算法,但是如果HashSlot多的话,可能压缩率会低一点,但是对于带filter的场景,在性能方面会更好。
▪TabletGroup
不仅像上面说的那样,TabletGroup不仅包含属于一定HashSlot的数据。
并且它可以有多个Tablet作为备份,但是现在暂时只有做为主备份的Tablet接受查询请求,这样的做法核心还是一致性的问题,这样做法一致性会比较容易做到,具有多个Tablet在TabletGroup中备份的顺序和Order一致;
▪Tablet
每个Tablet应该包括其所属TabletGroup的所有的数据,每个Tablet在技术层面,主要包括WAL,Memstore和YFile这三个结构,具体可以看附录;
▪TabletOrder
主要用来表示异步备份的顺序的Pipeline,也就是假设有三个Tablet,新的数据先到Tablet0,之后异步到Tablet1,之后异步到Tablet2;
▪TableInfo
这个数据结构件包含所有Table相关的元数据,无论DataNode还是Client端都主要通过从ControlServer获取其TableInfo,并且通过处理这个TableInfo获取其TabletOrder。
3.数据存储
分析一下用于存储和分析数据的DataNode节点,每个DataNode会运行和存储多个Tablet,当数据写入的时候,数据会首先写到这个Tablet的WAL日志上,接着会写入至一个位于内存的数据结构Memstore中,WAL全称为“Write-AheadLog”,主要用于暂存那些最新的数据更新请求,以避免当Tablet中的Memstore被意外关闭时所造成的数据丢失。
接着,当Memstore存储的数据达到一定的阀值时,它会将数据整理一下,之后批量写入硬盘,写入格式为YFile。
所以这样能有效地利用硬盘顺序读性能好的特性。
最后,系统会清空WAL日志中那些已经写入的数据。
在底层结构方面,WAL是比较简单的,就是对任何对数据有影响的操作,比如,插入、更新和删除等操作,直接加一个header写入到底层WAL文件中。
Memstore和YFile在架构方面有点类似,都主要由HashSlotBlock和ColumnBlock这两层次组成。
HashSlotBlock主要是用于存储对应那个HashSlot所有的数据,而且HashSlotBlock包含所有列的ColumnBlock。
每个YFile会在tablet目录中生成YFile的目录,对于每个HashSlotBlock会生成xxx.yfile的文件。
4.数据导入
▪概括
目前集群的数据倒入分三种:
1.单条/多条记录插入。
2.单个文件导入。
3.批量文件导入。
这三种方式最终使用的机制都是类似的,最后被当成多条数据记录的导入操作。
当导入数据的时候,先对导入数据的格式进行解析,把一条数据记录转换成对应特定表的各个属性的值,如果该列的值不存在,则对应的列为空。
每条数据记录会按照一定策略分组,每组数据会分发到不同的数据节点进行存储。
在整个导入操作开始前,会为此次导入操作贴上一个标签,如果整个导入操作成功,则为有效。
如果导入操作失败,则该标签下的数据无效并被删除。
▪多节点的Loading
首先,Loading主要的控制操作在MasterNode中,MasterNode中的有专门控制Loading的模块,它会根据Loading具体的情况,把具体的请求和实际的数据地址发给对应的几个DataNode;
其次,当到导入数据时候,发生导入问题(比如,某个节点突然宕机时),MasterNode会rollback本次数据导入过程中之前已经导入的DataNode的数据;
还有,当导入数据的时候,本MasterNode宕机时,这个导入操作会向其他操作一样同步到passiveMasterNode中。
V.
分布式机制
图6–分布式机制
1.概括
心跳是分布式里面判断一个节点是否失效的方式之一,有两种方式:
1、MasterNode主动间隔一段时间发送心跳给DataNode,用来判断DataNode是否存活。
MasterNode为发送方,DataNode为接收方;2、datanode主动发送心跳给MasterNode。
MasterNode维护一张心跳表纪录最后的DataNode心跳的时间。
MasterNode后台线程检查心跳表以处理心跳过期的节点。
MasterNode为接收方,DataNode为主动发送方。
目前DreamData使用的是第二种。
(lease和心跳的区别在于,lease应该有独占的概念。
比如当支持多个MasterNode时,只有拿着lease的MasterNode才有权限修改表)。
对于heartbeat机制,DataNode会起一个单独Thread,这个Thread的主要作用就是间隔向MasterNode发送心跳,并且可以设定新的心跳长度(Length),比如DataNode向MasterNode申请10分钟,也就意味着,当DataNode完成这个申请之后,在10分钟内,ControlServer在任何情况下,都不能认为这个DataNode有问题,一般常见的时间的是5-10秒。
其次,当发现一个DataNode失效的情况下,也就是心跳过期,MasterNode会发邮件通知给管理者,或者连接第三方的Monitoring系统。
这个时候,MasterNode会将这个DataNode所有的Tablet放置在其所在TabletGroup的末尾,并且将其WorkingStatus设置成false,数据会按照新的TabletGroup的Order来写入。
之后,用户可以选择修复DataNode,等修复完成,这个DataNode会发送renew信息给MasterNode,
对DataNode主要调用方SQL模块,当SQL模块无法连接作为这个TabletGroup的MasterTablet,它会等待几秒(这个时间长度应该设定为和MasterNode检查心跳状态的时间相关),之后去请求最新的TableInfo(目前最多重复尝试链接datanode3次),这样的做好主要是为了数据的Consistency,也就是在CAP中,优先选择CP,而不是A,但是如果今后有更好的做法,可以优化一下。
假设SQL模块从MasterNode收到最新的TableInfo之后,它会按照新的TableInfo发送,但对于新的MasterTablet并不知道现在他现在已经被Promote了,当新的MasterTablet收到Query这样只能由MasterTablet处理的请求时,它应该不知道自己被promote这个事实,它会从MasterNode端获取最新的TableInfo,来确认自己是不是最新的MasterTablet,如果的确有变化的,它会更新自身的TableInfo和Order,并继续处理新的请求,如果没有变化的话,MasterTablet将会返回错误的statuscode。
在Table最初始的时候,整个Tablet和TabletGroup部署由Scheduler来生成。
假设用户准备立刻放弃这个DataNode,这个时候用户可以执行命令来去掉,当去掉之后,ControlServer会自动去尝试利用最空的那几个DataNode的资源来创建最新的Tablet来替换和那个被放弃的DataNode相关的Tablet。
或者过了一天(时间可设置),DataNode还不renew。
会自动放弃这个DataNode,这个时候,ControlServer会创建新的Tablet来替换那个DataNode之前所有的Tablet,并且所有替换新Tablet的过程都通过Scheduler来做。
2.数据备份和同步
关于数据备份,主要是通过异步的pipeli