热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

武汉出差大数据项目小结

2014年2月到3月期间,我在实习期间去武汉出差参与一个项目为某上市网络舆情R公司提供技术解决方案。R公司接下了一个为浙江省政府DNS数据分析的项目,但他们自身没有技术实力去解决海

2014年 2月到3月期间,我在实习期间去武汉出差参与一个项目为某上市网络舆情R公司提供技术解决方案。R公司接下了一个为浙江省政府DNS数据分析的项目,但他们自身没有技术实力去解决海量数据的处理。DNS字段相对较小,所以一天的总量也就 1~2 TB 左右,涉及主要业务有从域名、顶级域名、客户端IP等不同维度出发的不同时间粒度的统计,并且运行有时限要求。

技术方案选择。因为这种处理是定时离线处理的(排除Storm等实时系统),而且他们提供的机器内存测试机才8G,线上也就16G(排除Spark等内存方案),再考虑到开发维护难度等,毫无疑问最佳选择便是MapReduce了。基本流程便是ETL(Extract-Transform-Load,即一般的数据预处理流程),然后做个过滤排重,接着业务统计,最后根据需求分别落地到HDFS、Oracle、Redis、Elastic Search等。

ETL一开始便遇到困难,平均一个小时10g的原始数据,而且是一开始放在单机上,要求半个小时做完处理任务。单机一个小时10g做IO还要走网络去分布式,可能光读取数据时间都不止三十分钟。其实最好的解决方案自然是一开始数据就放到HDFS上,但因为放数据那边的技术受限原因,最好的情况也就是放到FTP而已。因此为了提高数据读取效率,我们首先要求对方写了个一个定时压缩脚本,将数据压缩成gz格式,同时也为了提高MapReduce的IO效率,要求将一个小时数据分割成多个小压缩包,每个大概二十多M左右。这样一来在MapReduce解压缩后的大小基本就接近128M了,也就是我们配置的一个block的大小。同时我们还打开了MapReduce的JVM重用(机器数少但Mapper多),试图通过减少多次重启JVM的开销来达到优化,最后效果不是很明显,毕竟每次跑长时间任务的时间多少都会有误差,JVM重启最多也不过几秒到十几秒,相对来说不算是优化的重点。

一开始需求方本来是希望我们按照那个业务处理流程 ETL -> 排重 -> 统计 -> 同步 来按模块实现的,但是MapReduce瓶颈毕竟在那,纯技术类优化是有极限的,因此最后我们只能对业务流程做优化,将部分可以预处理的任务混合了起来。比如排重本来是要求每个不同维度的统计前做不同维度排重,我们在ETL做了一次排重然后按统计维度分发,如此一来接下来的多个统计MR的IO就大大减少,尽管从不同维度还得再做排重,但是数据量已经下降很多了。

但即使如此,统计时我们一开始仍然不太满意其性能,于是在多Mapper单Reducer的场景下自然而然就想到了应用Combiner。常有人提醒使用Combiner很容易犯些低级错误,这个每个初学Combiner的人应该都知道。当时我踌躇满志的觉得那种低级错误不会犯,于是在一个统计TOP N的任务中使用了Combiner,逻辑很简单,就是每个Combiner筛掉后面的选出TOP N,然后Reducer对来自所有的Combiner的record再统计做TOP N。道理很简单,每个山头选出最厉害的,再将这些最厉害的比一下选出全部中最厉害的,就是一个锦标赛原理嘛!但问题就出在这里了,要保证锦标赛的正确,前提是保证同一个top维度的数据必须在同一个Mapper,但当时读取的时候毕竟不是按top维度的key读取的。于是一开始有种错觉好像效率变快了,但是一看数据发现有不对,反复几次发现问题后,最终还是只能把Combiner去掉。

还有一个比较重要的业务是做diff,要统计相对于上一时间粒度,当前时间粒度新出现或未出现的客户端IP、域名、顶级域名等,类似做个集合差运算。这个设计很简单,读取两个目录的文件(上个时间粒度与当前时间粒度),然后根据读取的文件不同设key,在Reduce端过滤计算。这里要实现MapReduce读取多文件并能知道每条数据来自哪个文件,还要多输出。本来1.0.4内置是有个MultiOutput的,但是当时感觉不好用,于是自己通过看TextOutputFormat的源码重写了一个继承它的多文件读取类,Input也是自己重写的。一切都很美好,但没多久总觉得数据少了很多,挣扎了一两天终于发现bug来自自己写的那个Output,最后同事从Hadoop 1.1.2版本封装了一段MultiOutput类的代码才解决问题。于是最终变成自己写的多输入和抄了Hadoop 1.1.2的多输出共存的局面。

存储方面Redis自然要使用pipeline以及多次重试(Time out太常见了),Oracle自然要做好参数绑定,这些不赘述。

总结一下,我个人从这次项目出差的体会:

  • 技术优化一部分是基础,需要自己养成良好习惯;另外很重要的一步是针对业务做优化,否则在这个层次空谈性能优化有点耍流氓。
  • 在我们选择技术方案的时候,很多时候要靠经验,盲目相信别人的评测或选择常常导致自己会出问题而不知所措。
  • 出问题了代码有机会最好和同事一起做做peer review,常会有意想不到的收获(bug)
  • 对于我们这类经验尚浅的程序员,设计架构方案的时候其实不需要过分地深入思考性能等问题,因为很多问题没有实际做过是想不到的;根据自己已有经验做个初步方案,然后通过发现问题逐渐修改迭代。

武汉出差大数据项目小结


推荐阅读
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
author-avatar
patrick0129_645
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有