数据平台-推演单机到分布式应用

文章探讨了一个数据同步工具从简单脚本到成熟集群管理系统的演进过程,包括从最初的脚本方式到引入数据库配置、多服务器负载均衡、控制中心资源调度等改进。作者强调了系统设计的可复用性、可扩展性和可维护性,并遵循面向对象设计原则,以提高系统稳定性和容错能力。最终设计中,作业管理和资源管理分离,实现了任务的智能分配和资源的有效利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

最近看到一个在生产中运用的工具,用于同步不同来源的数据到hdfs,而且运用的较为广泛,但是业务反馈问题也颇多。所有的任务通过写脚本形式直接扔到特定的几台机子上,都是采用磁盘传输。存在几个问题:

  1. 使用难,维护和扩展难。没有输入控制,没有统一的日志打印机制。每个人员都必须记住自己配置的目录,文档没有维护好很容易漏。随着数据量的递增就需要考虑分盘,甚者分服务器。配置会更加眼花缭乱,容易出错。也容易影响到其他服务器目前配置的任务,容易引发新的异常。
  2. 对接新需求容易干扰现有业务。应对突发问题,内化问题能力不足。现在缓存目录都是各个业务自己配置上去,没有全局的视角去做资源的权衡,很难知道自己上线的同步任务会对现有传输造成什么影响。磁盘传输速度有限,发生异常,历史接连几个任务需要同时在同一磁盘上传输容易造成,互相干扰,导致传输速度急剧下降。
  3. 容错能力弱。filesync在同步的时候,会先去ping目标服务器,如果可以ping通,那么任务就会发往默认的第一台服务器,不论服务器的磁盘负载是否高。最坏的情况就是所有经过相同传输服务器的job都延迟。备用机的资源没法利用上。最坏情况是经过相同节点的传输的任务都延迟

RP不行,这个东西现在落在我手里进行维护。看到糟糕的设计心里就痒痒的,在看一下那一点美感的代码都没有,心里更是急痒难捱。有美感的代码是让自己保持对开发充满激情的原生动力之一,这种破坏原则的东西,不能容忍呀,遂开始构思

第一版

原先的设计定位为工具,看起来挺简单,用户需要需要配置相关参数,确保数据传输的机器之间是有权限进行数据拷贝传输的。就可以实现上传。 产生的问题入概述中所列
第一版

第二版

开始引入管理的意识,将配置统一放到数据库,由application进行读取。避免重复开发,提升整个工具的三性(可复用性,可扩展,可维护)。更确切地说他应该已经是一个系统,而不是工具。从这个角度来看,这也是我认为Sqoop1和Sqoop2最大的区别,一个是工具,一个是已经具备一定管理能力的系统。
第二版

第三版本

随着数据量的提升,一台机器肯定不够用,这时候会部署多台机器,client端随机ping下可用的机器,ping同则将任务提交到该台机器。这样的设计最直观的益处是通过人为指定ping的顺序,可以将原先一台服务器任务,分成多台机器共同承担,可以缓解一定的压力。同时坏处就是,客户端需要知道服务器地址,违背了组件通信最少知识设计法则。由客户端去控制传输的服务器显然也不可靠。依然可能产生作业相互干扰,提升的容错能力极为有限。这种情况最坏情况下回变成第二种版本。
第三版

第四版本

在这里我们引入控制中心,所有的server都会在控制中心注册,并定时上报系统目前的资源状况,当作业提交后,控制中心根据各台机器的资源状况选择一台或者若干台的机器,执行任务。到这个版本,可以实现在提升整个系统的三性的同时,引入资源管理这样一个层面的组件,实现对多台服务器的统筹管理,整个服务上升成为一种集群形式,提供系统容错性,降低了由于资源没有充分利用而造成的任务踩踏的问题。已经可以解决概述中提到的三个问题 第四版本

第五版本

这个版本引入是出于内心的隐僻吧!控制中心集成了资源管理和作业管理,职责太多,代码耦合较为严重。所以从控制中心拆分成作业管理,资源管理俩个组件。资源管理负责收集各个server的存活状态和服务器资源状态。作业管理,对作业进行拆分,然后对拆分的子任务单独进行资源申请,申请到资源的子任务会被分发到相应的服务器。为了不影响其他作业,eg一个任务抛出异常导致整个服务异常,每个application执行任务采用container的形式,去执行每个子任务。application 将收集container信息执行状态,并反馈给作业管理。作业管理根据状态,信息用于判断是否进行重新调度。
第五版本
下图是作业管理的基本类图设计
输入图片说明

心得与总结

看过yarn的同学可能最后的设计有yarn设计的影子。但是说实话,yarn的源码和设计很早以前看过,但是在写本文的时候没有刻意去查找yarn的资料。我要说的其实,一句话循原则设计。这点可以借鉴面向对象的设计原则:

  1. 单一职责原则(Single Responsibility Principle) 每一个类应该专注于做一件事情。
  2. 里氏替换原则(Liskov Substitution Principle) 超类存在的地方,子类是可以替换的。
  3. 依赖倒置原则(Dependence Inversion Principle) 实现尽量依赖抽象,不依赖具体实现。
  4. 接口隔离原则(Interface Segregation Principle) 应当为客户端提供尽可能小的单独的接口,而不是提供大的总的接口。
  5. 迪米特法则(Law Of Demeter) 又叫最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用。
  6. 开闭原则(Open Close Principle) 面向扩展开放,面向修改关闭。
  7. 组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP) 尽量使用合成/聚合达到复用,尽量少用继承。原则: 一个类中有另一个类的对象。

遵循原则做事,其实他是超越粒度的一种设计法则,不管是在类级别,还是模块级别,甚者服务级别他都是可以适用的。eg:在遵循原则对类进行设计的时候,会不知觉发现你已经适用某个设计模式。在遵循原则对模块进行设计的时候,会不知觉发现对模块的边界切面很平整,有毛边的边界切面一般是糟糕的设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值