说明
讲师:首席架构师 李智慧
交互方式的趋势:根据大数据分析用户喜好什么,就推荐什么。比如字节跳动推荐新闻,视频;比如淘宝推荐商品给用户。
大数据概述
大数据技术发展史
2004年 三驾马车
今天我们常说的大数据技术,其实起源于 Google 在 2004 年前后发表的三篇论文,也就是我们经常听到的大数据 “三驾马车”,分别是分布式文件系统 GFS、大数据分布式计算框架 MapReduce 和 NoSQL 数据库系统 BigTable。
搜索引擎主要就做两件事情,一个是网页抓取,一个是索引构建和排序,而在这个过程中,有大量的数据需要存储和计算。这 “三驾马车” 其实就是用来解决这个问题的,也就是,一个文件系统、一个计算框架、一个数据库系统。
浏览下 Hadoop 的代码,这个纯用 Java 编写的软件其实并没有什么高深的技术难点,使用的也都是一些最基础的编程技术,也没有什么出奇之处,但是它却给社会带来巨大的影响,甚至带动一场深刻的科技革命,推动了人工只能的发展与进步。
Lucene 开源项目的创始人 Doug Cutting 当时正在开发开源搜索引擎 Nutch,阅读了 Google 的论文后,根据论文原理初步实现了类似 GFS 和 MapReduce 的功能。
2006 年 Hadoop
2006 年, Doug Cutting 将这些大数据相关的功能从 Nutch 中分离了出来,然后启动了一个独立的项目专门开发维护大数据技术,这就是后来赫赫有名的 Hadoop,主要包括 Hadoop 分布式文件系统 HDFS 和大数据计算引擎 MapReduce。
Hadoop 发布之后,Yahoo 首先用了起来。
大概有过了一年到了 2007年,百度和阿里巴巴也开始使用 Hadoop 进行大数据存储与计算。
2008 年,Hadoop 正式成为 Apache 的顶级项目,后来 Doug Cutting 本人也成为了 Apache 基金会的主席。自此,Hadoop 作为软件开发领域的一颗明星冉冉升起。
同年,专门运营 Hadoop 的商业公司 Cloudera 成立,Hadoop 得到进一步的商业支持。
2008年5月,Owen O’Malley在910个节点群集上运行了此代码,并在209秒(3.48分钟)内对100亿条记录(1 TB)进行了排序,从而赢得了年度通用(daytona) TB级的基准测试。
群集统计信息为:
- 910个节点
- 每个节点4个双核Xeons @ 2.0ghz
- 每个节点4个SATA磁盘
- 每个节点8G RAM
- 每个节点上有1个千兆以太网
- 每个机架40个节点
- 从每个机架到核心的8个千兆以太网上行链路
- 红帽企业Linux服务器版本5.1(内核2.6.18)
- Sun Java JDK 1.6.0_05-b13
https://hadoop.apache.org/docs/r2.4.1/api/org/apache/hadoop/examples/terasort/package-summary.html
Pig 到 Hive 2011年
这个时候,Yahoo 的一些人觉得用 MapReduce 进行大数据编程太麻烦了,于是便开发了 Pig。Pig 是一种脚本语言,使用类 SQL 的语法,开发者可以用 Pig 脚本描述要对大数据集上进行的操作,Pig 经过编译后会生成 MapReduce 程序,然后在 Hadoop 上运行。
编写 Pig 脚本虽然比直接 MapReduce 编程容易,但是依然需要学习新的脚本语法。于是 Facebook 又发布了 Hive。 Hive 支持使用 SQL 语法来进行大数据计算,比如说你可以写个 Select 语句进行数据查询,然后 Hive 会把 SQL 语句转化成 MapReduce 的计算机程序。这样,熟悉数据库的数据分析师和工程师便可以无门槛地使用大数据进行数据分析和处理了。
Hive 出现后极大程度降低了 Hadoop 的使用难度,迅速得到开发者和企业的追捧。据说,2011 年的时候,Facebook 大数据平台上运行的作业 90% 都来源于 Hive。
Hadoop周边产品,大数据生态
随后,众多 Hadoop 周边产品开始出现,大数据生态体系逐渐形成,其中包括:
- 专门将关系数据库中的数据导入导出到 Hadoop 平台的 Sqoop;
- 针对大规模日志进行分布式收集、聚合和传输的 Flume;
- MapReduce 工作流调度引擎 Oozie。
2012 年 Yarn 和 Spark
在 Hadoop 早期,MapReduce 既是一个执行引擎,又是一个资源调度框架,服务器集群的资源调度管理由 MapReduce 自己完成。但是这样不利于资源复用,也使得 MapReduce 非常臃肿。于是一个新项目启动了,将 MapReduce 执行引擎和资源调度分离开来,这就是 Yarn。2012年,Yarn 成为一个独立的项目开始运营,随后被各类大数据产品支持,成为大数据平台上最主流的资源调度系统。
同样是在 2012 年, UC 伯克利 AMP 实验室(Algorithms、Machine 和 People 的缩写)开发的 Spark 开始崭露头角。但是 AMP 实验室的马铁博士发现使用 MapReduce 进行机器学习计算的时候性能非常差,因为机器学习算法通常需要进行很多次的迭代计算,而 MapReduce 每执行一次 Map 和 Reduce 计算都需要重新启动一次作业,带来大量的无畏消耗。还有一点就是 MapReduce 主要使用磁盘作为存储介质,而 2012 年的时候,内存已经突破容量和成本限制,成为数据运行过程中主要的存储介质。Spark 一经推出,立即受到业界的追捧,并逐步替代 MapReduce 在企业应用中的地位。
大数据离线计算 与 大数据流计算(大数据实时计算)
一般说来,像 MapReduce、Spark 这类计算框架处理的业务场景都被称作批处理计算,因为它们通常针对以 “天” 为单位产生的数据进行一次计算,然后得到需要的结果,这中间计算需要花费的时间大概是几十分钟甚至更长的时间。因为计算的数据是非在线得到的实时数据,而是历史数据,所以这类计算也被称为大数据离线计算。
而在大数据领域,还有另一类应用场景,它们需要对实时产生的大量数据进行即时计算,比如对于遍布城市的监控摄像头进行人脸识别和嫌犯追踪。这类计算称为大数据流计算,相应地,有 Storm、Flink、Spark Streaming 等流计算框架来满足此类大数据应用场景。流式计算要处理的数据是实时在线产生的数据,所以这类计算也被称为大数据实时计算。
NoSQL 系统处理的主要也是大规模海量数据的存储与访问,所以也被归为大数据技术。NoSQL 曾经在 2011 年左右非常火爆,涌现出 HBase、Cassandra 等许多优秀的产品,其中 HBase 是从 Hadoop 中分离出来的、基于 HDFS 的 NoSQL 系统。
大数据引擎、数据挖掘与机器学习
上面这些基本上都可以归类为大数据引擎或者大数据框架。而大数据处理的主要应用场景包括数据分析、数据挖掘与机器学习。数据分析主要使用 Hive、Spark SQL 等 SQL 引擎完成;数据挖掘与机器学习则有专门的机器学习框架 TensorFlow、Mahout 以及 MLlib 等,内置了主要的机器学习和数据挖掘算法。
大数据应用发展史
大数据应用的搜索引擎时代
作为去全球最大的搜索引擎公司,Google 也是我们公认的大数据鼻祖,它存储着全世界几乎所有可访问的网页,数目可能超过万亿规模,全部存储起来大约需要万块磁盘。为了将这些文件存储起来,Google 开发了 GFS (Google 文件系统),将数千台服务器上的数万块磁盘统一管理起来,然后当作一个文件系统,统一存储所有这些网页文件。
Google 得到这些网页文件是要构建搜索引擎,需要对所有文件中的单词进行词频统计,然后根据 PageRank 算法计算网页排名。这中间,Google 需要对这数万块磁盘上的文件进行计算处理,也正是基于这些需求,Google 又开发了 MapReduce 大数据计算框架。
大数据应用的数据仓库时代
曾经人们在进行数据分析与统计时,仅仅局限于数据库,在数据库的计算环境中对数据库中的数据表进行统计分析。并且受数据量和计算能力的限制,只能对最重要的数据进行统计和分析。这里所谓最重要的数据,通常指的都是给老板看的数据和财务相关的数据。
而 Hive 可以在 Hadoop 上进行 SQL 操作,实现数据统计与分析。也就是说,可以用更低廉的价格获得比以往多得多的数据存储与计算能力。可以把运行日志、应用采集数据、数据库数据放到一起进行计算分析,获得以前无法得到的数据结果,企业的数据仓库也随之呈指数级膨胀。
不仅是老板,公司中每个普通员工比如产品经理、运营人员、工程师,只要有数据访问权限,都可以提出分析需求,从大数据仓库中获得自己想要了解的数据分析结果。
大数据应用的数据挖掘时代
很早以前商家就通过数据发现,买尿不湿的人通常也会买啤酒,于是精明的商家就把这两样商品放在一起,以促进销售。除了商品和商品有关系,还可以利用人和人之间的关系推荐商品。如果两个人购买的商品有很多都是类似甚至相同的,不管这两个人天南海北相隔多远,他们一定有某种关系,比如可能有差不多的教育背景、经济收入、兴趣爱好。根据这种关系,可以进行关联推荐,让他们看到自己感兴趣的商品。
大数据还可以将每个人身上的不同特征挖掘出来,打上各种各样的标签:90后、生活在一线城市、月收入 1~2 万、宅… 这些标签组成了用户画像,并且只要这样的标签足够多,就可以完整描绘出一个人。除了商品销售,数据挖掘还可以用于人际关系挖掘。
大数据应用的机器学习时代
人们很早就发现,数据中蕴藏着规律,这个规律是所有数据都遵循的,过去发生的事情遵循这个规律,将来要发生的事情也遵循这个规律。一旦找到了这个规律,对于正在发生的事情,就可以按照这个规律进行预测。
在过去,受数据采集、存储、计算能力的限制,只能通过抽样的方式获取小部分数据,无法得到完整的、全局的、细节的规律。而现在有了大数据,可以把全部的历史数据都收集起来,统计其规律,进而预测正在发生的事情。
这就是机器学习。
大数据应用领域
医学影像智能识别
图像识别是机器学习获得的重大突破之一,使用大量的图片数据进行深度机器学习训练,机器可以识别出特定的图像元素,比如猫或者人脸,当然也可以识别出病理特征。
比如 X 光片里的异常病灶位置,是可以通过机器学习智能识别出来的。甚至可以说医学影像智能识别在某些方面已经比一般医生拥有更高的读图和识别能力。
病历大数据智能诊疗
病历,特别是专家写的病历,本身就是一笔巨大的知识财富,利用大数据技术将这些知识进行处理、分析、统计、挖掘,可以构成一个病历知识库,可以分享给更多人,即构成一个只能辅助诊疗系统。
AI 外语老师
得益于语音识别和语音合成技术的成熟(语音识别与合成技术同样是利用大数据技术进行机器学习与训练),一些在线教育网站尝试用人工只能外语老师进行外语教学。这里面的原理其实并不复杂,聊天机器人技术已经普遍应用,只要将学习的知识点设计进聊天的过程中,就可以实现一个简单的 AI 外语老师了。
智能解题
比较简单的只能解题系统其实是利用搜索引擎技术,在收集大量的试题以及答案的基础上,进行试题匹配,将匹配成功的答案返回。这个过程看起来就像智能做题一样,表明看给个题目就能解出答案,而实际上只是找出答案。
进阶一点的智能解题系统,通过图像识别与自然语言处理(这两项技术依然使用大数据技术实现),进行相似性匹配。更改试题的部分数字、文字表述,但是不影响实质性解答思路,依然可以解答。
高阶的智能解题系统,利用神经网络机器学习技术,将试题的自然语言描述转化成形式语言,然后分析知识点和解题策略,进行自动推导,从而完成实质性的解题。
舆情监控与分析
编写数据爬虫,实时爬取各个社交新媒体上的各种用户内容和媒体信息,然后通过自然语言处理,就可以进行情感分析、热点事件追踪等。舆情实时监控可以用于商业领域,引导智能广告投放;可用于金融领域,辅助执行自动化股票、期权、数字货币交易;可用于社会管理,及时发现可能引发社会问题的舆论倾向。
在美国总统大选期间,候选人就曾雇佣大数据公司利用社交媒体的数据进行分析,发现选票可能摇摆的地区,有针对性前去进行竞选演讲。并利用大数据分析选民关注的话题,包装自己的竞选主张。Facebook 也因为授权大数据公司滥用自己用户的数据而遭到调查和谴责,市值蒸发了数百亿美元。
大数据风控
在金融借贷中,如何识别出高风险用户,要求其提供更多抵押、支付更高利息、调整更低的额度,甚至拒绝贷款,从而降低金融机构的风险。事实上,金融行业已经沉淀了大量的历史数据,利用这些数据进行计算,可以得到用户特征和风险指数的曲线(即风控模型)。当新用户申请贷款的时候,将该用户特征带入曲线进行计算,就可以得到该用户的风险指数,进而自动给出该用户的贷款策略。
新零售
亚马逊 Go 无人店使用大量的摄像头,实时捕捉用户行为,判断用户是取出还是放回商品、取了何种商品等。这实际上是大数据流计算与机器学习的结合,最终实现的购物效果是,无需排队买单,进去就拿东西,拿好了就走。
无人驾驶
无人驾驶就是在人的驾驶过程中实时采集车辆周边数据和驾驶控制信息,然后通过机器学习,获得周边信息与驾驶方式的对应关系(自动驾驶模型)。然后将这个模型应用到无人驾驶汽车上,传感器获得车辆周边数据后,就可以通过自动驾驶模型计算出车辆控制信息(转向、刹车等)。计算自动驾驶模型需要大量的数据,所以我们看到,这些无人驾驶创业公司都在不断攀比自己的训练数据有几十万公里、几百万公里,因为训练数据的量意味着模型的完善程度。
Hadoop Distributed File System - HDFS
常用 RAID 技术(Redundant Array of Independent Drives or Redundant Array of Inexpensive Disks)
HDFS 系统架构
数据存储细节
HDFS 设计目标
- HDFS 以流式数据访问模式存储超大文件,运行于商用硬件集群上。
- 超大文件
- 流式数据访问:一次写入多次读取。
- 商用硬件。
HDFS 为了做到可靠性(Reliability)创建了多份数据库(Data Blocks)的复制(Replicas),并将它们放置在服务器集群的计算节点中(Compute Nodes),MapReduce就可以在它们所在的节点上处理这些数据了。
不适合 HDFS 的场景
- 低延迟的数据访问
- 大量小文件:超过 NameNode 的处理能力
- 多用户随机写入修改文件
节点设计目标
假设:节点失效是常态。
理想:
- 任何一个节点失效,不影响 HDFS 服务。
- HDFS 可以自动完成副本的复制。
文件
文件切分成块(默认大小 64M),以块为单位,每个块有多个副本存储在不同的机器上,副本数可在文件生成时指定(默认 3)。
NameNode 是主节点,存储文件的元数据如文件名,文件目录结构,文件属性(生成时间,副本数,文件权限),以及每个文件的块列表以及块所在的 DataNode 等等。
DataNode 在本地文件系统存储文件块数据,以及块数据的校验和。可以创建、删除、移动或者重命名文件,当文件创建、写入和关闭之后不能修改文件内容。
HDFS 分而治之(Divide and Conquer)
MapReduce 分而治之(Divide and Conquer)
NameNode
NameNode 是一个中心服务器,负责管理文件系统的名字空间(NameSpace)以及客户端对文件的访问。
文件操作,NameNode 负责文件元数据的操作,DataNode 负责处理文件内容的读写请求,跟文件内容相关的数据流不经过NameNode,只会询问它跟哪个 DataNode 联系,否则 NameNode 会成为系统的瓶颈。
副本存放在那些 DataNode 上由 NameNode 来控制,根据全局情况做出块放置决定,读取文件时 NameNode 尽量让用户先读取最近的副本,降低带宽消耗和读取迟延。
NameNode 全权管理数据库的复制,它周期性地从集群中的每个 DataNode 接收心跳信号和块状态报告(BlockReport)。接收到心跳信号意味着该 DataNode 节点工作正常。块状态报告包含了一个该 DataNode 上所有数据库的列表。
DataNode
一个数据块在 DataNode 以文件存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
DataNode 启动后向 NameNode 注册,通过后,周期性(1 小时)地向 NameNode 上报所有块信息。
心跳是每 3 秒一次,心跳返回结果带有 NameNode 给该 DataNode 的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个 DataNode 的心跳,则认为该节点不可用。
集群运行中可以安全加入和退出一些机器。
HDFS 关键运行机制 - 高可用
- 一个名字节点NameNode和多个数据节点DataNode
- 数据复制(冗余机制):存放的位置(机架感知策略)
- 故障检测
- 数据节点:心跳包(检测是否宕机)、块报告(安全模式下检测)、数据完整性检测(检验和比较)
- 名字节点NameNode(日志文件,镜像文件)
- 空间回收机制
HDFS 如何写文件?-- 架构图一
HDFS 如何写文件?-- 架构图二
写一个数据块 DataNode
- 使用 HDFS 提供的客户端开发库 Client,向远程的 NameNode 发起 RPC 请求;
- NameNode 会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录,否则会让客户端抛出异常;
- 当客户端开始写入文件的时候,开发库会将文件切分成多个 packets,并在内部以数据队列 “Data Queue” 的形式管理这些 packats,并想 NameNode 申请新的 blocks,获取用来存储 replicas 的合适的 DataNodes 列表,列表的大小根据在 NameNode 中对 replication 的设置而定。
- 开始以 Pipeline(管道)的形式将 packet 写入所有的 replicas 中。开发库把 packet 以流的方式写入第一个 DataNode,该DataNode 把该 packet 存储之后,再将其传递给再次 pipeline 中的下一个 DataNode,知道最后一个 DataNode,这种写数据的方式呈流水线的形式。
- 最后一个 DataNode 成功存储之后会返回一个 ack packet,在 pipeline 里传递至客户端,在客户端的开发库中维护者 “ack queue”,成功收到 DataNode 返回的 ack packet 后会从 “ack queue” 移除响应的 packet。
- 如果传输过程中,有某个 DataNode 出现了故障,那么当前 pipeline 会被关闭,出现故障的 DataNode 会从当前的 pipeline 中移除,剩余的 block 会继续剩下的 DataNode 中继续以 pipeline 的形式传输,同时 NameNode 会分配一个新的 DataNode, 保持 replicas 设定的数量。
HDFS 如何读文件?
- 使用 HDFS 提供的客户端开发库 Client,向远程的 NameNode 发起 RPC 请求;
- NameNode 会视情况返回文件的部分或者全部 block 列表,对于每个 block,NameNode 都会返回有改 block 拷贝的 DataNode 地址;
- 客户端开发库 Client 会选取离客户端最接近的 DataNode 来读取 block;如果客户端本身就是 DataNode, 那么将从本地直接获取数据。
- 读取完当前 block 数据后,关闭与当前的 DataNode 连接,并为读取下一个 block 寻找最佳的 DataNode;
- 当读完列表的 block 后,且文件读取还没有结束,客户端开发库会继续想 DataNode 获取下一批的 block 列表。
- 读取完一个 block 都会进行 checksum 验证,如果读取 DataNode 时出现错误,客户端会通知 NameNode,然后再从下一个拥有该 block 拷贝的 DataNode 继续读。
DataNode节点失效是常态
- DataNode 中的磁盘挂了怎么办?
- DataNode 所在机器挂了怎么办?
- NameNode 挂了怎么办?
- Client 挂了怎么办?
DataNode 的磁盘挂了怎么办?
- DataNode 正常服务
- 坏掉的磁盘上的数据尽快通知 NameNode
DataNode 所在机器挂了怎么办?
问:NameNode 怎么知道 DataNode 挂掉了?
答:DataNode 每 3 秒钟向 NameNode 发送心跳,如果 10 分钟 DataNode 没有向 NameNode 发送心跳,则 NameNode 认为该 DataNode 已经 dead,NameNode 将取出该 DataNode 上对应的 block,对其进行复制。
NameNode 挂了怎么办?
持久化元数据
- 操作日志(edit log)
☞ 记录文件创建,删除,修改文件属性等操作。 - Fsimage
☞ 包含完整的命名空间
☞ File -> Block 的映射关系
☞ 文件的属性 (ACL,quota,修改时间等)
Client 挂了怎么办?
问: Client 所在机器挂了有什么影响?
答: 一致性问题。
HDFS 一致性模型
- 文件创建以后,不保证在 NameNode 立即可见,即使文件刷新并存储,文件长度依然可能为 0;
- 当写入数据超过一个块后,新的 reader 可以看见第一个块,reader 不能看见当前正在写入的块;
- HDFS 提供
sync()
方法强制缓存与数据节点同步,sync()
调用成功后,当前写入数据对所有 reader 可见且一致; - 调用
sync()
会导致额外的开销。
HDFS 副本摆放策略
压缩
目的:
- 减少存储所需的磁盘空间;
- 加速数据再网络和磁盘上的传输。
SequenceFile
数据块 block
- 默认 64 M,通常设置为 128M;
- 可以在
hdfs-site.xml
中设置。
<property>
<name>dfs.block.size</name>
<value>18831411592</value>
</property>
NameNode 参数,在 hdfs-site.xml
中设置。 dfs.name.dir
<property>
<name>dfs.name.dir</name>
<value>/data0/name,/nfs/name</value>
<description>saving file location</description>
</property>
NameNode 参数,在 hdfs-site.xml
中设置。dfs.replication
<property>
<name>dfs.replication</name>
<value>3</value>
<description>copy number</description>
</property>
DataNode 参数,在 hdfs-site.xml
中设置。dfs.data.dir
<property>
<name>dfs.name.dir</name>
<value>/data0/hdfs,/data1/hdfs</value>
<description>saving data location</description>
</property>
Hadoop 文件系统
文件系统抽象 (org.apache.hadoop
)
fs.FileSystem
fs.LocalFileSystem
hdfs.DistributedFileSystem
hdfs.HftpFileSystem
hdfs.HsftpFileSystem
fs.HarFileSystem
Java 接口
通过 FileSystem API 读取数据
- Path 对象:
hdfs://localhost:9000/user/john.t.txt
- 获取 FileSystem 实例
public static FileSystem get(Configuration conf) throws IOException
public static FileSystem get(URI uri, Configuration conf) throws IOException
- 获取文件输入流
public FSDataInputStream open(Path p) throws IOException
public abstract FSDataInputStream open(Path p, int bufferSize) throws IOException