basic_knowledge
Table of Contents

相关概念

大数据平台

img

三驾马车

分别是分布式文件系统GFS、大数据分布式计算框架MapReduce和NoSQL数据库系统BigTable

即实现了一个文件系统、一个计算框架、一个数据库系统

新三驾马车

Dremel Google的交互式数据分析系统,处理时间缩短到秒级别,作为MapReduce的补充

Pregel 图计算法

Caffeine 大规模实时增量算法

HDFS

Hadoop File System

HDFS分布式文件存储系统,将文件分成很多块(Block),以块为单位存储在集群的服务器上。

HDFS则是水平伸缩,通过添加更多的服务器实现数据更大、更快、更安全存储与访问。

这些年来,各种计算框架、各种算法、各种应用场景不断推陈出新,让人眼花缭乱,但是大数据存储的王者依然是HDFS。

Hadoop

2006年,Doug Cutting将这些大数据相关的功能从Nutch中分离了出来,然后启动了一个独立的项目专门开发维护大数据技术,这就是后来赫赫有名的Hadoop,主要包括Hadoop分布式文件系统HDFS和大数据计算引擎MapReduce。

发行版本

Apache

Apache 版本是最原始,最基础

Cloudera

Cloudera's DistributionIncluding Apache Hadoop

简称CDH

Pig

Yahoo的一些人觉得用MapReduce进行大数据编程太麻烦了,于是便开发了Pig。Pig是一种脚本语言,使用类SQL的语法,开发者可以用Pig脚本描述要对大数据集上进行的操作,Pig经过编译后会生成MapReduce程序,然后在Hadoop上运行。

Hive

编写Pig脚本虽然比直接MapReduce编程容易,但是依然需要学习新的脚本语法。于是Facebook又发布了Hive。Hive支持使用SQL语法来进行大数据计算,比如说你可以写个Select语句进行数据查询,然后Hive会把SQL语句转化成MapReduce的计算程序。

这样,熟悉数据库的数据分析师和工程师便可以无门槛地使用大数据进行数据分析和处理了。Hive出现后极大程度地降低了Hadoop的使用难度

Hive可以在Hadoop上进行SQL操作,实现数据统计与分析。也就是说,我们可以用更低廉的价格获得比以往多得多的数据存储与计算能力。可以把运行日志、应用采集数据、数据库数据放到一起进行计算分析,获得以前无法得到的数据结果,企业的数据仓库也随之呈指数级膨胀。

Yarn 资源调度框架

在Hadoop早期,MapReduce既是一个执行引擎,又是一个资源调度框架,服务器集群的资源调度管理由MapReduce自己完成。但是这样不利于资源复用,也使得MapReduce非常臃肿。于是一个新项目启动了,将MapReduce执行引擎和资源调度分离开来,这就是Yarn。2012年,Yarn成为一个独立的项目开始运营,随后被各类大数据产品支持,成为大数据平台上最主流的资源调度系统

Spark

在2012年,UC伯克利AMP实验室(Algorithms、Machine和People的缩写)开发的Spark开始崭露头角。当时AMP实验室的马铁博士发现使用MapReduce进行机器学习计算的时候性能非常差,因为机器学习算法通常需要进行很多次的迭代计算,而MapReduce每执行一次Map和Reduce计算都需要重新启动一次作业,带来大量的无谓消耗。还有一点就是MapReduce主要使用磁盘作为存储介质,而2012年的时候,内存已经突破容量和成本限制,成为数据运行过程中主要的存储介质。Spark一经推出,立即受到业界的追捧,并逐步替代MapReduce在企业应用中的地位。

HBase

除了大数据批处理和流处理,NoSQL系统处理的主要也是大规模海量数据的存储与访问,所以也被归为大数据技术。 NoSQL曾经在2011年左右非常火爆,涌现出HBase、Cassandra等许多优秀的产品,其中HBase是从Hadoop中分离出来的、基于HDFS的NoSQL系统。

分布式架构

分布式架构的原则:尽量使用无状态的服务,不同服务实例之间不共享状态,也就是不持有数据, 主要好处是服务间无需同步状态或者数据,便于扩缩容

框架设计

框架在架构设计上遵循一个重要的设计原则叫“依赖倒转原则”,依赖倒转原则是高层模块不能依赖低层模块,它们应该共同依赖一个抽象,这个抽象由高层模块定义,由低层模块实现。

所谓高层模块和低层模块的划分,简单说来就是在调用链上,处于前面的是高层,后面的是低层。我们以典型的Java Web应用举例,用户请求在到达服务器以后,最先处理用户请求的是Java Web容器,比如Tomcat、Jetty这些,通过监听80端口,把HTTP二进制流封装成Request对象;然后是Spring MVC框架,把Request对象里的用户参数提取出来,根据请求的URL分发给相应的Model对象处理;再然后就是我们的应用程序,负责处理用户请求,具体来看,还会分成服务层、数据持久层等。

在这个例子中,Tomcat相对于Spring MVC就是高层模块,Spring MVC相对于我们的应用程序也算是高层模块。我们看到虽然Tomcat会调用Spring MVC,因为Tomcat要把Request交给Spring MVC处理,但是Tomcat并没有依赖Spring MVC,Tomcat的代码里不可能有任何一行关于Spring MVC的代码。

Tomcat和Spring MVC都依赖J2EE规范,Spring MVC实现了J2EE规范的HttpServlet抽象类,即DispatcherServlet,并配置在web.xml中。这样,Tomcat就可以调用DispatcherServlet处理用户发来的请求。

同样Spring MVC也不需要依赖我们写的Java代码,而是通过依赖Spring MVC的配置文件或者Annotation这样的抽象,来调用我们的Java代码。

所以,Tomcat或者Spring MVC都可以称作是框架,它们都遵循依赖倒转原则。

实际项目开发中,要做到依赖倒置的方法,一般就是抽象出相应的接口的方法,不依赖具体。面向接口编程。

更重要的是接口是高层需求的抽象,还是底层实现的抽象。这是依赖倒置的关键,面向接口本身并不能保证依赖倒置原则,否则和接口隔离原则没有区别。

SQL 引擎

Cloudera开发了Impala,这是一种运行在HDFS上的MPP架构的SQL引擎。和MapReduce启动Map和Reduce两种执行进程,将计算过程分成两个阶段进行计算不同,Impala在所有DataNode服务器上部署相同的Impalad进程,多个Impalad进程相互协作,共同完成SQL计算。在一些统计场景中,Impala可以做到毫秒级的计算速度

Spark出道以后,也迅速推出了自己的SQL引擎Shark,也就是后来的Spark SQL,将SQL语句解析成Spark的执行计划,在Spark上执行。由于Spark比MapReduce快很多,Spark SQL也相应比Hive快很多,并且随着Spark的普及,Spark SQL也逐渐被人们接受。后来Hive推出了Hive on Spark,将Hive的执行计划转换成Spark的计算模型,当然这是后话了。

此外,我们还希望在NoSQL的数据库上执行SQL,毕竟SQL发展了几十年,积累了庞大的用户群体,很多人习惯了用SQL解决问题。于是Saleforce推出了Phoenix,一个执行在HBase上的SQL引擎。

这些SQL引擎基本上都只支持类SQL语法,并不能像数据库那样支持标准SQL,特别是数据仓库领域几乎必然会用到嵌套查询SQL,也就是在where条件里面嵌套select子查询,但是几乎所有的大数据SQL引擎都不支持。

Beam

An advanced unified programming model

计算类型

在典型的大数据的业务场景下,数据业务最通用的做法是,采用批处理的技术处理历史全量数据,采用流式计算处理实时新增数据。而像Flink这样的计算引擎,可以同时支持流式计算和批处理计算。

批处理计算/大数据离线计算

像MapReduce、Spark这类计算框架处理的业务场景都被称作批处理计算,因为它们通常针对以“天”为单位产生的数据进行一次计算,然后得到需要的结果,这中间计算需要花费的时间大概是几十分钟甚至更长的时间。因为计算的数据是非在线得到的实时数据,而是历史数据,所以这类计算也被称为大数据离线计算

大数据流计算/大数据实时计算

而在大数据领域,还有另外一类应用场景,它们需要对实时产生的大量数据进行即时计算,比如对于遍布城市的监控摄像头进行人脸识别和嫌犯追踪。这类计算称为大数据流计算,相应地,有Storm、Flink、Spark Streaming等流计算框架来满足此类大数据应用的场景。 流式计算要处理的数据是实时在线产生的数据,所以这类计算也被称为大数据实时计算

应用场景

数据分析

主要使用Hive、Spark SQL等SQL引擎完成

数据挖掘与机器学习

有专门的机器学习框架TensorFlow、Mahout以及MLlib等,内置了主要的机器学习和数据挖掘算法。

大数据计算过程

1.将待处理的大规模数据存储在服务器集群的所有服务器上,主要使用HDFS分布式文件存储系统,将文件分成很多块(Block),以块为单位存储在集群的服务器上。

2.大数据引擎根据集群里不同服务器的计算能力,在每台服务器上启动若干分布式任务执行进程,这些进程会等待给它们分配执行任务。

3.使用大数据计算框架支持的编程模型进行编程,比如Hadoop的MapReduce编程模型,或者Spark的RDD编程模型。应用程序编写好以后,将其打包,MapReduce和Spark都是在JVM环境中运行,所以打包出来的是一个Java的JAR包。

4.用Hadoop或者Spark的启动命令执行这个应用程序的JAR包,首先执行引擎会解析程序要处理的数据输入路径,根据输入数据量的大小,将数据分成若干片(Split),每一个数据片都分配给一个任务执行进程去处理。

5.任务执行进程收到分配的任务后,检查自己是否有任务对应的程序包,如果没有就去下载程序包,下载以后通过反射的方式加载程序。走到这里,最重要的一步,也就是移动计算就完成了。

6.加载程序后,任务执行进程根据分配的数据片的文件地址和数据在文件内的偏移量读取数据,并把数据输入给应用程序相应的方法去执行,从而实现在分布式服务器集群中移动计算程序,对大规模数据进行并行处理的计算目标。

分布式架构的原则

尽量使用无状态的服务,不同服务实例之间不共享状态,也就是不持有数据

分布式架构的设计者在考虑架构的可扩展行(伸缩性)的时候设计出来的这样一个针对于服务的一个要求或者是标准(也就是原则)

主要目的是为了实现服务的低耦合高内聚的目标。一旦低耦合高内聚,服务就可以动态伸缩(放/换哪个机器上都可以运行)

大数据软件性能优化

在大数据使用、开发过程的性能优化一般可以从以下角度着手进行。

SQL语句优化

使用关系数据库的时候,SQL优化是数据库优化的重要手段,因为实现同样功能但是不同的SQL写法可能带来的性能差距是数量级的。我们知道在大数据分析时,由于数据量规模巨大,所以SQL语句写法引起的性能差距就更加巨大。典型的就是Hive的MapJoin语法,如果join的一张表比较小,比如只有几MB,那么就可以用MapJoin进行连接,Hive会将这张小表当作Cache数据全部加载到所有的Map任务中,在Map阶段完成join操作,无需shuffle。

数据倾斜处理

数据倾斜是指当两张表进行join的时候,其中一张表join的某个字段值对应的数据行数特别多,那么在shuffle的时候,这个字段值(Key)对应的所有记录都会被partition到同一个Reduce任务,导致这个任务长时间无法完成。

淘宝一个案例,把用户日志和用户表通过用户ID进行join,但是日志表有几亿条记录的用户ID是null,Hive把null当作一个字段值shuffle到同一个Reduce,结果这个Reduce跑了两天也没跑完,SQL当然也执行不完。像这种情况的数据倾斜,因为null字段没有意义,所以可以在where条件里加一个userID != null过滤掉就可以了。

MapReduce、Spark代码优化

了解MapReduce和Spark的工作原理,了解要处理的数据的特点,了解要计算的目标,设计合理的代码处理逻辑,使用良好的编程方法开发大数据应用,是大数据应用性能优化的重要手段,也大数据开发工程师的重要职责。

配置参数优化

根据公司数据特点,为部署的大数据产品以及运行的作业选择合适的配置参数,是公司大数据平台性能优化最主要的手段,也是大数据运维工程师的主要职责。比如Yarn的每个Container包含的CPU个数和内存数目、HDFS数据块的大小和复制数等,每个大数据产品都有很多配置参数,这些参数会对大数据运行时的性能产生重要影响。

大数据开源软件代码优化

修改直接修改Hadoop、Spark、Sqoop这些产品的代码进行性能优化的方法虽然比较激进,但是对于掌控自己公司的大数据平台来说,效果可能是最好的。

大数据基准测试的应用

大数据基准测试的主要用途是对各种大数据产品进行测试,检验大数据产品在不同硬件平台、不同数据量、不同计算任务下的性能表现

HiBench

大数据基准测试工具HiBench

HiBench内置了若干主要的大数据计算程序作为基准测试的负载(workload)。

此外还有十几种常用大数据计算程序,支持的大数据框架包括MapReduce、Spark、Storm等。

HiBench的价值不在于对各种大数据系统进行基准测试,而是学习大数据、验证自己大数据平台性能的工具。

使用

HiBench使用非常简单,只需要三步:

1.配置,配置要测试的数据量、大数据运行环境和路径信息等基本参数。

2.初始化数据,生成准备要计算的数据,比如要测试1TB数据的排序,那么就生成1TB数据。

3.执行测试,运行对应的大数据计算程序。

具体初始化和执行命令也非常简单,比如要生成数据,只需要运行bin目录下对应workload的prepare.sh就可以自动生成配置大小的数据。

bin/workloads/micro/terasort/prepare/prepare.sh

要执行大数据计算,运行run.sh就可以了。

bin/workloads/micro/terasort/hadoop/run.sh
bin/workloads/micro/terasort/spark/run.sh

前端埋点

前端埋点数据采集也是互联网应用大数据的重要来源之一,用户的某些前端行为并不会产生后端请求,比如用户在一个页面的停留时间、用户拖动页面的速度、用户选中一个复选框然后又取消了。这些信息对于大数据处理,对于分析用户行为,进行智能推荐都很有价值。但是这些数据必须通过前端埋点获得,所谓前端埋点,就是应用前端为了进行数据统计和分析而采集数据。

埋点的方式主要有手工埋点和自动化埋点。

手工埋点就是前端开发者手动编程将需要采集的前端数据发送到后端的数据采集系统。通常公司会开发一些前端数据上报的SDK,前端工程师在需要埋点的地方,调用SDK,按照接口规范传入相关参数,比如ID、名称、页面、控件等通用参数,还有业务逻辑数据等,SDK将这些数据通过HTTP的方式发送到后端服务器。

自动化埋点则是通过一个前端程序SDK,自动收集全部用户操作事件,然后全量上传到后端服器。自动化埋点有时候也被称作无埋点,意思是无需埋点,实际上是全埋点,即全部用户操作都埋点采集。自动化埋点的好处是开发工作量小,数据规范统一。缺点是采集的数据量大,很多数据采集来也不知道有什么用,白白浪费了计算资源,特别是对于流量敏感的移动端用户而言,因为自动化埋点采集上传花费了大量的流量,可能因此成为卸载应用的理由,这样就得不偿失了。在实践中,有时候只是针对部分用户做自动埋点,抽样一部分数据做统计分析。

介于手工埋点和自动化埋点之间的,还有一种方案是可视化埋点。通过可视化的方式配置哪些前端操作需要埋点,根据配置采集数据。可视化埋点实际上是可以人工干预的自动化埋点。

常见问题

网卡是整个系统的瓶颈

程序运行过程中网卡达到了最大I/O能力,整个系统经常在等待网卡的数据传输,请问,你有什么性能优化建议呢?

如果是网络问题,可以考虑batch要发送的网络包,打包一起发送。另一个能想到的就是compression.

确定问题细节原因,针对主要问题进行解决
1.如是网卡接入能力不够,则需要更换网卡或增加网卡
2.如是网卡--应用之间的io瓶颈,则需要考虑零拷贝减少copy释放性能,使用大页内存减少页表miss,使用专门核心做收包缓存到软队列等

采用netty这样的网络框架,因为netty的数据读写都是在bytebuf中进行的。而且我们可以自定义channelHandler在数据出站入站的时候编解码,压缩解压。

1.批量发送数据
2.压缩传输数据
3.增加带宽