图1:google bigdata 关键词搜索热度上面的热度曲线来看,大数据发展大概可以分成三个阶段:成长期(2009-2015),这段时期主要代表是Hadoop1.0以及相关生态的快速成长;巅峰期(2015-2018),这段时期主要代表是Hadoop2.0以及Spark迅速成为大数据基础架构和计算引擎的行业事实基础底座;成熟期(2018-now),这段时间主要代表是Spark、Flink等计算引擎以及OLAP引擎的繁荣;从这个热度曲线看,有一个小疑问,近两年大数据热度迅速下降,那么什么技术在近几年成为热度最大的技术?
2013年,大数据巅峰期之初,OPPO开始搭建大数据集群和团队,使用Hadoop 0.20版本(Hadoop1.0)。2015年,使用CDH服务,集群初具规模。2018年,自建集群,已经达到中等规模,使用Hive作为计算引擎。2020年,开始大规模从Hive向Spark计算引擎迁移SQL作业。2021年,从大数据资源层和计算层升级改造。OPPO的大数据发展可以总结成两个阶段:发展期:2013-2018年,OPPO大数据从无到有,慢慢成长,计算节点规模从0扩展到中等规模;繁荣期:2018-现在,三年大数据快速发展,技术上从hadoop1.0升级到hadoop2.0,计算引擎由hive升级到spark;自研技术以及架构升级解决集群规模膨胀后常见问题;
图4:集群1 24小时资源使用情况
图5:集群2 24小时资源使用情况从资源使用情况看,集群2的资源利用率明显低于集群1,这就造成集群之间负载不均匀,资源利用率低下,资源浪费。
图6:ORS2在云数融合架构图有了ORS2,不仅将spark任务的shuffle过程从本地磁盘解耦,同时承接了云上资源的大数据计算任务的shuffle数据。从ShuffleService本身来说,独立出来一个service角色,负责整合计算任务的shuffle数据。同时,ShuffleService本身可以部署到云上资源,动态扩缩容,将shuffle资源化。整体架构上看,ShuffleService 分成两层,上面Service层,主要有ShuffleMaster和ShuffleWorker两种角色。ShuffleMaster负责ShuffleWorker的管理,监控,分配。ShuffleWorker将自身的相关信息上报给ShuffleMaster,master对worker的健康做管理;提供worker加黑放黑、punish等管理操作。分配策略可定制,比如:Random策略、Roundrobin策略、LoadBalance策略。ShuffleWorker负责汇集数据,将相同分区的数据写入到一个文件,Reduce读分区数据的过程变成顺序读,避免了随机读以及MxN次的RPC通信。在存储层,我们的ShuffleService可以灵活选取不同的分布式存储文件系统,分区文件的管理以及稳定性保障交由分布式文件系统保障。目前支持HDFS、CFS、Alluxio三种分布式文件系统接口。可以根据不同的需求使用不同的存储介质,例如,小任务作业或者对性能要求比较高的作业,可以考虑使用内存shuffle;对于稳定性要求比较高,作业重要性也比较高的作业,可以选取ssd;对性能要求不高的低级别作业,可以选取SATA存储;在性能和成本之间寻求最佳的平衡。
图7:ORS2 核心架构图从ShuffleService的核心架构来看,分为三个阶段:ShuffleWriter:Map任务使用ShuffleWriter完成数据的聚集和发送,采用多线程异步发送;使用堆外内存,内存管理统一交由spark原生内存管理系统,避免额外内存开销,降低OOM风险。为了提高发送数据的稳定性,我们设计了中间切换目的ShuffleWorker的共,当正在发送的ShuffleWorker出现故障,Writer端可以立即切换目的Worker,继续发送数据。ShuffleWorker:Shuffle负责将数据汇集,同时将数据落到分布式文件系统中。ShuffleWorker的性能和稳定性,我们做了很多设计,包括流量控制,定制的线程模型,消息解析定制,checksum机制等。ShuffleReader:ShuffleReader直接从分布式文件系统读取数据,不经过ShuffleWorker。为匹配不同的存储系统读数据的特性,Reader端我们做了Pipeline read优化。经过以上的多种优化,我们使用线上大作业测试,ShuffleService能够加速30%左右。
图8:Spark Commit V1 示意图Spark的V1版本Commit,分为两个阶段,Task侧的commit和Driver侧的commit。Task侧的commit,负责将该Task本身产生的文件挪到Task级的临时目录;Driver侧的commit将整所有的Task commit的临时目录挪到最终的目录,最后创建_SUCCESS文件,标志作业运行成功。我们实现了自己的CommitProtocol,在Driver commit阶段的前段加入合并小文件的操作,扫描:${output.dir.root}_temporary/${appAttempt}/目录下面的小文件,然后生成对应的合并小文件作业。合并完小文件,再调用原来的commit,将合并后的文件挪到${output.dir.root}/ 目录下。
图9:Spark Commit 阶段合并小文件示意图这种方式巧妙的避免显性的提交额外的作业对结果数据合并,同时,在Driver commit挪动结果文件的时候挪动的文件数成数量级的降低,减少文件挪动的时间消耗。目前,我们已经在国内和海外环境全部上线小文件合并。
图10:多集群资源使用不均衡示意图从示意图上看,左边代表pending作业,右边代表集群资源情况;长度代表资源量多少,颜色代表资源负载,越深代表负载越高。很明显可以看出来,目前的各个集群资源负载不均衡,同时pending作业情况也跟集群的资源使用比成比例,比如Y1集群的资源负载很高,但是pending作业也很高,Y3集群资源很空闲,但是这个集群没有作业pending。这种问题,我们如何解决?我们引入了社区的Yarn Router功能,用户提交的任务到router,router再分配到各个yarn集群,实现联邦调度。社区版本的Router策略比较单一,只能通过简单的比例分配路由到不同的集群。这种方式只能简单实现路由作业的功能,对集群的资源使用和作业运行情况没有感知,所以,做出来的决策依然会导致集群负载不均匀,例如:
图11:集群1 资源负载情况
图12:集群2 资源负载情况为了彻底解决负载均衡的问题,我们自研了智能路由策略。ResourceManager实时向router上报自身集群的资源和作业运行情况,给出资源释放量的预测,router根据各个集群上报的信息,产生全局的视图。根据全局视图,router做出更合理的路由决策。
图13:OPPO Yarn Router总体上看,有了一个全局视野的Router角色,多集群场景下,充分发挥多集群的优势,同时避免多集群的不足。未来,我们计划赋予Router更多的能力,不仅用来解决作业pending,提升资源利用率。还将从作业运行效率方面做更多的工作,让作业和计算、存储资源做更好的匹配,让计算更有价值。
图14:Waggle-Dance元数据切分示意图上面的示意图,左边是原始的HiveMetastore架构,从架构图本身来看,整体架构存在明显的单点问题,同时数据交换流程不够优美。使用Waggle Dance升级后,整体架构更加清晰,更加优美。Waggle Dance作为元数据交换的“总线”,将上层计算引擎的请求按照库名路由到对应的Metastore。我们在做线上切分元数据实际操作过程中,总体Metastore停机时间在10分钟以内。我们对Waggle Dance做了定制优化,加了数据缓存层,提升路由效率;同时,将Waggle Dance与我们的内部管理系统整合,提供界面话的元数据管理服务。
图15:Livy架构示意图(引自官网)Livy能满足我们的需求吗?我们先看Livy本身有哪些问题。我们总结的Livy主要有三个缺陷:缺乏高可用:Livy Server进程重启或者服务掉线,上面管理的Spark Context session将会失控,导致任务失败。缺乏负载均衡:Livy Server的任务分配是一个随机过程,随机选取zk命名空间的一个Livy Server,这种随机过程会导致一组Livy Server负载不均衡。对spark submit作业支持不足:对于spark submit提交的jar包任务,目前支持的不完善。
图16:Olivia 架构示意图 针对上面的几个问题,我们基于Livy自研了Olivia,是一种高可用、负载均衡、同时支持spark submit jar包任务以及python脚本的计算统一入口。Olivia使用域名提交作业,用户不用感知具体是哪台Server支持作业提交和管理。后台使用一致性Hash实现负载均衡,如果有Server上下线,也会自动完成负载均衡。对于故障转移,我们使用zk存储spark session信息,某个server出现问题,对应管理的session会自动转移到其他的server管理。对于Spark submit任务的支持,我们新增一个Olivia client角色,该client会自动将jar包以及python脚本上传到集群,方便Olivia Server提交作业。
图17:OPPO 大数据平台架构示意图由上到下,我们可以抽象出六层,分别是:Job Submit:这层主要是我们的离线作业调度Oflow,完成任务的定时调度,dag 管理,作业运行管理;核心功能就是实现了任务的提交。Job Control:这层主要有HiveServer、Livy、Olivia这些任务控制组件,负责任务向集群提交和管控。Compute Engine:引擎层主要使用Spark和MR。Shuffle Service:这层是为Spark引擎提供shuffle 服务,后续Shuffle Service也将承接Flink引擎的 shuffle 数据。MetaData Control:Waggle Dance和MetaStore以及底层的MySQL形成我们的元数据控制层,使用了Waggle Dance是我们的元数据管理更灵活。Resource Control:资源控制层,就是我们的计算资源,主要由Yarn Router来控制各个集群的作业路由,各个Yarn集群完成资源的管理和作业运行。我们不仅在Router上有自研的策略,我们在RM资源调度上也探索了更多的调度模式,比如:动态标签、资源限售、更智能的抢占调度。
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,