夏同学面经

面经 xug9998 ⋅ 于 2020-08-04 13:31:41 ⋅ 1808 阅读

项目准备
基于用户设备测量报告的大数据RF侧质量优化项目
UE在Idle状态和connected状态下都会进行测量,测量包括同频的测量和异频测量还有inter-rat测量,这些测量的信息包括rsrp,sinr,pathloss等表征当前ue无线环境特征的参数,正常情况下这些测量报告不会上报给核心网,只是上报给eutran以便进行eutran对手机进行重选、切换、回落等操作,但是可以通过EMS/CSS下发测量报告收集任务,将指定时间指定范围的测量报告收集到数据分析服务器上,每cell每天能产生5到10万的mr,项目在进行簇优化的时候每个簇大概有一千个小区左右,所以每个簇一天就可以产生五千万到一亿条的数据,其中带有agps的数据的大概有百分之零点三到百分之零点四。数据处理的步骤,首先将数据采集分析服务器上的数据上传到集群hdfs上,使用MapReduce对数据进行字段的划分抽取,因为mr是以二进制形式存储,所以我们重写了一个inputformat类型,对数据进行切分,比如file inputformat的record reader是每一行调用一次map方法,但是重写的这个measurement report inputformat,是通过报文头进行识别的。每个测量报告中有32个字段,常用的字段有rsrp、干扰信号功率、sinr值、时间提前量、邻区的信号rsrp、电平,将这些数据转换成avro表的文件,通过脚本自动创建分区并将指定时间分区内的数据移动到分区所对应的目录,储存到avro表的原因是因为avro表可以使用schema文件随时拓展字段,然后通过insert into Table select from 语句从avro查询需要的业务字段到orc表,orc表有:

  1. 分析干扰的表,包含干扰功率、ue位置,主服务小区频点,干扰信号频点
  2. 弱覆盖、过覆盖的表,电平、邻区电平,ue位置
  3. 邻区优化表
  4. 导入EMS指标进行联合分析,包括掉话、接入、信令、流量、用户事件分析,这是常用的集中优化维度。
    使用orc表的原因是orc自带索引,而且压缩,每行的数据没有字段信息,占空间比较小查询性能更高,再从orc表查询需要的业务数据到MySQL表,再通过报表系统查看数据
    shell脚本有六个,
  5. 执行测量报告文件转avro的MapReduce,
  6. 执行avro表自动创建分区
  7. avro表文件移动到指定分区目录
  8. 查询avro表中的数据insert into orc表
  9. 使用hive -e命令查询出\t分割的数据结果
  10. LOAD DATA LOCAL INFILE命令将hive -e查询到的命令导入到MySQL中
    这些步骤较多所以使用了oozie进行流程上的控制,保证各个脚本能够有序执行。
    这个项目中我负责的部分有测量报告转avro表MapReduce逻辑的实现,其中我封装了很多工具类,包括
    baseMR任务链中的任务对象可以直接通过继承这个基础类的子工厂类进行get获取
    JobRunUtil可以通过封装任务执行的逻辑,简化任务链类的编写
    JobRunResult任务返回结果的类也进行了专门的封装
    另外还写了一些udf小工具。
    file
    file
    财经资讯网页实时获取项目
    该项目使用Python进行开发,基于发布订阅模式和生产者消费者框架,其中联系多台机器的纽带是MySQL库和Redis库。

第一步建立种子表数据库,将种子表数据库中的数据全部导入到queue表中,这个一步相当于发布者将数据发布到队列中间件,MySQL中的这个queue表相当于发布订阅模式中的代理。队列表的设计是type表示当前执行的哪种模式,是抽取内外链还是在进行下载,is_work表示该条记录当前是否已经被某台机器操作,相当与自己实现了一种独占锁,params列存一些无关紧要的参数,比如新闻的类型,fail_ip记录失败的ip,fai_time记录失败的总次数,最后的创建时间没什么重要的。

第二步,生产者类中有一个缓存list,每次可以调用生产方法拿取一批次的消费动作对象,进入循环,当真正的队列中未完成任务个数消费者线程数,缓存list会发派一个消费动作到队列中,当缓存中消费者用完时,退出循环。生产者休息一段时间。在这个类中还负责启动消费者线程,根据设定的消费者线程数量启动相应的消费者线程。消费者线程,一直循环从真实队列中拿取消费动作对象,然后执行这个消费动作对象的Action方法,如果执行不成功,且失败次数没有达到上限,将失败次数自增,然后放回队列,休息一个设定范围内的随机时间,目的是防止反爬取。以上这些框架部分的内容都是封装好通用的工具代码。
需要特殊实现的地方是,producer的Action,创建一个批次的消费动作对象,拿数据的要求是当前机器ip不是失败ip黑名单上的,而且失败总次数没有达到上限,拿去后将is_work的状态更新成1。
另外需要实现的是消费者动作对象,在这个项目中消费者实现的是使用phantomjs无头浏览器,获取html对象,使用beautiful soup工具获取全部的a标签对象,判断内链外链,内链放入Redis中,其中Redis的键分为备份键和下载键两种,下载键的数据随着下载的进行会被删除,值使用字符串拼接分隔符的方式存入的,包含的字段有网页的一些原数据信息,网页的domain,host,category,响应时间,内链本身这些数据。执行成功的话更新seed表中上次爬取成功的网页数,并且删除queue表中的数据。如果失败,将工作状态复位,同时添加本机的失败次数和ip到队列表中。

第三步迭代scan内链中的下载键,成功拿取的数据放入到MySQL的queue表中,跟据之前设计的分隔符抽取数据,此时type为2,Action为要下载的网页,params是一些网页的元信息。

第四步还是使用之前提到的生产者消费者模式,只不过这次消费者逻辑变成了下载网页,获取URL和HTML以\001拼接得到内容字符串,通过md5对内容字符串进行计算,得到校验位,用于后续校验完整性。同时为了进一步确保网页写出完整,将\r全部去掉、\n替换成\002。每五分钟一次换一个文件名,并将之前的历史文件移动到待上传目录,效果就是写出目录下,每个线程都有一个文件,查询失败和成功的逻辑也和上边一样需要更新一下其他表中的状态。失败的条目会更新失败次数和失败ip。当自身机器的失败次数达到上限,且总失败次数没有达到上限的时候,将is_work状态更新成0,以便其它机器可以获取。

通过脚本,将待上传目录中的文件进行进一步的合并,再将文件上传到hdfs目录。可以进行后续的文件离线分析。当然在下载逻辑中我们后来又添加了插入到kafka队列的逻辑,这样可以使用spark-streaming流式计算对kafka队列中的网页html数据进行处理,到达正文抽取的效果。

这个项目的创新点是通过生产者消费者模式,加上Python自带的queue工具类,实现了一个多线程高并发的单机多线程处理框架,这套框架在针对别的场景的时候只需要重写,producer的queue_item逻辑,即批量生产消费动作的。而consumer部分只要重写这个消费动作的逻辑就可以。其它还提供了重试容错的机制,适合请求外部网页这种存在不确定性因素较多的情况。另外,有配合MySQL和Redis搭建发布者订阅者模式框架,将原来的单机多线程扩展为多机多线程。MySQL线程安全的核心是for update独占锁的使用。
财经资讯网页正文抽取项目
上面提到过,在下载的consumer添加了插入到kafka队列中的逻辑,这样可以通过spark-streaming对kafka队列中html进行处理,
如果zookeeper中有offset的历史数据,从zookeeper中读取偏移量数据,并更新偏移量,进行正文抽取的算法是基于之前看过的一篇文章,找到所有包含div的标签,去掉不想干的标签内容比如form,script,css等html标签,按字符串的长度进行降序排序,这里的长度只计算中文字符,此时的标签可能还包含一些版权信息,摘要信息等,这时,对该标签下的子节点如果有一个节点,占父节点信息量的占比超过了一个阈值,根据文中的实验结果,正文标签判断字数阈值设定在50字,主标签占比的阈值设置在0.65比较好,这样判断的准确率是比较高的,但是这样的方法是不能解决新闻正文过短的问题的,还是不能做到完全准确。
此时还存在的问题是,网页正文中有的包含有例如责任编辑、来源、记者等信息,为了将这部分信息单独提取出来,设计匹配含有这些字符xpath的反规则xpath提取器,这样可以在正文将这些内容去掉,也可以单独保存起来。
为此在第一步中,每处理一个网页,就使用该算法将该网页的疑似正文xpath抽取出来,以网站的host作为主键,以zset的数据结构存储到Redis,其中value是该网页疑似正文的xpath,score是该xpath出现的次数,这样就相当于训练了Redis中xpath规则库,当网站中某个正文xpath的占比超过80%,就认为这是该网站的正文xpath,当然有些网站有不止一种网页结构,这个时候取前两中xpath。
极个别网站训练效果不好的,或者网站有超过两种正规则xpath结构的,可以采用MySQL表人为添加规则表的方法解决。Python脚本读取Redis和MySQL中的xpath规则库,并标记好正反规则,写入到一个文件中上传到hdfs,这样可以方便地别集群中每一个机器获取。
此时,spark-streaming中就可以有一个逻辑读取hdfs相应目录下的xpath规则文件,讲这个文件转换为一个广播变量,map的数据结构,广播变量的处理逻辑是,为空或者超过某个时间阈值没有更新的话,就从hdfs中读取并更新一次,这样广播变量中就携带正反规则的xpath信息,获取正反规则xpath的set,变量正规则的set,其中字数最多的就是正文,之后遍历反规则的set,如果匹配到,就从正文提出这些信息,将被踢出的信息单独保存到一个字段中,如果成功匹配到了数据,将网页的元信息(url,host,反规则信息)、网页的正文信息、网页的html插入到hbase中,其中主键是host_时间_url的MD5。另外将这些信息插入一份到elastic search数据库中,方便日后之间查询使用,使用的mapPartition方法,获得一个包含map的数组,最后调用save to ES作为Action。另外,在这个过程中,设置了5个累加器,来记录总的扫描网页、成功抽取的网页数、抽取为空的网页数、没有获取到训练用xpath的数、数据不完整的数量,将这些数据插入到MySQL数据库中,可以生成实时报表,观测当前处理的进度。
面试题
spark和MapReduce的区别

  1. MapReduce最本质的过程只有map和reduce,虽然可以重写partition group等代码的逻辑,但是计算工具有限。
  2. spark是基于rdd的弹性分布式数据集,基于内存,并且可以cache,persist用于缓存多次用到的计算中间结果,checkpoint可以忘掉父依赖关系,存储到磁盘,序列化等多种多样的存储形式,速度快且安全
  3. spark算子类型丰富,使用简单,MapReduce中n多行的代码可以在rdd是利用链式编程缩减到一行
  4. MapReduce中shuffle阶段要经历三次排序,环形缓冲区溢写排序、partition内的文件合并排序、read shuffle阶段的并归排序,但是spark中会根据算子的不同,只有在需要全局有序性的算子下才会进行排序。
  5. spark对于内存的依赖很高,可能会发生频繁的GC
    大数据项目分几个阶段?
    数据规划、数据治理,这些一般由上游提需求的部门来完成,我们接手过来的时候一般先进行数据评估,然后进行技术选型,接下来分析框架模型选取,最后进行迭代实施
    当初为什么会选择大数据这一块呢?
    因为虽然我是学这个专业的,但是在大二的时候我基本已经确定自己兴趣点在编程这一块,所以一直在自学java和Python这一块,当时有个朋友在中兴XXX做大数据开发(主要做政企网项目,中兴技服主要做运营商项目),我在跟他聊过之后看了一些Hadoop权威指南呀、数据算法、Hadoop/spark数据处理技巧这些书,对大数据技术栈有了一个了解,然后16年中兴校招有一个提前批蓝剑计划面上了
    为什么换工作,去了上海?
    首先在xxx的时候是在工程经营部,按公司架构来讲不属于研发线,属于营销线,我们平时工作中是需要花大量的时间来和客户沟通澄清问题的,而且在中兴的两年中用的技术都比较固定,一直是在做基于MapReduce的数据清洗,接触新东西慢,并且中兴管理比较像国企,当然他前身就是国企,可能说的不好听一点感觉不太适合施展拳脚。
    现在Hadoop用的什么版本?2.7,现在3.多版本刚出来,用的比较少,三代hdfs支持可擦除编码,磁盘监控,对hbase有什么优化吗,分region会把表下线掉,使用脚本分region,会根据分region的时间还有hfile的大小预测分region的时间,执行脚本的逻辑。还有就是hbase中常用的数据放到Redis中,这样会走两条逻辑,一条插入hbase,一条插入Redis,这样不仅能提高性能,还能做到小的灾备。
    分布式数据系统分布的规则,一致性hash,一致性hash采用hash环,扩容性好,而且可以通过虚拟节点解决数据倾斜的问题。
    平时都用什么编程语言:看情况java Python Scala都在用,Scala的算子丰富而且使用起来比较简单,Scala的多线程框架也很好用,Scala的源码不是很好看,有很多隐式转换的地方。
    任务管理:用的oozie,有webui可以方便调整任务依赖。
    file
    当时hbase我们在用的时候碰到了一个bug,就是hfile增长到一定程度的时候他会分裂,但是我们实际在使用的时候发现,他的文件是分裂了但是元数据没有更新。
    我们用的是Apache的Hadoop因为要添加一些支持,比如对snappy压缩的支持,还需要自己编译,我了解到现在Cloudera版本(Cloudera’s Distribution Including Apache Hadoop,简称“CDH”)用的比较多。
    刚来公司的时候做数据清洗日志归集这一部分,做一个量化,之后做了全网新闻爬取,那个项目还挺大的,因为高顿网校和app的首页比较重要的一个模块是热点资讯,当时就想模拟今日头条做一种全网收集、并且对正文进行抽取,给内容运营提供素材。然后今年开始做的是相似推荐这个系统,主要是为了app中推荐课程这个功能的实现,后来这个功能也被我们移植到了题库模块的智能组卷,他会根据这个用户的错题记录去推荐相似的错题给用户。语言这一块,是java、Python、Scala都在用,集群方面我们那边用的是Apache的Hadoop,用过的组件像hive、no-SQL的数据库用到像hbase、Redis,后期用到spark,spark-streaming、kafka这些。整体集群是15个节点,zookeeper是搭了5台,name-node弄了一主一备,
版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海牛部落-xug9998,http://hainiubl.com/topics/75258
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter