第三部分 派生数据
存储和处理数据的系统分为:记录系统和派生系统,后者可视为冗余部分,以前者为准;
第十章 批处理系统
web这种交互模式并不是唯一的系统类型,一般有三种类型的系统:
在线服务,服务端等待客户端的请求,收到请求后尽快返回响应,以平均响应时间为性能指标(包括可用性);
批处理系统(离线系统),接收一批静态、历史的、预先存在的数据,处理执行相当一段时间,客户端不会等待其响应,通常定时执行处理该批量数据,以吞吐量为性能指标(处理数据的耗时);
流处理系统(近实时系统),处理连续不断到达的实时数据,数据是以事件的形式流入系统,相比批处理系统,执行延迟更低;
unix上的批处理
最大的局限性是只能运行在单机上;
cat /var/log/nginx/access.log |
awk '{print $7}' |
sort |
uniq -c |
sort-r -n |
head -n 5
- line 1,读取日志文件;
- line 2,将每行按照空格分割为不同的部分,且仅输出第七部分,即请求的url地址;
- line 3,按照字母顺序排列url地址列表;
- line 4,检查相邻行是否相同,过滤掉重复行,并输出一个计数器,计数不同的url的出现次数;
- line 5,按照每行的起始处的数字排序(计数值),降序返回结果;
- line 6,只输出结果的前五行;
常用命令:awk、sed、grep、sort、xargs
统一的接口
使用管道串联时,不同程序对应的输入输出需要兼容的接口,在unix中即为文件(文件描述符)
即使是相同数据模型的数据库,做数据迁移也不容易,因为继承性的缺失导致了数据的巴尔干化,即数据被割裂、分散在多个地方(因为没有统一接口);
MapReduce和分布式文件系统
hdfs 通过网络连接,在每台机器上都有一个守护进程,开放一个网络服务供其他节点访问该机器上的文件;
namenode 作为中央服务器,管理追踪文件块存储在哪台机器上(包括副本);
reduce端的join和分组
通常reduce处理后的事件,或者流数据,在分析任务时可能需要和 当前处理的数据 和 数据库中的信息 相关联,即使用 join 操作;
最简单的 join 就是遍历当前处理的事件,再去数据库根据唯一标识进行查询,很明显性能极差;
优化的方法,将数据库数据提前备份到hdfs,再由MapReduce集中所有有关数据;
理数据倾斜
即某个关键字的相关数据量很大,导致单个 reducer 处理的数据量明显比其他的 reducer片多,防止延迟当前作业的完成时间;
hive 的优化为,提前在元数据识别出热点,在map端进行join;
可以分阶段执行聚合热点,每阶段聚合一部分数据,最后合并为单一值;
map端join
- 在Map阶段,Mapper节点会将本地的数据和广播的小数据集进行Join操作。这样可以避免在Reduce阶段的大量数据传输;
广播哈希join:
大数据集中每个分区读取整个小数据集,多个map任务;
即:
- 当其中一个数据集很小(足够装入内存)时,可以将这个小数据集广播给所有的Mapper节点;
分区哈希join:
即对输入map的数据进行分区,即将分类的数据,和对应的哈希关系(映射关系,如对外键哈希分区)
多个数据源的分区策略必须一致;
在hive中被称为 backeted map join;
排序join:
如果输入的数据集已经按照Join的Key进行排序,Mapper可以直接读取两个有序的数据集并执行类似于归并排序的Join操作;
即原本不能确定全局顺序,现在可以区分出输入数据集各自的顺序时,就可以使用归并如依次寻找最小值去合并(性能好),最后的结果是有序的;
批处理工作流的输出
生成倒排索引:
mapper对文档进行分区(分词计数等),reducer构建分区索引,并写入分布式文件系统;
构建机器学习系统,如分类器,推荐系统等;
mapreduce 如果直接读写数据库,那么数据库可能会过载,且影响查询性能,通常满足一个大任务,全有或全无;
则写入分布式文件系统内更佳,数据文件写入后就是不可变的;
进一步
中间状态实体化(如 RDD)
一个大任务内会有多个作业,可能有依赖顺序,即中间状态可能被多个任务依赖,可持久化,避免重复计算;
数据流引擎
如spark,flink等;
他们将整个工作流都看做一个作业,同样对输入分区并行处理,输出会被复制到网络上成为另一个RDD的输入;
工作流所需的数据和join都是明确声明的,即由调度器去做本地优化,如拉近输出和输入的距离;
中间状态的持久化不是写入分布式文件系统(被复制会浪费),而是写入磁盘或本地内存;
任务开始执行的时机是其输入条件准备完成即可,不需要等上一阶段的任务全完成后才开始;
spark通过血统图,重新计算丢失数据;