昨夜西风凋碧树。独上高楼,望尽天涯路。
数据,已经渗透到当今每一个行业和业务职能领域,成为重要的生产因素。人们对于海量数据的挖掘和运用,预示着新一波生产率增长和消费者盈余浪潮的到来——麦肯锡
大数据(Big Data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。
大数据并不等同于海量数据,基本特征如下:
- Volume(数据体量大):存储量大、增量大
- Velocity(处理速度快):高速数据、高速处理
- Variety(数据类型多):来源多、类型多
- Value(价值密度低)
- Veracity(数据准确性)
当今,互联网、云计算、移动与物联网发展迅猛,移动设备、RFID、无线传感器每分每秒都在产生数据,数以亿计用户的互联网服务时时刻刻在产生巨量的交互。而传统方案集中式存储与计算,同时需要考虑设备性能、成本等问题,难以满足要求;因此架构基于大规模分布式计算(MPP)的 GFS/HDFS 分布式文件系统、各种 NoSQL分布式 等新方案应运而生。另外,在大数据处理上, Hadoop 对于大部分的企业来说,基于 Hadoop 已经能够满足绝大部分的数据需求,因此才会成为现在的主流选择。
Hadoop生态圈:由 Apache基金会 所开发的分布式系统基础框架,用于分布式大数据处理的开源框架,允许使用简单的编程模型在跨计算机集群的分布式环境中存储和处理大数据。
Hadoop生态圈:
Hadoop生态圈组件说明:
Hadoop典型应用架构:
HDFS(Hadoop Distributed File System,Hadoop分布式文件系统),是 Hadoop 项目的核心子项目,是分布式计算中数据存储管理的基础。支持海量数据的存储,成百上千的计算机组成存储集群,HDFS 可以运行在低成本的硬件之上,具有的高容错、高可靠性、高可扩展性、高吞吐率等特征,非常适合大规模数据集上的应用。
HDFS主要由主节点(NameNode)、辅助名称节点(Secondary NameNode)、数据节点(DataNode)组成。
NameNode的职责主要是:管理维护 HDFS(即管理DataNode上文件Block的均衡,维持副本数量);接收客户端的请求:上传、下载、创建目录等;维护 edits 与 fsimage 两个重要的文件。
其中:
edits 文件:记录操作日志,元数据的每一次变更操作都会被记录到edits中。
fsimage 文件:HDFS的元信息,NameNode节点的元数据运行在内存中,为防止宕机数据丢失,每隔一段时间会将元数据持久化到磁盘中。
Secondary NameNode主要职责是: 定期地创建命名空间的检查点(CheckPoint)操作——把edits中最新的状态信息合并到 fsimage 文件中,防止 edits 过大;也可以做冷备(即两个服务器,一个运行,一个不运行做备份),对一定范围内数据块做快照性备份。
DataNode的主要职责是:存储数据块;负责客户端对数据块的 io 请求;DataNode 定时和 NameNode 进行心跳通信,接受 NameNode 的指令。
YARN (Yet Another Resource Negotiator,另一种资源协调者),一种新的 Hadoop 资源管理器。它是一个通用资源管理系统,最初是为了改善MapReduce的实现,但也是一种资源调度框架,具有通用性,可为上层应用提供统一的资源管理和调度,可以支持其他的分布式计算模式(如Spark)。它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。
- ResourceManager(资源管理器):负责整个系统的资源分配和管理,是一个全局的资源管理器。它主要由两个组件构成:调度器和应用程序管理器。
- 调度器(Scheduler):根据资源情况为应用程序分配封装在 Container 中的资源。
- 应用程序管理器(Application Manager):负责管理整个系统中所有应用程序。
- NodeManager(节点管理器):每个节点上的资源和任务管理器。它会定时向 ResourceManager 汇报本节点上的资源使用情况和各个 Container 的运行状态;并接收并处理来自 ApplicationManager 的 Container 启动/停止等请求。
- Container(容器):YARN中的资源抽象,它封装了某个节点上的多维度资源。另外,YARN会为每个任务分配一个 Container 。
- ApplicationMaster (主应用):用户提交的每一个应用程序均包含一个 ApplicationMaster 。它是一个详细的框架库,它结合从 ResourceManager 获得的资源和 NodeManager 协同工作来运行和监控任务。主要功能包括:
- 与 ResourceManager 调度器协商以获取抽象资源(Container);
- 负责应用的监控,跟踪应用执行状态,重启失败任务等 ;
- 并且与 NodeManager 协同工作完成Task的执行和监控 。
YARN中应用(Application)运行机制(流程):
(1)Client 向 ResourceManager 提交 YARN Application ;
(2) ResourceManager 启动 Container ;
(3) 在 NodeManager 的协助下启动 Container,首次启动,Container 里面包含 Application Master ;
(4) Application Master 计算资源是否足够,如果够,则自己处理 ;如果不够,Application Master 向 ResourceManager 申请资源 ;
(6)Application Master 获取到资源后,开始启动 Container ;
(7)在NodeManager的协助下,启动 Container,Application 运行 。
YARN中任务进度监控:
(1)任务运行时,向自身的 ApplicationMaster 报告进度和状态 ;
(2)ApplicationMaster 形成一个作业的汇聚视图 ;
(3)客户端向 ApplicationMaster 获取最新状态 。
YARN调度器(Scheduler),负责给应用分配资源。但资源的有限,需要考虑采用资源利用率最高的策略。
YARN调度器:
FIFO Scheduler:最简单的调度器,所有用户提交应用到仅有一个的队列中按照先进先出的方式处理。可以针对这个队列设置ACL。没有应用优先级可以配置。
如下图:
Capacity Schedule:可以看作是FIFO Scheduler的多队列版本。每个队列可以限制资源使用量。但队列间的资源分配以使用量作排列依据,使得容量小的队列有竞争优势。
注:若不限制某队列最大容量,则运行过程中,它可以占用全部资源。
如下图:
Fair Scheduler:多队列,多用户共享资源。特有的客户端创建队列的特性,使得权限控制不太完美。根据队列设定的最小共享量或权重等参数,按比例共享资源。延迟调度机制跟Capacity Schedule的目的类似,但是实现方式稍有不同。
资源抢占特性,是指调度器能够依据公平资源共享算法,计算每个队列应得的资源,将超额资源的队列的部分容器释放掉的特性。
如下图:
衣带渐宽终不悔,为伊消得人憔悴。
MapReduce是一种简化并行计算的编程模型,用于进行大数据量的计算。
MapReduce采用“分而治之”的思想,把对大规模数据集的操作,分发给一个主节点管理下的各个子节点共同完成,然后整合各个子节点的中间结果,得到最终的计算结果。即“分散任务,汇总结果”。
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)“和"Reduce(归约)”,是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
创建文本文件friends.txt,内容为:
A:B,C,D,F,E,O
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
F:A,B,C,D,E,O,M
G:A,C,D,E,F
H:A,C,D,E,O
I:A,O
J:B,O
K:A,C,D
L:D,E,F
M:E,F,G
O:A,H,I,J,K
一、求互粉好友对 数据格式如下
人:关注列表
A:B,C,D,F,E,O
B:A,C,E,K
C:F,A,D,I
D:A,E,F,L
E:B,C,D,M,L
…
上述数据中A-B就是一对互粉好友对 最终结果:所有互粉对的集合 X-Y、Y-X
解决思路
map阶段:
1、列出所有的关注关系,value都为1。如 A:B,C,D => A-B 1,A-C 1,A-D 1。
2、始终把字母顺序小的排在前。如 D-A => A-D F-A => A-F。reduce阶段:
3、相同key的value总和大于1的说明两者为互粉。如 A-D的value总和为2,说明AD互粉。
map.py
#导入sys模块,与Python解释器进行交互
import sys
#sys.stdin 即Python的标准输入通道(通过键盘输入的字符)
for line in sys.stdin:
if line[0] != '':
#strip() ——该方法用于删除字符串头尾指定的字符(默认空格,删除空格符或者换行符);split()——该方法为指定分隔符对字符串进行切分(默认空格,空格切分)
Me = line.strip().split(':')[0]
frieds = line.strip().split(':')[1].split(',')
for i in Me:
for fan in frieds:
n = i + fan
m = sorted(n)
s = m[0] + '-' + m[1]
print(s,1)
#本地管道测试:
cat friends.txt | python map.py | head -n 10
reduce.py
import sys
compare = None
count = 0
for line in sys.stdin:
if line[0] != 0 :
s = line.strip().split()[0]
if compare == None:
compare = s
if compare != s:
print(compare,count)
compare = s
count = 0
count += 1
print(compare,count)
cat friends.txt | python map.py | sort -k 1 | python reduce.py | head -n 10
Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的 SQL 查询功能,可以将 SQL 语句转换为 MapReduce 任务来执行。学习成本低,可以通过类似 SQL 语句实现快速 MapReduce 统计,而不必开发专门的 MapReduce 应用程序。Hive 十分适合对数据仓库进行统计分析。
HiveQL 是一种 Hive 定义的类SQL语言,提供熟悉SQL的用户方便查询数据。Hive 支持的数据类型有基本数据类型、复杂数据类型与时间类型(不区分大小写)。
- 基本数据类型
Tinyint / Smallint / Int / Bigint :整数类型
Float / Double:浮点数类型
Boolean:布尔类型
String:字符串类型- 复杂数据类型
Array:数组类型,由一系列相同数据类型的元素组成
Map:集合类型,包含键值对,可以通过key来访问元素
Struct:结构类型,可以包含不同数据类型的元素。其元素可以通过”点语法”的方式来得到所需要的元素- 时间类型
Date:从Hive0.12.0开始支持
Timestamp:从Hive0.8.0开始支持
HiveQL与SQL语法类似,这里简单了解一下:
#创建TableName表,字段有学号、姓名与所在系
create table TableName(id int, name string, sno string) row format delimited fields terminated by ',';
#TableName表导入本地数据
load data local inpath '数据路径' into table TableName;
#查询
select * from TableName;
#条件查询
select * from TableName where id = 01 ;
#模糊查询
select * from TableName where id like '0%'; 查询id以 ‘0开头’ 的信息
#按所在系分组查询
select * from TableName group by sno;
#按id排序查询
select * from TableName order by id;
按照表数据的生命周期,可将表分为两类:内部表与外部表。
内部表(管理表),在概念上,与数据库中的表是类似的。Hive 可以控制该表的生命周期。默认情况下该表的数据都保存在这个目录下(/user/hive/warehouse)。 当删除表时,Hive也会删除该表中的数据(将表文件删除)。内部表不适合和其他工具共享数据。
#创表
create table TableName(id int, name string, sno string) row format delimited fields terminated by ',';
#导入数据
load data inpath '数据路径' into table TableName; 导入HDFS的数据
load data local inpath '数据路径' into table TableName; 导入本地Linux的数据
外部表,创建表时会用 external 修饰。Hive 不可以控制该表的生命周期。它与内部表在元数据的组织上是相同的,但实际数据的存储则有较大的差异。外部表只有一个过程,加载数据和创建表同时完成,并不会移动到数据仓库目录中,只是与外部数据建立一个链接。当删除外部表时,仅删除该链接。外部表的数据,可以同时作为多个外部表的数据源共享使用。
#创表
create external table TableName(id int, name string, sno string) row format delimited fields terminated by ',' location '存放目录';
分区表是将大表的数据分成称为分区的许多小的子集。在 Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中。
#根据id创建分区
create table TableName(id int, name string, sno string) partitioned by (id int) row format delimited fields terminated by ',';
#往分区表中插入数据,指明导入的数据的分区
load data inpath '数据路径' into table TableName partition(id=01);
...
#或者
load data inpath '数据路径' into table DataTable;
insert into table TableName partition(id=01) select id, name, sno from DataTable where id=01; 从DataTable导入数据
桶表是对数据进行哈希取值,然后放到不同文件中存储。即将数据集分解成更容易管理的若干部分。
#设置环境变量
set hive.enforce.bucketing = true;
#创建一个桶表,根据 id 进行分桶
create table TableName(id int, name string, sno string) clustered by (id int) into 3 buckets row format delimited fields terminated by ',';
#通过子查询插入数据
insert into TableName select * from DataTable;
视图是一种虚表,是一个逻辑概念,即数据库中只存放着视图的定义而不存放视图对应的数据,而这些数据仍存放在导出视图的基表中(视图建立在已有表的基础上, 视图赖以建立的表称为基表)。视图是只读的,可以跨越多张表,可以简化复杂的查询,但不能提高查询的效率。
Hive 最终都会转化为 MapReduce 的 job 来运行,Hive 调优实际上就是 MapReduce 的调优。有以下五个方面:
(1)解决数据倾斜问题,减少 job 数量
(2)设置合理的 Map 和 Reduce 个数
(3)对小文件进行合并
(4)优化时把握整体,单个 task 最优不如整体最优
(5)按照一定规则分区
Pig 是一个基于 Hadoop 的大规模数据分析平台,它提供的 SQL-LIKE 语言叫 Pig Latin,该语言的编译器会把 类SQL 的数据分析请求转换为一系列经过优化处理的 MapReduce 运算,适用于 Hadoop 平台来查询大型半结构化数据集(如日志文件)。Pig 为复杂的海量数据并行计算提供了一个简单的操作和编程接口。
Pig 赋予开发人员在大数据集领域更多的灵活性,并允许开发简洁的脚本用于转换数据流以便嵌入到较大的应用程序。而 Hive 更适合于数据仓库的任务,Hive 主要用于静态的结构以及需要经常分析的工作。
众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。