本文是系列文章的第二部分,阅读前两部分见这里《大数据管理系统LAXCUS(一):基础与数据》
网络通信
LAXCUS 集群网络建立在 TCP/IP 协议网络之上,支持 IPv4 和 IPv6 网络地址。为了适应不同的网络通信需求和节约网络通信资源,LAXCUS 采用了专属的网络通信协议,和在此协议上建立的多套网络通信方案,它们共同组成了 LAXCUS 网络通信运行的基础。本章将阐述与网络通信有关的各个组成部分。
3.1 FIXP 协议
LAXCUS 使用 FIXP 协议进行网络通信,FIXP 是一套全新的二进制格式的应用层通信协议,名字全称是自由消息交换协议 (Free Information eXchange Protocol)。二进制数据采用小头码位序 (Little Endian)。FIXP 协议具有平台独立、上下文无关、结构简单、数据尺寸小等特点。
3.1.1 协议结构
如图 3.1 所示,协议结构布局按排列顺序由三部分组成:命令、消息、数据实体。命令分为两种:请求和应答,命令的作用是说明本次通信的基本属性。每次通信由发起方发送请求命令,受理方返回应答命令。消息在命令之后出现,消息在一次通信协议中允许出现任意多个,消息中携带本次通信需要的多类附属信息。消息之间是衔接的,彼此无分隔标记,通过消息头中的标记长度加以区别。在最后是数据实体部分,数据实体包含本次通信需要的主要内容,如音频、档案资料等。数据实体是一个可选部分,是否存在会在消息中注明。比如通信发起方通常是不需要传递数据实体的。
图 3.1 FIXP 协议结构
3.1.2 命令结构
如图 3.2,命令是一个 56 位 (7 字节) 的数字序列。第一个 8 位的标识的作用是区分当前是请求命令或者应答命令。之后的协议版本号占用 16 位,协议版本号是可变的,不同的协议版本号代表不同的协议格式,在应用中分别有不同的解释。目前协议的最新版本号是 256(0x100)。 命令的主要区别在第 24 至 40 位,请求命令需要提供两个 8 位的主命令和从命令,说明本次操作的作用目标,应答命令返回一个 16 位的应答码,确认本次请求是接受、还是因为其它原因拒绝。最后是 16 位的消息成员数,理论上,一次 FIXP 通信最多可以携带 65535 个消息。
图 3.2 命令 (请求 / 应答) 结构
3.1.3 消息结构
如图 3.3,消息是一个不定长的数据结构,由键、类型、参数长度、参数组成。键占用 16 位,每个键都有一个固定的定义,键理论上有 65536 个,目前已经使用了大约 100 个。类型占用 4 位,说明后续的参数属性,包括布尔、短整数、整型、长整型,单浮点、双浮点、二进制数组、字符串、压缩二进制数组、压缩字符串。参数长度是一个 12 位的值,参数的实际尺寸由参数长度说明。需要特别指出的是,数值型参数具有字长压缩能力,例如一个整型数 0x20,按照计算机字长标准需要占用 4 个字节,但是实际尺寸只有 1 个字节。这时参数长度会说明为 1,忽略前面 3 个 0。如本章开篇所述,数值型参数遵循 Little Endian 格式。
图 3.3 消息结构
3.2 通信方案
LAXCUS 在 FIXP 协议基础上提供了四种通信方案。这些通信方案将根据所属环境和任务的不同需求,实现有区别的通信,达到节约网络流量,降低运行负载,提高计算效率的目的。
3.2.1 TCP 通信
TCP 通信建立在 TCP/IP 网络的 TCP 模式基础上,主要针对持序的、大流量的数据传输。比如数据块的分发。在有上千台计算机运行的集群环境中,这种流量规模的数据通信会占用大量的网络带宽,造成网络阻塞,严重影响集群其它通信业务的正常进行,更严重的甚至会造成网络的瘫痪。所以,大流量的数据传输是受到限制的,已经规定必须在 HOME 节点监管下进行。
3.2.2 UDP 通信
UDP 通信建立在 TCP/IP 网络的 UDP 模式基础上,主要针对于非持序、可靠性要求不高的小流量数据传输。在系统的网络通信中,基于 UDP 传输的 FIXP 协议包,数据尺寸普遍介于 20 至 300 字节之间,小于一个 IP 包的最大传输单元 (MTU),并且以网络监控包为主,测试节点是否正常运行的心跳包是最常用一种。UDP 通信是 LAXCUS 使用频率最高的通信方案。
3.2.3 KEEP UDP 通信
UDP 的优点在于对计算机的资源占用率低,缺点是数据通信不稳定,存在丢包现象。TCP 恰恰相反,可以提供稳定的数据通信,但是对 TCP/IP 堆栈的资源占用率高。在系统的网络通信过程中,存在大量需要保持稳定通信,但是又希望采用 UDP 的通信业务。如何拥有二者的优点而且避免其缺点,答案就是“KEEP UDP(可持续的包通信)”。KEEP UDP 是 TCP 和 UDP 之间的一种过渡方案,通过在 UDP 基础上模拟 TCP 通信过程,为 UDP 数据提供稳定的通信保证。这个方案的实质就是将原来在 TCP/IP 堆栈上进行的包的分组和重组的工作,转移到 LAXCUS 控制的工作线程上去执行。在减轻 TCP/IP 堆栈压力的同时,还能够根据当时需求,自由定义一些对包的特殊规则。目前 KEEP UDP 主要是发送网络日志和 RPC 处理,这些都是数据流量不大但是需要可靠传输的业务。
3.2.4 RPC 通信
RPC(远程进程调用) 的出现由来以久,是一种非常优秀的网络通信方案,至今仍在被广泛使用。它通过隐藏网络两端通信的方式,使网络上两台计算机之间进行的网络调用类似本地 API 调用的过程。这样就极大地简化了程序员对网络编程的难度,提高了工作效率,减少了出错的机会。
LAXCUS 包含了对 RPC 的实现,它的通信建立在 TCP 和 KEEP UDP 通信基础之上,通过在本地嵌入接口和对程序员屏蔽网络流程,实现 RPC 调用处理。目前节点间许多复杂的、安全度高的网络通信都被要求采用 RPC 方案执行。
3.3 通信检测
集群运行过程中,发生的很多故障都与网络和网络设备有关。根据统计,这些故障大致包括:线路损坏、插口松动、电磁影响、网络阻塞、网络设备损坏。其中有些是硬件故障,有些是暂时性的网络故障。判断故障的有效手段是通过发送 ICMP 包来检测网络可达。这项测试可以由单机处理,必要时需要多个节点对一个地址共同测试,然后汇总测试结果得出答案。系统将判断故障是暂时性的网络问题或是不可恢复的物理故障。如果问题严重,将报告给系统管理员,通过人工处理来解决故障问题。通信检测在所有节点都会执行,是体现集群弱中心化和自维持能力的必要手段。
3.4 通信服务器
如 1.3 节所述,通信服务器是节点管理下的一个工作线程,采用 FIXP 协议通信。通信服务器在启动时分别绑定 TCP/UDP 两个模式的监听套接字 (SOCKET),套接字参数在配置文件中定义。根据系统的规定,工作节点的套接字地址在启动时由系统随机选择,管理节点的套接字必须有固定的 IP 地址和端口。因为只有管理节点的地址固定,工作节点才能够在网络上找到管理节点。通信服务器不主动发起通信工作,只接收外部发来的命令。在收到命令后,分派给下属的任务线程完成具体的任务处理。通信服务器还承担网络通信安全的职能,确保通信过程中,网络两端传输的数据是正确和可信任的。通信服务器的安全管理是一个可选项,是否使用由用户决定,在配置文件中设置。
3.5 全局时间
在网络通信过程中,为了能够辨别各节点之间数据处理的先后顺序,需要一个参数来标识它们当时所处的位置。这个参数被称为全局时间,也称为主时钟或者时间轴。全局时间以集群中唯一的 TOP 运行节点的操作系统时间为标准,其它所有节点必须遵从这个时间定义,与 TOP 运行节点保持一致。全局时间在节点启动时向所属上级管理节点申请和获取,在本地操作系统上设置,误差要求不超过 1 秒。全局时间目前已经使用在网络日志、网络计算,以及主块冲突、数据冗灾处理中。
网络计算
网络计算是在网络通信基础上实施的数据计算工作,相较于集中计算,网络计算更适合处理那些复杂的、数据量大、耗时长的计算任务。进行网络计算的前提是数据可以被分片。分片的办法有很多种,最常用的是按照数据范围和散列分片。需要强调的是,分片后的数据区域之间不应该存在数据重叠的现象。
LAXCUS 网络计算模型的设计基于网络节点物理分散逻辑统一这个现状,其宗旨将系统职能和用户职能分开。系统负责网络通信、计算任务的分配和调度、故障管理等工作,为用户的计算业务提供一个稳定的运行环境。用户的职能由程序员通过网络计算可编程接口实现派生编程,把各种业务规则转化为计算机可执行的程序代码,然后发布放到集群上运行,与系统功能结合,共同完成网络计算工作。
另外声明:很多资料介绍中,网络计算又被称为分布计算。为减少歧意,在这里统一称为网络计算。
4.1 DIFFUSE/CONVERGE 算法
对于传统的集中计算的工作模式,其数据处理过程可以理解为:产生 / 计算,扩大到网络环境,可以进一步解释为:分散 / 汇合。这也是算法名称的由来。LAXCUS 网络计算模型即源于这一思路。
以下结合集群网络和图 4.1,阐述 DIFFUSE/CONVERGE 算法的处理流程。
如图所示,DIFFUSE 是网络计算的开始,同时会有多个 DIFFUSE 请求分别作用到不同的节点上,根据内部携带的命令产生供后续的 CONVERGE 计算用的原始数据。在实际应用中,这些命令可以是 SQL 语句,或者是用户自定义和自解释的数据和参数。
CONVERGE 是第二步,它分别从多个 DIFFUSE 结果中提取需要的数据,然后执行计算。当计算完成时,如果还有继续计算的需要,就将本次计算结果交给下个 CONVERGE 处理;如果没有,向任务请求方返回计算结果。这个计算结果也是 DIFFUSE/CONVERGE 计算的最终答案。
可以看到,DIFFUSE 只执行一次,CONVERGE 会执行多次迭代计算。这正是本节需要说明的:DIFFUSE/CONVERGE 算法的本质是步骤间串行、步骤内并行的工作方式。当前步骤结束后进入下一个步骤,当前步骤内同时有一批线程对上次的数据进行再计算,线程之间无联系。计算过程中,每一个步骤执行同一程序的副本,当前步骤的数据输出是下次步骤的数据输入,直到最后输出结果数据,完成计算任务。
在 DIFFUSE/CONVERGE 计算中,出现最多的数据处理是:排序、分解、重组、筛选。
按习惯,LAXCUS 把实现 DIFFUSE/CONVERGE 算法的中间件程序称为“任务”。任务编写完成后需要发布到节点上以供调用。
图 4.1 DIFFUSE/CONVERGE 处理流程
4.2 任务命名
任务发布后,需要向集群传播一个标识说明它的存在。这个标识被称为任务命名。任务命名是一个任意长度的字符串描述,由 ASCII 码集中的英文字符、数字、下划线的组成,英文字符不区分大小写。系统要求每个任务命名在集群中都是唯一的,这样才能够保证区别不同的发布任务。节点把任务发布成功后,会向 HOME 节点注册任务命名。通过任务命名,关联节点可以快速检索到成功发布的任务,保证后续启动和调用的需要。
生成任务命名的权限没有具体规定,但是重名会导致调用和计算过程的混乱,所以命名最好由系统管理员或者拥有系统管理员权限的用户分配。因为他们拥有管理整个集群的权限,通过检查全网的任务命名,防止出现重名现象。
任务实现
系统为 DIFFUSE/CONVERGE 算法任务提供了一套编程接口,这个编程工作由程序员来完成。一个完整的任务由五个阶段组成,每个阶段的工作内容和范围,系统都由做了明确的设定。程序员编码完成后,需要打包发布到相应的节点上。CALL 节点处于任务协调中心的位置,负责任务各阶段的管理和分配工作。
4.3.1 INIT 阶段
这个阶段是对网络计算任务进行初始化处理,设置后续阶段运行需要的配置数据。配置数据根据用户输入的自定义参数,和结合系统当前可提供的资源产生。INIT 阶段任务指定发布到 CALL 节点。
4.3.2 FROM 阶段
这个阶段对应 DIFFUSE 算法,产生网络计算任务最初的原始数据。数据的来源目前有两种:使用 SQL SELECT 语句产生,或者自定义的数据和规则产生。数据产生后会被保存到磁盘上,同时生成数据位图信息返回给 CALL 节点。数据位图是对数据计算结果的抽象化描述,系统提供了一个基础框架,由系统或者用户生成。FROM 阶段任务指定发布到 DATA 节点。
4.3.3 TO 阶段
这个阶段对应 CONVERGE 算法。如 4.1 节所述,CONVERGE 是迭代化的处理过程。为匹配任务迭代,TO 阶段在其之下,定义了一个子阶段:NEXTO,以加以区别。NEXTO 理论上可以无限迭代。TO 和 NEXTO 阶段的数据源自上个阶段的计算结果。本次计算结果,如果当前处理不是迭代过程的最后一次,数据就在本地保存,向 CALL 节点返回的是数据位图信息,否则向 CALL 节点返回这次计算结果。TO 阶段任务指定发布到 WORK 节点。
4.3.4 BALANCE 阶段
这个阶段存在于 FROM 和 TO/NEXTO 阶段之后。它的工作是根据数据位图信息,为后面的 TO/NEXTO 任务平均分配当前散布在各节点上的数据资源,希望每一个 TO/NEXTO 任务以基本相同的时间完成数据计算,达到节省总计算时间、提高计算效率的目的。当前的数据位图信息,如果是由用户生成,那么解释工作也由用户完成,否则由系统默认的接口执行。BALANCE 阶段任务指定发布到 CALL 节点。
4.3.5 COLLECT 阶段
这个阶段承接最后一次的 TO/NEXTO 任务,是对实际计算结果进行的最后处理。最后处理包括:对来自可能不同 CALL 节点的计算结果的整合,某些个性化处理,以及数据输出。数据的输出地址,系统提供了磁盘和计算机屏幕做为输出目标。COLLECT 阶段任务的发布位置由用户选择,可以是 CALL 节点或者终端。
4.4 计算过程中的数据平均分配问题
判断网络计算效率的重要指标之一是计算的运行时间。计算时间的长短,取决于所有线程中最慢的那个线程的计算时间。所以,为了实现高效的数据计算,需要保证每个线程的计算时间基本一致。而每个线程的计算时间能否保持一致,忽略掉计算机性能这个指标不谈,分散到每个线程上计算的数据量是否平均,基本上能够决定每个线程的计算时间能否保持一致。
LAXCUS 采用“模”为平均数据提供指导依据。
按照 LAXCUS 的定义,模是数据分布数量的参考标准,是一个 64 位无符号整数,具有两种含义:1. 相同的模,它代表的数据范围是一致的;2. 在以升序排序后的模数组里,相邻的模,它们所代表的数据范围是衔接的。
在 4.3 节所提的数据位图信息,它的实质就是数据映射模为后,散列化的元信息集合,同时还包括节点地址、数据的磁盘地址等。
BALANCE 的位图计算,是在收集了来自各个 TO/NEXTO 任务的数据位图信息后,按照模值进行的重新分配,尽可能的为后面的每个 TO/NEXTO 任务分配相同量的数据。这样,在不考虑计算机性能的情况下,理论上,每个节点的数据计算时间能够大体保持一致。
模概念的引入,解决了网络计算过程中各个线程处理时间不一致的问题,有助于提高计算效率。
安全管理
安全对于当前计算机网络的重要性,已是一个不可回避的话题。数据处理过程中的任何一点疏漏都可能造成无法挽回的损失,所以提供一个全面的安全管理方案成为必然选择。基于对这种现状的考量,LAXCUS 在数据处理的每一个环节都实施了安全管理。安全管理主要围绕着两个方面进行:防窃取和防篡改。同时,出于对计算机性能、计算效率、运行压力的考虑,而安全管理通常又是非常消耗计算资源和时间的计算,所以,某些环节的安全管理设为可选项,决定权交由用户选择。比如内网通信过程中的安全,由于内网的安全保障程度比较高,而且内网的数据传输量非常大,网络计算工作几乎都在内网中进行。这种情况下,为了给网络计算腾出基础资源,提高数据计算效率,可以酌情选择不采用。
本意将阐述在哪些环节实施安全措施,以及实施的办法。
5.1 通信安全
在一次网络通信开始时,为了确保任务请求方是可以信任的,任务受理方会要求对方出示通信安全凭证。这个凭证将保证双方在安全的状态下通信。
通信安全凭证需要在 FIXP 服务器上配置,里面存储着请求方必须出示的信息。安全通信类型分为三种:地址验证、账号验证、地址 / 账号复合验证。当受理方要求出示安全凭证时,请求方必须遵守这个协定,向受理方出示自己的安全凭证,否则通信将被受理方中止。请求方也可以主动向受理方要求安全校验,受理方都是会接受的。
在通过安全凭证检测后,可以确定网络两端间传输的数据是正确和可信任的,这样就为后续的数据处理提供了一个基本的安全保障。
但是使用中也有例外,比如本节上面提及的内网通信。因为内网相对公共网络安全度颇高,而通信安全项除了地址验证外,其他两种都需要进行大量计算,这会造成任务处理的延迟,对大规模、高密度的网络计算来说显得得不偿失。所以,一般的建议是,在穿越 VPN 或者互联网的通信双方,应该启用安全通信;在信任度高的内网,这项工作可以忽略。
5.2 账号安全
用户无论是以终端或者应用接口接入 LAXCUS 集群,系统都要求使用者提供一个登录账号。按照 LAXCUS 规定,账号由用户名称和密码组成,系统管理员拥有管理整个集群的权力,每一个账号必须经由系统管理员建立。用户账号由系统管理员在终端输入,账号的用户名称和密码的明文不会出现在网络的任何位置,而是首先在本地散列为 SHA1 码,再通过网络上传,保存到 TOP 节点的数据字典里,供以后查证和调用。这样就保证了账号产生过程中的安全。
账号持有人拥有修改账号密码的权利,当系统管理员建立该账号后,可以修改由系统管理员设置的密码。这样做的目的是,除了账号持有人外,任何人包括系统管理员,都不能再通过该账号,操作其属下的数据资源,从而保证了账号持有人和账号属下的数据资源的绝对安全。
账号中还包括了账号持有人的命令操作许可,这些许可也是系统管理员赋予的。操作许通过 SQL 命令设置。系统管理员的权限可以延伸和再分配,被赋予了系统管理员权限的用户也可以拥有与系统管理员平等的权力。
5.3 登录安全
用户登录进入 LAXCUS 集群,除了需要提供登录账号外,还必须持有一个系统管理员颁发的安全许可证书。这是一个经过 RSA 算法签名的文件,由系统管理员建立和保管。用户登录时首先出示这个证书,TOP 节点检查证书的有效性,确定证书有效和登录者可信后,再执行账号检查。与 5.2 节所述一样,网络上传的账号是散列后的 SHA1 码,此时又经过了证书加密,TOP 节点会与本地保存的账号记录逐一比对,判断账号的有效性和操作范围,决定是接受还是拒绝。
登录成功后,双方进入正式的通信状态,此时的数据同样被要求经过加密或者签名处理。目前可供选择的加密和签名算法有:AES、DES、3DES、MD5、SHA1 等。这些算法保证通信双方每一次交换的数据都是安全和可以依赖的。
5.4 数据块安全
数据块的安全依赖于对数据的签名。当数据块从 CACHE 状态转向 CHUNK 状态过程中,系统会计算这个数据块的数据内容,生成一个 16 字节数组序列,做为校验码保存到数据块里。数据块的签名过程很快,一个 64M 的数据块签名生成时间,在 PENTIUM4 2.0G 的计算机上,通常在 10 毫秒以下。
当 DATA 节点重新启动,或者数据块被加载到内存,或者通过网络传输到另一个 DATA 节点,系统会重新根据数据内容再次生成一个校验码,与已经存在的校验码进行比较,确认数据的完整性,从而保证后续数据处理的数据本身是正确的。
5.5 行和列集安全
数据块在从 CACHE 状态转入 CHUNK 状态过程中,除了生成针对数据块的签名,还会根据数据块的存储模型,针对每一行或者每一列集合,生成它们的 CRC32 校验码,并且保存在它们记录的开始位置。
设置行 / 列集校验码的原因是,因为整块的数据不会被经常调用,而行 / 列集的数据却总是在网络上大量、频繁传递,这就使得行 / 列集的数据校验更有实际意义。
然而相较于少量的数据块签名计算,被传输的行 / 列集因为粒度细、数据量大、校验次数频繁,计算持续时间也会更长,这将消耗大量计算资源,影响到网络计算的处理效率。所以,通常任务请求方在收到计算结果后,会根据数据的来源来选择是否检测。如果是内网数据,由于网络安全度高,这个校验可以被忽略。
5.6 数组列安全
LAXCUS 中的数组列,包括二进制的字节数组和字符串数组,这些列中的内容,偶尔会保存一些很关键的信息,比如密码、电话、家庭地址等私密信息。这些信息,通常是不希望被别人知道的,包括系统管理员和运行的集群本身。还有一些内容,比如像网页或者文档这样的文本数据,可能会很长,如果用明文的方式保存会占用较多的存储空间,将其压缩后再保存可以有效减少空间占用,而且文本数据的压缩比率都是很高的。
LAXCUS 提供了这样一个选项,可以对这类信息进行压缩和加密。数据的压缩和解压、加密和解密的控制权由用户掌握,在终端或者应用接口上完成。系统在其中只是被动接受和传递,不做任何处理。具体使用,见 6.3.4 节介绍。
感谢梁堰波对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。
评论