第1部分 选择题html
1.1 Hadoop选择题java
1.1.1 Hdfsnode
1. 下面哪一个程序负责 HDFS 数据存储?mysql
a)NameNode linux
b)Jobtracker ios
c)Datanode c++
d)secondaryNameNode web
e)tasktracker面试
2. HDfS 中的 block 默认保存几份?正则表达式
a)3份
b)2份
c)1份
d)不肯定
3. 下列哪一个程序一般与NameNode 在一个节点启动?
a)SecondaryNameNode
b)DataNode
c)TaskTracker
d)Jobtracker
注:haoop1.X
分析:
hadoop 的集群是基于 master/slave 模式,namenode 和 jobtracker 属于 master,datanode 和 tasktracker属于 slave,master 只有一个,而 slave 有多个。SecondaryNameNode 内存需求和 NameNode 在一个数量级上,因此一般 secondary NameNode(运行在单独的物理机器上)和 NameNode 运行在不一样的机器上。
JobTracker 和 TaskTracker
JobTracker 对应于 NameNode
TaskTracker 对应于 DataNode
DataNode 和 NameNode 是针对数据存放来而言的
JobTracker 和 TaskTracker 是对于 MapReduce 执行而言的
mapreduce 中几个主要概念,mapreduce 总体上能够分为这么几条执行线索:
jobclient,JobTracker 与 TaskTracker。
一、JobClient 会在用户端经过 JobClient 类将应用已经配置参数打包成 jar 文件存储到 hdfs,并把路径提交到 Jobtracker,而后由 JobTracker 建立每个 Task(即 MapTask 和 ReduceTask)并将它们分发到各个 TaskTracker 服务中去执行
二、JobTracker 是一个 master 服务,软件启动以后 JobTracker 接收 Job,负责调度 Job 的每个子任务 task运行于 TaskTracker 上,并监控它们,若是发现有失败的 task 就从新运行它。通常状况应该把 JobTracker 部署在单独的机器上。
三、TaskTracker 是运行在多个节点上的 slaver 服务。TaskTracker 主动与 JobTracker 通讯,接收做业,并负责直接执行每个任务。TaskTracker 都须要运行在 HDFS 的 DataNode 上
4. HDFS 默认 Block Size
a)32MB
b)64MB
c)128MB
注:旧版本是64MB
5. Client 端上传文件的时候下列哪项正确
a)数据通过 NameNode 传递给 DataNode
b)Client 端将文件切分为 Block,依次上传
c)Client 只上传数据到一台 DataNode,而后由 NameNode 负责 Block 复制工做
分析:
Client 向 NameNode 发起文件写入的请求。
NameNode 根据文件大小和文件块配置状况,返回给 Client 它所管理部分 DataNode 的信息。
Client 将文件划分为多个 Block,根据 DataNode 的地址信息,按顺序写入到每个 DataNode 块中。
6. 下面与 HDFS 相似的框架是?C
A NTFS
B FAT32
C GFS
D EXT3
7. 的
8. 的
1.1.2 集群管理
1. 下列哪项一般是集群的最主要瓶颈
a)CPU
b)网络
c)磁盘 IO
d)内存
解析:
因为大数据面临海量数据,读写数据都须要 io,而后还要冗余数据,hadoop 通常备 3 份数据,因此 IO就会打折扣。
2. 关于SecondaryNameNode 哪项是正确的?
a)它是 NameNode 的热备
b)它对内存没有要求
c)它的目的是帮助 NameNode 合并编辑日志,减小 NameNode 启动时间
d)SecondaryNameNode 应与 NameNode 部署到一个节点
3. 下列哪项能够做为集群的管理?
a)Puppet b)Pdsh c)ClouderaManager d)Zookeeper
分析:
A:puppetpuppet 是一种 Linux、Unix、windows 平台的集中配置管理系统
B:pdsh 能够实如今在多台机器上执行相同的命令
详细参考:集群管理小工具介绍-pdsh
C:能够参考 Cloudera Manager 四大功能【翻译】
首先这里给管理下一个定义:部署、配置、调试、监控,属于管理
4. 配置机架感知的下面哪项正确
a)若是一个机架出问题,不会影响数据读写
b)写入数据的时候会写到不一样机架的 DataNode 中
c)MapReduce 会根据机架获取离本身比较近的网络数据
5. 下列哪一个是 Hadoop 运行的模式
a)单机版 b)伪分布式 c)分布式
6. Cloudera 提供哪几种安装 CDH 的方法
a)Cloudera manager b)Tarball c)Yum d)Rpm
7. 的
8. D d
9. 的
10. 的
1.2 Hbase选择题
1.2.1 Hbase基础
1. HBase 来源于哪篇博文? C
A TheGoogle File System
BMapReduce
CBigTable
D Chubby
2. 下面对 HBase 的描述哪些是正确的? B、C、D
A 不是开源的
B 是面向列的
C 是分布式的
D 是一种 NoSQL 数据库
3. HBase 依靠()存储底层数据 A
A HDFS
B Hadoop
C Memory
DMapReduce
4. HBase 依赖()提供消息通讯机制 A
AZookeeper
B Chubby
C RPC
D Socket
5. HBase 依赖()提供强大的计算能力 D
AZookeeper
B Chubby
C RPC
DMapReduce
6. MapReduce 与 HBase 的关系,哪些描述是正确的? B、C
A 二者不可或缺,MapReduce 是 HBase 能够正常运行的保证
B 二者不是强关联关系,没有 MapReduce,HBase 能够正常运行
CMapReduce 能够直接访问 HBase
D 它们之间没有任何关系
7. 下面哪些选项正确描述了HBase 的特性? A、B、C、D
A 高可靠性
B 高性能
C 面向列
D 可伸缩
8. 下面哪些概念是 HBase 框架中使用的?A、C
A HDFS
B GridFS
CZookeeper
D EXT3
9. D
1.2.2 Hbase核心
1. LSM 含义是?A
A 日志结构合并树
B 二叉树
C 平衡二叉树
D 长平衡二叉树
2. 下面对 LSM 结构描述正确的是? A、C
A 顺序存储
B 直接写硬盘
C 须要将数据 Flush 到磁盘
D 是一种搜索平衡树
3. LSM 更能保证哪一种操做的性能?B
A 读
B 写
C 随机读
D 合并
4. LSM 的读操做和写操做是独立的?A
A 是。
B 否。
C LSM 并不区分读和写
D LSM 中读写是同一种操做
5. LSM 结构的数据首先存储在()。 B
A 硬盘上
B 内存中
C 磁盘阵列中
D 闪存中
6. HFile 数据格式中的 Data 字段用于()。A
A 存储实际的 KeyValue 数据
B 存储数据的起点
C 指定字段的长度
D 存储数据块的起点
7. HFile 数据格式中的 MetaIndex 字段用于()。D
A Meta 块的长度
B Meta 块的结束点
C Meta 块数据内容
D Meta 块的起始点
8. HFile 数据格式中的 Magic 字段用于()。A
A 存储随机数,防止数据损坏
B 存储数据的起点
C 存储数据块的起点
D 指定字段的长度
9. HFile 数据格式中的 KeyValue 数据格式,下列选项描述正确的是()。A、D
A 是 byte[]数组
B 没有固定的结构
C 数据的大小是定长的
D 有固定的结构
10. HFile 数据格式中的 KeyValue 数据格式中 Value 部分是()。C
A 拥有复杂结构的字符串
B 字符串
C 二进制数据
D 压缩数据
11. D
1.2.3 HBase 高级应用介绍
1. HBase 中的批量加载底层使用()实现。A
AMapReduce
B Hive
CCoprocessor
D BloomFilter
2. HBase 性能优化包含下面的哪些选项?A、B、C、D
A 读优化
B 写优化
C 配置优化
D JVM 优化
3. Rowkey 设计的原则,下列哪些选项的描述是正确的?A、B、C
A 尽可能保证越短越好
B 能够使用汉字
C 能够使用字符串
D 自己是无序的
4. HBase 构建二级索引的实现方式有哪些? A、B
AMapReduce
BCoprocessor
C BloomFilter
D Filter
5. 关于 HBase 二级索引的描述,哪些是正确的?A、B
A 核心是倒排表
B 二级索引概念是对应 Rowkey 这个“一级”索引
C 二级索引使用平衡二叉树
D 二级索引使用 LSM 结构
6. 下列关于 Bloom Filter 的描述正确的是?A、C
A 是一个很长的二进制向量和一系列随机映射函数
B 没有误算率
C 有必定的误算率
D 能够在 Bloom Filter 中删除元素
7. D
1.2.4 HBase 安装、部署、启动
1. HBase 官方版本能够安装在什么操做系统上?A、B、C
A CentOS
B Ubuntu
C RedHat
D Windows
2. HBase 虚拟分布式模式须要()个节点?A
A 1
B 2
C 3
D 最少 3 个
3. HBase 分布式模式最好须要()个节点?C
A 1
B 2
C 3
D 最少
4. 下列哪些选项是安装 HBase 前所必须安装的?A、B
A 操做系统
B JDK
C ShellScript
D JavaCode
5. 解压.tar.gz 结尾的 HBase 压缩包使用的 Linux 命令是?A
A tar-zxvf
B tar -zx
C tar -s
D tar -nf
6. D
7. D
1.3 Zookeeper选择题
1.3.1 Zookeeper基础
1. 下面与 Zookeeper 相似的框架是?D
AProtobuf
B Java
C Kafka
D Chubby
2. 的
3. D
4. D
5. D
6. D
7. D
8. D
9. d
第2部分 判断题
第2部分
2.1 Hadoop判断题
2.1.1 集群管理
1. Ganglia 不只能够进行监控,也能够进行告警。(正确)
解析:
ganglia 做为一款最经常使用的 Linux 环境中的监控软件,它擅长的的是从节点中按照用户的需求以较低的代价
采集数据。可是 ganglia 在预警以及发生事件后通知用户上并不擅长。最新的 ganglia 已经有了部分这方面
的功能。可是更擅长作警告的还有 Nagios。Nagios,就是一款精于预警、通知的软件。经过将 Ganglia 和
Nagios 组合起来,把 Ganglia 采集的数据做为 Nagios 的数据源,而后利用 Nagios 来发送预警通知,能够
完美的实现一整套监控管理的系统。
2. Nagios 不能够监控 Hadoop 集群,由于它不提供 Hadoop支持。(错误 )
分析:
Nagios 是集群监控工具,并且是云计算三大利器之一
3. 若是 NameNode 意外终止,SecondaryNameNode 会接替它使集群继续工做。(错误 )
分析:
SecondaryNameNode 是帮助恢复,而不是替代
4. Cloudera CDH 是须要付费使用的。(错误)
分析:
第一套付费产品是 Cloudera Enterpris,Cloudera Enterprise 在美国加州举行的 Hadoop 大会 (HadoopSummit) 上公开,以若干私有管理、监控、运做工具增强 Hadoop 的功能。收费采起合约订购方式,价格随用的 Hadoop 叢集大小变更。
5. NameNode 负责管理 metadata,client 端每次读写请求,它都会从磁盘中读取或则会写入 metadata信息并反馈 client 端。(错误)
分析:
NameNode 不须要从磁盘读取 metadata,全部数据都在内存中,硬盘上的只是序列化的结果,只有每次namenode 启动的时候才会读取。
1)文件写入
Client 向 NameNode 发起文件写入的请求。
NameNode 根据文件大小和文件块配置状况,返回给 Client 它所管理部分 DataNode 的信息。
Client 将文件划分为多个 Block,根据 DataNode 的地址信息,按顺序写入到每个 DataNode 块中。
2)文件读取
Client 向 NameNode 发起文件读取的请求。
NameNode 返回文件存储的 DataNode 的信息。
Client 读取文件信息。
6. NameNode 本地磁盘保存了 Block 的位置信息。( 我的认为正确,欢迎提出其它意见)
分析:
DataNode 是文件存储的基本单元,它将 Block 存储在本地文件系统中,保存了 Block 的 Meta-data,同时周期性地将全部存在的 Block 信息发送给 NameNode。
7. DataNode 经过长链接与 NameNode 保持通讯。错误
分析:
经过心跳机制。
(1).长链接
Client 方与 Server 方先创建通信链接,链接创建后不断开,而后再进行报文发送和接收。这种方式下因为通信链接一直存在,此种方式经常使用于点对点通信。
(2).短链接
Client 方与 Server 每进行一次报文收发交易时才进行通信链接,交易完毕后当即断开链接。此种方式经常使用于一点对多点通信,好比多个 Client 链接一个 Server.
8. Hadoop 自身具备严格的权限管理和安全措施保障集群正常运行。(错误)
9. Slave 节点要存储数据,因此它的磁盘越大越好。(错误)
分析:
一旦 Slave 节点宕机,数据恢复是一个难题
10. hadoop dfsadmin –report 命令用于检测 HDFS 损坏块。(错误)
分析:
hadoop dfsadmin -report
用这个命令能够快速定位出哪些节点 down 掉了,HDFS 的容量以及使用了多少,以及每一个节点的硬盘使用状况。
固然 NameNode 有个 http 页面也能够查询,可是这个命令的输出更适合咱们的脚本监控 dfs 的使用情况
11. Hadoop 默认调度器策略为 FIFO(正确 )
12. 集群内每一个节点都应该配 RAID,这样避免单磁盘损坏,影响整个节点运行。(错误)
分析:
首先明白什么是 RAID:磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具备冗余能力的阵列”之意。
这句话错误的地方在于太绝对,具体状况具体分析。题目不是重点,知识才是最重要的。
由于 hadoop 自己就具备冗余能力,因此若是不是很严格不须要都配备 RAID。
13. Hadoop 环境变量中的 HADOOP_HEAPSIZE 用于设置全部 Hadoop 守护线程的内存。它默认是 200 GB。( 错误)
分析:
hadoop 为各个守护进程(namenode,secondarynamenode,jobtracker,datanode,tasktracker)统一分配的内存在 hadoop-env.sh 中设置,参数为 HADOOP_HEAPSIZE,默认为 1000M。
14. DataNode 首次加入 cluster 的时候,若是 log 中报告不兼容文件版本,那须要 NameNode执行―Hadoopnamenode -format‖操做格式化磁盘。(错误 )
分析:
这个报错是说明 DataNode 所装的 Hadoop 版本和其它节点不一致,应该检查 DataNode 的 Hadoop 版本
15. D
16. D
17. 的
18. D
19. 的
20. D的
21. D的
22. D
23. d
2.1.2 Hdfs
1. Block Size 是不能够修改的。(错误)
解析:
Hadoop 的基础配置文件是 hadoop-default.xml,默认创建一个 Job 的时候会创建 Job 的 Config,Config
首先读入hadoop-default.xml的配置,而后再读入hadoop-site.xml的配置(这个文件初始的时候配置为空),
hadoop-site.xml 中主要配置须要覆盖的 hadoop-default.xml 的系统级配置。具体配置能够参考下:
<property>
<name>dfs.block.size</name>//block 的大小,单位字节,后面会提到用处,必须是 512 的倍数,因
为采用 crc 做文件完整性校验,默认配置 512 是 checksum 的最小单元。
<value>5120000</value>
<description>The default block size for new files.</description>
</property>
2. Hadoop 支持数据的随机读写。(错)
分析:
lucene 是支持随机读写的,而 hdfs 只支持随机读。可是 HBase 能够来补救。
HBase 提供随机读写,来解决 Hadoop 不能处理的问题。HBase 自底层设计开始即聚焦于各类可伸缩性问题:表能够很―高‖,有数十亿个数据行;也能够很―宽‖,有数百万个列;水平分区并在上千个普通商用机节点上自动复制。表的模式是物理存储的直接反映,使系统有可能提升高效的数据结构的序列化、存储和检索。
3. 由于 HDFS 有多个副本,因此 NameNode 是不存在单点问题的。(错误 )
分析:
副本针对DataName而讲的
4. 的
5. 的
6. 的
2.1.3 MapReduce
1. Hadoop 是 Java 开发的,因此 MapReduce 只支持 Java 语言编写。(错误 )
分析:
支持c++等语言,须要经过接口。
2. 每一个 map 槽就是一个线程。(错误)
分析:
一个task对应一个线程
分析:首先咱们知道什么是 map 槽,map 槽->map slot,map slot 只是一个逻辑值 ( org.apache.hadoop.mapred.TaskTracker.TaskLauncher.numFreeSlots ),而不是对应着一个线程或者进程
3. Mapreduce 的 input split 就是一个 block。(错误)
分析:
应该是一个block数组
一、运行mapred程序;
二、本次运行将生成一个Job,因而JobClient向JobTracker申请一个JobID以标识这个Job;
三、JobClient将Job所须要的资源提交到HDFS中一个以JobID命名的目录中。这些资源包括JAR包、配置文件、InputSplit、等;
四、JobClient向JobTracker提交这个Job;
五、JobTracker初始化这个Job;
六、JobTracker从HDFS获取这个Job的Split等信息;
七、JobTracker向TaskTracker分配任务;
八、TaskTracker从HDFS获取这个Job的相关资源;
九、TaskTracker开启一个新的JVM;
十、TaskTracker用新的JVM来执行Map或Reduce;
InputSplit也是一个interface,具体返回什么样的implement,这是由具体的InputFormat来决定的。InputSplit也只有两个接口函数:
long getLength() throws IOException;
String[] getLocations() throws IOException;
这个interface仅仅描述了Split有多长,以及存放这个Split的Location信息(也就是这个Split在HDFS上存放的机器。它可能有多个replication,存在于多台机器上)。除此以外,就再没有任何直接描述Split的信息了。好比:Split对应于哪一个文件?在文件中的起始和结束位置是什么?等等重要的特征都没有描述到。
为何会这样呢?由于关于Split的那些描述信息,对于MapReduce框架来讲是不须要关心的。框架只关心Split的长度(主要用于一些统计信息)和Split的Location(主要用于Split的调度,后面会细说)。
而Split中真正重要的描述信息仍是只有InputFormat会关心。在须要读取一个Split的时候,其对应的InputSplit会被传递到InputFormat的第二个接口函数getRecordReader,而后被用于初始化一个RecordReader,以解析输入数据。也就是说,描述Split的重要信息都被隐藏了,只有具体的InputFormat本身知道。它只须要保证getSplits返回的InputSplit和getRecordReader所关心的InputSplit是一样的implement就好了。这就给InputFormat的实现提供了巨大的灵活性。
4. 的
5. 的
6. 的
7. D
8. 的
第3部分 叙述题
第3部分
3.1 Hadoop叙述题
3.1.1 Hadoop部署
1. hdfs的体系结构
解答:
hdfs有namenode、secondraynamenode、datanode组成。
为n+1模式
namenode负责管理datanode和记录元数据
secondraynamenode负责合并日志
datanode负责存储数据
2. 简要描述如何安装配置一个apache开本来hadoop,只描述便可,无需列出完整步骤,能列出步骤更好。
流程:
1.建立hadoop用户
2.修改IP
3.安装JDK,并配置环境变量
4.修改host文件映射
5.安装SSH,配置无秘钥通讯
6.上传解压hadoop安装包
7.配置conf文件夹下的hadoop-env.sh、core-site.xlmapre-site.xml、hdfs-site.xml
8.配置hadoop的环境变量
9.Hadoop namenode -format
10.start-all
3. 启动hadoop集群时报下图错误,分析什么缘由:
解答:
一、权限问题,可能曾经用root启动过集群。(例如hadoop搭建的集群,是tmp/hadoop-hadoop/.....)
二、多是文件夹不存在
三、解决: 删掉tmp下的那个文件,或改为当前用户
4. 请列出hadoop的进程名称
解答:
1.namenode:管理集群,并记录datanode文件信息。
2.Secondname:能够作冷备,对必定范围内的数据作快照性备份。
3.Datanode:存储数据。
4.Jobtracker:管理任务,并将任务分配给tasktracker。
5.Tasktracker:任务执行者
5. Hadoop的核心配置是什么?
解答:
Hadoop的核心配置经过两个xml文件来完成:
1.hadoop-default.xml;
2.hadoop-site.xml。
这些文件都使用xml格式,所以每一个xml中都有一些属性,包括名称和值,可是当下这些文件都已不复存在。
6. 那当下又该如何配置?
解答:
Hadoop如今拥有3个配置文件:
1,core-site.xml;
2,hdfs-site.xml;
3,mapred-site.xml。
这些文件都保存在conf/子目录下。
7. “jps”命令的用处?
解答:
这个命令能够检查Namenode、Datanode、Task Tracker、 Job Tracker是否正常工做。
8. 简要描述如何安装配置一个apache 开源版 hadoop,描述便可,列出步骤更好
解答:
9. 请列出正常工做的 hadoop 集群中 hadoop 都须要启动哪些进程,他们的做用分别是什么?
解答:
10. 启动 hadoop 报以下错误,该如何解决?
error org.apache.hadoop.hdfs.server.namenode.NameNode
org.apache.hadoop.hdfs.server.common.inconsistentFSStateExceptio
n Directory /tmp/hadoop-root/dfs/name is in an inconsistent
state storage direction does not exist or is not accessible?
11. 请写出如下执行命令
1)杀死一个 job?
2)删除 hdfs 上的/tmp/aaa 目录
3)加入一个新的存储节点和删除一个计算节点须要刷新集群状态命令?
解答:
hadoop job -list 记录job-id、hadoop job -kill job-id
hadoop fs -rmr /tmp/aaa
添加新节点:
hadoop -daemon.sh start datanode
hadoop -daemon.sh start tasktracker
移除一个节点:
hadoop mradmin -refreshnodes
hadoop dfsadmin -refreshnodes
12. 请列出你所知道的 hadoop 调度器,并简要说明其工做方法?
解答:
1.FIFO schedular:默认,先进先出的原则
2.Capacity schedular:计算能力调度器,选择占用最小,优先级高的先执行,以此类推。
3.Fair schedular:公平调度,全部的job具备相同的资源。
13. 请列出在你之前工做中所使用过的开发 mapreduce 的语言?
解答:
14. 你认为用 Java,Streaming,pipe 方式开发 mapreduce,各有哪些优缺点?
解答:
15. hadoop框架中怎么来优化
解答:
(1) 从应用程序角度进行优化。因为mapreduce是迭代逐行解析数据文件的,怎样在迭代的状况下,编写高效率的应用程序,是一种优化思路。
(2) 对Hadoop参数进行调优。当前hadoop系统有190多个配置参数,怎样调整这些参数,使hadoop做业运行尽量的快,也是一种优化思路。
(3) 从系统实现角度进行优化。这种优化难度是最大的,它是从hadoop实现机制角度,发现当前Hadoop设计和实现上的缺点,而后进行源码级地修改。该方法虽难度大,但每每效果明显。
(4)linux内核参数调整
1. 使用自定义Writable
自带的Text很好用,可是字符串转换开销较大,故根据实际须要自定义Writable,注意做为Key时要实现WritableCompareable接口
避免output.collect(new Text( ),new Text())
提倡key.set( ) value.set( ) output.collect(key,value)
前者会产生大量的Text对象,使用完后Java垃圾回收器会花费大量的时间去收集这些对象
2. 使用StringBuilder
不要使用Formatter StringBuffer( 线程安全)
StringBuffer尽可能少使用多个append方法,适当使用+
3. 使用DistributedCache加载文件
好比配置文件,词典,共享文件,避免使用static变量
4. 充分使用Combiner Parttitioner Comparator。
Combiner : 对map任务进行本地聚合
Parttitioner : 合适的Parttitioner避免reduce端负载不均
Comparator : 二次排序
好比求天天的最大气温,map结果为日期:气温,若气温是降序的,直接取列表首元素便可
5. 使用自定义InputFormat和OutputFormat
6. MR应避免
静态变量:不能用于计数,应使用Counter
大对象:Map List
递归:避免递归深度过大
超长正则表达式:消耗性能,要在map或reduce函数外编译正则表达式
不要建立本地文件:变向的把HDFS里面的数据转移到TaskTracker,占用网络带宽
不要大量建立目录和文件
不要大量使用System.out.println,而使用Logger
不要自定义过多的Counter,最好不要超过100个
不要配置过大内存,mapred.child.java.opts -Xmx2000m是用来设置mapreduce任务使用的最大heap量
7.关于map的数目
map数目过大[建立和初始化map的开销],通常是由大量小文件形成的,或者dfs.block.size设置的过小,对于小文件能够archive文件或者Hadoop fs -merge合并成一个大文件.
map数目过少,形成单个map任务执行时间过长,频繁推测执行,且容易内存溢出,并行性优点不能体现出来。dfs.block.size通常为256M-512M
压缩的Text 文件是不能被分割的,因此尽可能使用SequenceFile,能够切分
8.关于reduce的数目
reduce数目过大,产生大量的小文件,消耗大量没必要要的资源,reduce数目太低呢,形成数据倾斜问题,且一般不能经过修改参数改变。
可选方案:mapred.reduce.tasks设为-1变成AutoReduce。
Key的分布,也在某种程度上决定了Reduce数目,因此要根据Key的特色设计相对应的Parttitioner 避免数据倾斜
9.Map-side相关参数优化
io.sort.mb(100MB):一般k个map tasks会对应一个buffer,buffer主要用来缓存map部分计算结果,并作一些预排序提升map性能,若map输出结果较大,能够调高这个参数,减小map任务进行spill任务个数,下降 I/O的操做次数。若map任务的瓶颈在I/O的话,那么将会大大提升map性能。如何判断map任务的瓶颈?
io.sort.spill.percent(0.8):spill操做就是当内存buffer超过必定阈值(这里一般是百分比)的时候,会将buffer中得数据写到Disk中。而不是等buffer满后在spill,不然会形成map的计算任务等待buffer的释放。通常来讲,调整 io.sort.mb而不是这个参数。
io.sort.factor(10):map任务会产生不少的spill文件,而map任务在正常退出以前会将这些spill文件合并成一个文件,即merger过程,缺省是一次合并10个参数,调大io.sort.factor,减小merge的次数,减小Disk I/O操做,提升map性能。
min.num.spill.for.combine:一般为了减小map和reduce数据传输量,咱们会制定一个combiner,将map结果进行本地汇集。这里combiner可能在merger以前,也可能在其以后。那么何时在其以前呢?当spill个数至少为min.num.spill.for.combine指定的数目时同时程序指定了Combiner,Combiner会在其以前运行,减小写入到Disk的数据量,减小I/O次数。
10.压缩(时间换空间)
MR中的数据不管是中间数据仍是输入输出结果都是巨大的,若不使用压缩不只浪费磁盘空间且会消耗大量网络带宽。一样在spill,merge(reduce也对有一个merge)亦能够使用压缩。若想在cpu时间和压缩比之间寻找一个平衡,LzoCodec比较适合。一般MR任务的瓶颈不在CPU而在于I/O,因此大部分的MR任务都适合使用压缩。
11. reduce-side相关参数优化
reduce:copy->sort->reduce,也称shuffle
mapred.reduce.parellel.copies(5):任一个map任务可能包含一个或者多个reduce所须要数据,故一个map任务完成后,相应的reduce就会当即启动线程下载本身所须要的数据。调大这个参数比较适合map任务比较多且完成时间比较短的Job。
mapred.reduce.copy.backoff:reduce端从map端下载数据也有可能因为网络故障,map端机器故障而失败。那么reduce下载线程确定不会无限等待,当等待时间超过mapred.reduce.copy.backoff时,便放弃,尝试从其余地方下载。需注意:在网络状况比较差的环境,咱们须要调大这个参数,避免reduce下载线程被误判为失败。
io.sort.factor:recude将map结果下载到本地时,亦须要merge,若是reduce的瓶颈在于I/O,可尝试调高增长merge的并发吞吐,提升reduce性能、
mapred.job.shuffle.input.buffer.percent(0.7):reduce从map下载的数据不会马上就写到Disk中,而是先缓存在内存中,mapred.job.shuffle.input.buffer.percent指定内存的多少比例用于缓存数据,内存大小可经过mapred.child.java.opts来设置。和map相似,buffer不是等到写满才往磁盘中写,也是到达阈值就写,阈值由mapred.job,shuffle.merge.percent来指定。若Reduce下载速度很快,容易内存溢出,适当增大这个参数对增长reduce性能有些帮助。
mapred.job.reduce.input.buffer.percent (0):当Reduce下载map数据完成以后,就会开始真正的reduce的计算,reduce的计算必然也是要消耗内存的,那么在读物reduce所须要的数据时,一样须要内存做为buffer,这个参数是决定多少的内存百分比做为buffer。默认为0,也就是说reduce所有从磁盘读数据。若redcue计算任务消耗内存很小,那么能够设置这个参数大于0,使一部份内存用来缓存数据。
16. 从应用程序角度进行优化
解答:
(1) 避免没必要要的reduce任务
若是mapreduce程序中reduce是没必要要的,那么咱们能够在map中处理数据, Reducer设置为0。这样避免了多余的reduce任务。
(2) 为job添加一个Combiner
为job添加一个combiner能够大大减小shuffle阶段从map task拷贝给远程reduce task的数据量。通常而言,combiner与reducer相同。
(3) 根据处理数据特征使用最适合和简洁的Writable类型
Text对象使用起来很方便,但它在由数值转换到文本或是由UTF8字符串转换到文本时都是低效的,且会消耗大量的CPU时间。当处理那些非文本的数据时,能够使用二进制的Writable类型,如IntWritable, FloatWritable等。二进制writable好处:避免文件转换的消耗;使map task中间结果占用更少的空间。
(4) 重用Writable类型
不少MapReduce用户常犯的一个错误是,在一个map/reduce方法中为每一个输出都建立Writable对象。例如,你的Wordcout mapper方法可能这样写:
public void map(...) {
…
for (String word : words) {
output.collect(new Text(word), new IntWritable(1));
}
}
这样会致使程序分配出成千上万个短周期的对象。Java垃圾收集器就要为此作不少的工做。更有效的写法是:
class MyMapper … {
Text wordText = new Text();
IntWritable one = new IntWritable(1);
public void map(...) {
for (String word: words) {
wordText.set(word);
output.collect(wordText, one);
}
}
}
(5) 使用StringBuffer而不是String
当须要对字符串进行操做时,使用StringBuffer而不是String,String是read-only的,若是对它进行修改,会产生临时对象,而StringBuffer是可修改的,不会产生临时对象。
17. datanode在什么状况下不会备份
解答:
当分备份数为1时。
18. combiner出如今那个过程
解答:
出如今map阶段的map方法后。
19. 3个datanode中有一个datanode出现错误会怎样?
解答:
这个datanode的数据会在其余的datanode上从新作备份。
20. 描述一下hadoop中,有哪些地方使用了缓存机制,做用分别是什么?
解答:
21. 如何肯定hadoop集群的健康状态
解答:
22. hadoop 的 namenode 宕机,怎么解决
解答:
先分析宕机后的损失,宕机后直接致使client没法访问,内存中的元数据丢失,可是硬盘中的元数据应该还存在,若是只是节点挂了,重启便可,若是是机器挂了,重启机器后看节点是否能重启,不能重启就要找到缘由修复了。可是最终的解决方案应该是在设计集群的初期就考虑到这个问题,作namenode的HA。
23. 一个datanode 宕机,怎么一个流程恢复
解答:
Datanode宕机了后,若是是短暂的宕机,能够实现写好脚本监控,将它启动起来。若是是长时间宕机了,那么datanode上的数据应该已经被备份到其余机器了,那这台datanode就是一台新的datanode了,删除他的全部数据文件和状态文件,从新启动。
24. 的
25. D
26. 的
27. 的
28. 的
29. 的
30. d
3.1.2 Hadoop原理
1. 请简述 hadoop 怎么样实现二级排序?
解答:
在Reduce阶段,先对Key排序,再对Value排序
最经常使用的方法是将Value放到Key中,实现一个组合Key,而后自定义Key排序规则(为Key实现一个WritableComparable)。
2. 如何使用MapReduce实现两个表join,能够考虑一下几种状况:(1)一个表大,一个表小(可放到内存中);(2)两个表都是大表?
解答:
第一种状况比较简单,只需将小表放到DistributedCache中便可;
第二种状况经常使用的方法有:map-side join(要求输入数据有序,一般用户Hbase中的数据表链接),reduce-side join,semi join(半链接)
3. MapReduce中排序发生在哪几个阶段?这些排序是否能够避免?为何?
解答:
一个MapReduce做业由Map阶段和Reduce阶段两部分组成,这两阶段会对数据排序,从这个意义上说,MapReduce框架本质就是一个Distributed Sort。在Map阶段,在Map阶段,Map Task会在本地磁盘输出一个按照key排序(采用的是快速排序)的文件(中间可能产生多个文件,但最终会合并成一个),在Reduce阶段,每一个Reduce Task会对收到的数据排序,这样,数据便按照Key分红了若干组,以后以组为单位交给reduce()处理。不少人的误解在Map阶段,若是不使用Combiner便不会排序,这是错误的,无论你用不用Combiner,Map Task均会对产生的数据排序(若是没有Reduce Task,则不会排序, 实际上Map阶段的排序就是为了减轻Reduce端排序负载)。因为这些排序是MapReduce自动完成的,用户没法控制,所以,在hadoop 1.x中没法避免,也不能够关闭,但hadoop2.x是能够关闭的。
4. 请简述 mapreduce 中,combiner,partition 做用?
解答:
combiner是reduce的实现,在map端运行计算任务,减小map端的输出数据。
做用就是优化。
可是combiner的使用场景是mapreduce的map输出结果和reduce输入输出同样。
partition的默认实现是hashpartition,是map端将数据按照reduce个数取余,进行分区,不一样的reduce来copy本身的数据。
partition的做用是将数据分到不一样的reduce进行计算,加快计算效果。
一、combiner最基本是实现本地key的聚合,对map输出的key排序,value进行迭代。以下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K2, V2)
reduce: (K2, list(V2)) → list(K3, V3)
二、combiner还具备相似本地的reduce功能.
例如hadoop自带的wordcount的例子和找出value的最大值的程序,combiner和reduce彻底一致。以下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K3, V3)
reduce: (K3, list(V3)) → list(K4, V4)
三、若是不用combiner,那么,全部的结果都是reduce完成,效率会相对低下。使用combiner,先完成的map会在本地聚合,提高速度。
四、对于hadoop自带的wordcount的例子,value就是一个叠加的数字,因此map一结束就能够进行reduce的value叠加,而没必要要等到全部的map结束再去进行reduce的value叠加。
combiner使用的合适,能够在知足业务的状况下提高job的速度,若是不合适,则将致使输出的结果不正确。
5. 解释―hadoop‖和―hadoop 生态系统‖两个概念
解答:
6. 说明 Hadoop 2.0 的基本构成
解答:
分别说明hdfs,yarn,mapreduce
7. 相比于 HDFS1.0,HDFS 2.0 最主要的改进在哪几方面?
解答:
8. 试使用―步骤 1,步骤 2,步骤 3…..‖说明 YARN 中运行应用程序的基本流程
解答:
9. ―MapReduce 2.0‖与―YARN‖是否等同,尝试解释说明
解答:
10. MapReduce 2.0 中,MRAppMaster 主要做用是什么,MRAppMaster如何实现任务容错的?
解答:
11. hdfs 原理,以及各个模块的职责
解答:
12. mr 的工做原理
解答:
Map—combiner—partition—sort—copy—sort—grouping—reduce
13. map 方法是如何调用 reduce 方法的
解答:
14. shell 如何判断文件是否存在,若是不存在该如何处理?
解答:
15. fsimage 和 edit 的区别?
解答:
16. hadoop1 和 hadoop2 的区别?
解答:
17. hdfs 中的 block 默认报错几份?
解答:
18. 哪一个程序一般与 nn 在一个节点启动?并作分析
解答:
19. 列举几个配置文件优化?
解答:
20. datanode 首次加入 cluster 的时候,若是 log 报告不兼容文件版本,那须要 namenode 执行格式化操做,这样处理的缘由是?
解答:
21. 用mapreduce怎么处理数据倾斜问题?
解答:
数据倾斜:map /reduce程序执行时,reduce节点大部分执行完毕,可是有一个或者几个reduce节点运行很慢,致使整个程序的处理时间很长,这是由于某一个key的条数比其余key多不少(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其余节点就大不少,从而致使某几个节点迟迟运行不完,此称之为数据倾斜。
用hadoop程序进行数据关联时,常碰到数据倾斜的状况,这里提供一种解决方法。
本身实现partition类,用key和value相加取hash值:
方式1:
源代码:
public int getPartition(K key, V value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
修改后
public int getPartition(K key, V value,
int numReduceTasks) {
return (((key).hashCode()+value.hashCode()) & Integer.MAX_VALUE) % numReduceTasks;
}
方式2:
public class HashPartitioner<K, V> extends Partitioner<K, V> {
private int aa= 0;
/** Use {@link Object#hashCode()} to partition. */
public int getPartition(K key, V value,
int numReduceTasks) {
return (key.hashCode()+(aa++) & Integer.MAX_VALUE) % numReduceTasks;
}
22. 谈谈数据倾斜,如何发生的,并给出优化方案
解答:
23. mapreduce 基本执行过程
解答:
24. 谈谈 hadoop1 和 hadoop2 的区别
解答:
25. hadoop中Combiner的做用?
解答:
combiner是reduce的实现,在map端运行计算任务,减小map端的输出数据。
做用就是优化。
可是combiner的使用场景是mapreduce的map和reduce输入输出同样。
26. Mapreduce 的 map 数量 和 reduce 数量 怎么肯定 ,怎么配置
解答:
map的数量有数据块决定,reduce数量随便配置。
27. 在hadoop中文件的压缩带来了两大好处:
解答:
(1)它减小了存储文件所需的空间;
(2)加快了数据在网络上或者从磁盘上或到磁盘上的传输速度;
28. mapreduce的调度模式
解答:
一个MapReduce做业的生命周期大致分为5个阶段 【1】 :
1. 做业提交与初始化
2. 任务调度与监控
3. 任务运行环境准备
4. 任务执行
5. 做业完成
咱们假设JobTracker已经启动,那么调度器是怎么启动的?JobTracker在启动时有如下代码:
JobTracker tracker = startTracker(new JobConf());
tracker.offerService();
其中offerService方法负责启动JobTracker提供的各个服务,有这样一行代码:
taskScheduler.start();
taskScheduler即为任务调度器。start方法是抽象类TaskScheduler提供的接口,用于启动调度器。每一个调度器类都要继承TaskScheduler类。回忆一下,调度器启动时会将各个监听器对象注册到JobTracker,以FIFO调度器JobQueueTaskScheduler为例:
@Override
public synchronized void start() throws IOException {
super.start();
taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener);
eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager);
eagerTaskInitializationListener.start();
taskTrackerManager.addJobInProgressListener(
eagerTaskInitializationListener);
}
这里注册了两个监听器,其中eagerTaskInitializationListener负责做业初始化,而jobQueueJobInProgressListener则负责做业的执行和监控。当有做业提交到JobTracker时,JobTracker会执行全部订阅它消息的监听器的jobAdded方法。对于eagerTaskInitializationListener来讲:
@Override
public void jobAdded(JobInProgress job) {
synchronized (jobInitQueue) {
jobInitQueue.add(job);
resortInitQueue();
jobInitQueue.notifyAll();
}
}
提交的做业的JobInProgress对象被添加到做业初始化队列jobInitQueue中,并唤醒初始化线程(若原来没有做业能够初始化):
class JobInitManager implements Runnable {
public void run() {
JobInProgress job = null;
while (true) {
try {
synchronized (jobInitQueue) {
while (jobInitQueue.isEmpty()) {
jobInitQueue.wait();
}
job = jobInitQueue.remove(0);
}
threadPool.execute(new InitJob(job));
} catch (InterruptedException t) {
LOG.info("JobInitManagerThread interrupted.");
break;
}
}
threadPool.shutdownNow();
}
}
这种工做方式是一种“生产者-消费者”模式:做业初始化线程是消费者,而监听器eagerTaskInitializationListener是生产者。这里能够有多个消费者线程,放到一个固定资源的线程池中,线程个数经过mapred.jobinit.threads参数配置,默认为4个。
下面咱们重点来看调度器中的另外一个监听器。 jobQueueJobInProgressListener对象在调度器中初始化时连续执行了两个构造器完成初始化:
public JobQueueJobInProgressListener() {
this(new TreeMap<JobSchedulingInfo,
JobInProgress>(FIFO_JOB_QUEUE_COMPARATOR));
}
/**
* For clients that want to provide their own job priorities.
* @param jobQueue A collection whose iterator returns jobs in priority order.
*/
protected JobQueueJobInProgressListener(Map<JobSchedulingInfo,
JobInProgress> jobQueue) {
this.jobQueue = Collections.synchronizedMap(jobQueue);
}
其中,第一个构造器调用重载的第二个构造器。能够看到,调度器使用一个队列jobQueue来保存提交的做业。这个队列使用一个TreeMap对象实现,TreeMap的特色是底层使用红黑树实现,能够按照键来排序,而且因为是平衡树,效率较高。做为键的是一个JobSchedulingInfo对象,做为值就是提交的做业对应的JobInProgress对象。另外,因为TreeMap自己不是线程安全的,这里使用了集合类的同步方法构造了一个线程安全的Map。使用带有排序功能的数据结构的目的是使做业在队列中按照优先级的大小排列,这样每次调度器只需从队列头部得到做业便可。
做业的顺序由优先级决定,而优先级信息包含在JobSchedulingInfo对象中:
static class JobSchedulingInfo {
private JobPriority priority;
private long startTime;
private JobID id;
...
}
该对象包含了做业的优先级、ID和开始时间等信息。在Hadoop中,做业的优先级有如下五种:VERY_HIGH、HIGH、NORMAL、LOW、VERY_LOW。这些字段是经过做业的JobStatus对象初始化的。因为该对象做为TreeMap的键,所以要实现本身的equals方法和hashCode方法:
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != JobSchedulingInfo.class) {
return false;
} else if (obj == this) {
return true;
}
else if (obj instanceof JobSchedulingInfo) {
JobSchedulingInfo that = (JobSchedulingInfo)obj;
return (this.id.equals(that.id) &&
this.startTime == that.startTime &&
this.priority == that.priority);
}
return false;
}
咱们看到,两个JobSchedulingInfo对象相等的条件是类型一致,而且做业ID、开始时间和优先级都相等。hashCode的计算比较简单:
@Override
public int hashCode() {
return (int)(id.hashCode() * priority.hashCode() + startTime);
}
注意,监听器的第一个构造器有一个比较器参数,用于定义 JobSchedulingInfo的比较方式:
static final Comparator<JobSchedulingInfo> FIFO_JOB_QUEUE_COMPARATOR
= new Comparator<JobSchedulingInfo>() {
public int compare(JobSchedulingInfo o1, JobSchedulingInfo o2) {
int res = o1.getPriority().compareTo(o2.getPriority());
if (res == 0) {
if (o1.getStartTime() < o2.getStartTime()) {
res = -1;
} else {
res = (o1.getStartTime() == o2.getStartTime() ? 0 : 1);
}
}
if (res == 0) {
res = o1.getJobID().compareTo(o2.getJobID());
}
return res;
}
};
从上面看出,首先比较做业的优先级,若优先级相等则比较开始时间(FIFO),若再相等则比较做业ID。 咱们在实现本身的调度器时可能要定义本身的做业队列,那么做业在队列中的顺序(即 JobSchedulingInfo的比较器 )就要仔细定义,这是调度器可以正常运行基础。
Hadoop中的做业调度采用pull方式,即TaskTracker定时向JobTracker发送心跳信息索取一个新的任务,这些信息包括数据结点上做业和任务的运行状况,以及该TaskTracker上的资源使用状况。JobTracker会依据以上信息更新做业队列的状态,并调用调度器选择一个或多个任务以心跳响应的形式返回给TaskTracker。从上面描述能够看出,JobTracker和taskScheduler之间的互相利用关系:前者利用后者为TaskTracker分配任务;后者利用前者更新队列和做业信息。接下来,咱们一步步详述该过程。
首先,当一个心跳到达JobTracker时(实际上这是一个来自TaskTracker的远程过程调用 heartbeat方法 ,协议接口是InterTrackerProtocol),会执行两种动做:更新状态和下达命令 【1】 。下达命令稍后关注。有关更新状态的一些代码片断以下:
if (!processHeartbeat(status, initialContact, now)) {
if (prevHeartbeatResponse != null) {
trackerToHeartbeatResponseMap.remove(trackerName);
}
return new HeartbeatResponse(newResponseId,
new TaskTrackerAction[] {new ReinitTrackerAction()});
}
具体的心跳处理,由私有函数processHeartbeat完成。该函数中有如下两个方法调用:
updateTaskStatuses(trackerStatus);
updateNodeHealthStatus(trackerStatus, timeStamp);
分别用来更新任务的状态和结点的健康状态。在第一个方法中有下面代码片断:
TaskInProgress tip = taskidToTIPMap.get(taskId);
// Check if the tip is known to the jobtracker. In case of a restarted
// jt, some tasks might join in later
if (tip != null || hasRestarted()) {
if (tip == null) {
tip = job.getTaskInProgress(taskId.getTaskID());
job.addRunningTaskToTIP(tip, taskId, status, false);
}
// Update the job and inform the listeners if necessary
JobStatus prevStatus = (JobStatus)job.getStatus().clone();
// Clone TaskStatus object here, because JobInProgress
// or TaskInProgress can modify this object and
// the changes should not get reflected in TaskTrackerStatus.
// An old TaskTrackerStatus is used later in countMapTasks, etc.
job.updateTaskStatus(tip, (TaskStatus)report.clone());
JobStatus newStatus = (JobStatus)job.getStatus().clone();
// Update the listeners if an incomplete job completes
if (prevStatus.getRunState() != newStatus.getRunState()) {
JobStatusChangeEvent event =
new JobStatusChangeEvent(job, EventType.RUN_STATE_CHANGED,
prevStatus, newStatus);
updateJobInProgressListeners(event);
}
} else {
LOG.info("Serious problem. While updating status, cannot find taskid "
+ report.getTaskID());
}
这里的job对象经过从TaskTracker那里获得的task状态信息中抽取出来。注意,这里拷贝了原有做业状态的一个副本,而后修改这个副本的相关信息,调用的是updateJobStatus方法,更新任务的状态信息和JobInProgress的相关信息,如map和reduce任务的进度等,这里不展开了。这些信息的更新能够为调度器的工做提供依据。
做业状态的更新是经过updateJobInProgressListeners方法实现,该方法的参数是一个JobStatusChangeEvent对象,表示做业状态变化的事件。这种事件的类型能够是运行状态改变、开始时间改变、优先级改变等等。用户也能够根据须要自定义事件类型。事件对象维护了两个JobStatus对象,分别表示事件发生先后做业的状态。
进入该方法后,咱们又看到了熟悉的观察者模式:
// Update the listeners about the job
// Assuming JobTracker is locked on entry.
private void updateJobInProgressListeners(JobChangeEvent event) {
for (JobInProgressListener listener : jobInProgressListeners) {
listener.jobUpdated(event);
}
}
此次每一个监听器要回调jobUpdated方法,表示做业有更新。对于jobQueueJobInProgressListener来讲是这样作的:
@Override
public synchronized void jobUpdated(JobChangeEvent event) {
JobInProgress job = event.getJobInProgress();
if (event instanceof JobStatusChangeEvent) {
// Check if the ordering of the job has changed
// For now priority and start-time can change the job ordering
JobStatusChangeEvent statusEvent = (JobStatusChangeEvent)event;
JobSchedulingInfo oldInfo =
new JobSchedulingInfo(statusEvent.getOldStatus());
if (statusEvent.getEventType() == EventType.PRIORITY_CHANGED
|| statusEvent.getEventType() == EventType.START_TIME_CHANGED) {
// Make a priority change
reorderJobs(job, oldInfo);
} else if (statusEvent.getEventType() == EventType.RUN_STATE_CHANGED) {
// Check if the job is complete
int runState = statusEvent.getNewStatus().getRunState();
if (runState == JobStatus.SUCCEEDED
|| runState == JobStatus.FAILED
|| runState == JobStatus.KILLED) {
jobCompleted(oldInfo);
}
}
}
}
首先,获取做业更新 前 的状态。而后根据事件的类型,进行相应的处理。好比,若是优先级变化了,则要从新排列队列中做业的顺序。这里直接取出原有做业,从新插入队列。插入后,做业会自动从新排序,体现了TreeMap的优越性。再好比,若是做业状态变为完成,那么就从队列中删除该做业。
private void reorderJobs(JobInProgress job, JobSchedulingInfo oldInfo) {
synchronized (jobQueue) {
jobQueue.remove(oldInfo);
jobQueue.put(new JobSchedulingInfo(job), job);
}
}
下面就是调度器中最关键的一步了:任务选择。此时,做业队列中信息已经更新完毕,能够选择一些任务返回给TaskTracker执行了。heartbeat方法接下来会有这样的代码:
List<Task> tasks = getSetupAndCleanupTasks(taskTrackerStatus);
if (tasks == null ) {
tasks = taskScheduler.assignTasks(taskTrackers.get(trackerName));
}
若是不须要setup和cleanup,就说明须要选择map或reduce任务。调用TaskScheduler的assignTasks方法完成任务选择。因为篇幅限制,我打算将这部份内容放到下一篇文章中,并关注heartbeat中JobTracker下达的命令过程以及JobInProgress和TaskInProgress对调度有影响的一些字段。
29. 是
30.
3.1.3 Hadoop使用
1. hdfs写流程
流程:
1.client连接namenode存数据
2.namenode记录一条数据位置信息(元数据),告诉client存哪。
3.client用hdfs的api将数据块(默认是64M)存储到datanode上。
4.datanode将数据水平备份。而且备份完将反馈client。
5.client通知namenode存储块完毕。
6.namenode将元数据同步到内存中。
7.另外一块循环上面的过程。
2. hdfs读流程
流程:
1.client连接namenode,查看元数据,找到数据的存储位置。
2.client经过hdfs的api并发读取数据。
3.关闭链接。
3. 举一个简单的例子说明mapreduce是怎么来运行的 ?
解答:
Word count例子接口
============================
一个MapReduce做业(job)一般会把输入的数据集切分为若干独立的数据块,由map任务(task)以彻底并行的方式处理它们。框架会对map的输出先进行排序,而后把结果输入给reduce任务。一般做业的输入和输出都会被存储在文件系统中。整个框架负责任务的调度和监控,以及从新执行已经失败的任务。
一般,MapReduce框架和分布式文件系统是运行在一组相同的节点上的,也就是说,计算节点和存储节点一般在一块儿。这种配置容许框架在那些已经存好数据的节点上高效地调度任务,这能够使整个集群的网络带宽被很是高效地利用。
MapReduce框架由一个单独的master JobTracker和每一个集群节点一个slave TaskTracker共同组成。master负责调度构成一个做业的全部任务,这些任务分布在不一样的slave上,master监控它们的执行,从新执行已经失败的任务。而slave仅负责执行由master指派的任务
4. 用mapreduce来实现下面需求?如今有10个文件夹,每一个文件夹都有1000000个url.如今让你找出top1000000url。
5. yarn流程
解答:
1) 用户向YARN 中提交应用程序, 其中包括ApplicationMaster 程序、启动ApplicationMaster 的命令、用户程序等。
2) ResourceManager 为该应用程序分配第一个Container, 并与对应的NodeManager 通讯,要求它在这个Container 中启动应用程序的ApplicationMaster。
3) ApplicationMaster 首先向ResourceManager 注册, 这样用户能够直接经过ResourceManage 查看应用程序的运行状态,而后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
4) ApplicationMaster 采用轮询的方式经过RPC 协议向ResourceManager 申请和领取资源。
5) 一旦ApplicationMaster 申请到资源后,便与对应的NodeManager 通讯,要求它启动任务。
6) NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并经过运行该脚本启动任务。
7) 各个任务经过某个RPC 协议向ApplicationMaster 汇报本身的状态和进度,以让ApplicationMaster 随时掌握各个任务的运行状态,从而能够在任务失败时从新启动任务。在应用程序运行过程当中,用户可随时经过RPC 向ApplicationMaster 查询应用程序的当前运行状态。
8) 应用程序运行完成后,ApplicationMaster 向ResourceManager 注销并关闭本身。
6. 的
7. 的
8. 的
9. 的
10. 的
11.
12. 的
13.
3.2 Hive叙述题
3.2.1 Hive基础
1. hive 有哪些方式保存元数据,各有哪些特色?
解答:
一、内存数据库derby,安装小,可是数据存在内存,不稳定
二、mysql数据库,数据存储模式能够本身设置,持久化好,查看方便。
2. hive内部表和外部表的区别
解答:
内部表:加载数据到hive所在的hdfs目录,删除时,元数据和数据文件都删除
外部表:不加载数据到hive所在的hdfs目录,删除时,只删除表结构。
3. 生产环境中为何建议使用外部表?
解答:
一、由于外部表不会加载数据到hive,减小数据传输、数据还能共享。
二、hive不会修改数据,因此无需担忧数据的损坏
三、删除表时,只删除表结构、不删除数据。
4. 大家数据库怎么导入hive 的,有没有出现问题
解答:
在导入hive的时候,若是数据库中有blob或者text字段,会报错。有个参数limit
5. 简述Hive中的虚拟列做用是什么,使用它的注意事项
解答:
Hive提供了三个虚拟列:
INPUT__FILE__NAME
BLOCK__OFFSET__INSIDE__FILE
ROW__OFFSET__INSIDE__BLOCK
但ROW__OFFSET__INSIDE__BLOCK默认是不可用的,须要设置hive.exec.rowoffset为true才能够。能够用来排查有问题的输入数据。
INPUT__FILE__NAME, mapper任务的输出文件名。
BLOCK__OFFSET__INSIDE__FILE, 当前全局文件的偏移量。对于块压缩文件,就是当前块的文件偏移量,即当前块的第一个字节在文件中的偏移量。
hive> SELECT INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE, line
> FROM hive_text WHERE line LIKE '%hive%' LIMIT 2;
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 2243
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 3646
6. hive partition分区
解答:
分区表,动态分区
7. insert into 和 override write区别?
解答:
insert into:将某一张表中的数据写到另外一张表中
override write:覆盖以前的内容。
8. 假如一个分区的数据主部错误怎么经过hivesql删除hdfs
解答:
alter table ptable drop partition (daytime='20140911',city='bj');
元数据,数据文件都删除,但目录daytime= 20140911还在
9. Hive里面用什么代替in查询
解答:
提示:Hive中的left semi join替换sql中的in操做
10. 的
11. 的
12. d
3.3 Hbase
3.3.1 Hbase基础
1. 介绍一下 hbase 过滤器
解答:
2. hbase 集群安装注意事项
解答:
3. hbase的rowkey怎么建立好?列族怎么建立比较好?
解答:
hbase存储时,数据按照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将常常一块儿读取的行存储放到一块儿。(位置相关性)
一个列族在数据底层是一个文件,因此将常常一块儿查询的列放到一个列族中,列族尽可能少,减小文件的寻址时间。
由于hbase是列式数据库,列非表schema的一部分,因此在设计初期只须要考虑rowkey 和 columnFamily便可,rowkey有位置相关性,因此若是数据是练习查询的,最好对同类数据加一个前缀,而每一个columnFamily实际上在底层是一个文件,那么文件越小,查询越快,因此讲常常一块儿查询的列设计到一个列簇,可是列簇不宜过多。
Rowkey长度原则
Rowkey是一个二进制码流,Rowkey的长度被不少开发者建议说设计在10~100个字节,不过建议是越短越好,不要超过16个字节。
缘由以下:
(1)数据的持久化文件HFile中是按照KeyValue存储的,若是Rowkey过长好比100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
(2)MemStore将缓存部分数据到内存,若是Rowkey字段过长内存的有效利用率会下降,系统将没法缓存更多的数据,这会下降检索效率。所以Rowkey的字节长度越短越好。
(3)目前操做系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操做系统的最佳特性。
Rowkey散列原则
若是Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位做为散列字段,由程序循环生成,低位放时间字段,这样将提升数据均衡分布在每一个Regionserver实现负载均衡的概率。若是没有散列字段,首字段直接是时间信息将产生全部新数据都在一个 RegionServer上堆积的热点现象,这样在作数据检索的时候负载将会集中在个别RegionServer,下降查询效率。
Rowkey惟一原则
必须在设计上保证其惟一性。
4. 简述Hbase性能优化的思路
解答:
一、在库表设计的时候,尽可能考虑rowkey和columnfamily的特性
二、进行hbase集群的调优
5. 简述Hbase filter的实现原理是什么?结合实际项目经验,写出几个使用filter的场景。
解答:
hbase的filter是经过scan设置的,因此是基于scan的查询结果进行过滤。
1.在进行订单开发的时候,咱们使用rowkeyfilter过滤出某个用户的全部订单
2.在进行云笔记开发时,咱们使用rowkey过滤器进行redis数据的恢复。
6. ROWKEY的后缀匹配怎么实现?列如ROWKEY是yyyyMMDD-UserID形式,如UserID为条件查询数据,怎么实现。
解答:
7. HBase的检索支持3种方式:
解答:
(1) 经过单个Rowkey访问,即按照某个Rowkey键值进行get操做,这样获取惟一一条记录;
(2) 经过Rowkey的range进行scan,即经过设置startRowKey和endRowKey,在这个范围内进行扫描。这样能够按指定的条件获取一批记录;
(3) 全表扫描,即直接扫描整张表中全部行记录。
8. 简述HBase的瓶颈
解答:
HBase的瓶颈就是硬盘传输速度。HBase的操做,它能够往数据里面insert,也能够update一些数据,但update的实际上也是insert,只是插入一个新的时间戳的一行。Delete数据,也是insert,只是insert一行带有delete标记的一行。Hbase的全部操做都是追加插入操做。Hbase是一种日志集数据库。它的存储方式,像是日志文件同样。它是批量大量的往硬盘中写,一般都是以文件形式的读写。这个读写速度,就取决于硬盘与机器之间的传输有多快。而Oracle的瓶颈是硬盘寻道时间。它常常的操做时随机读写。要update一个数据,先要在硬盘中找到这个block,而后把它读入内存,在内存中的缓存中修改,过段时间再回写回去。因为你寻找的block不一样,这就存在一个随机的读。硬盘的寻道时间主要由转速来决定的。而寻道时间,技术基本没有改变,这就造成了寻道时间瓶颈。
9. Hbase内部是什么机制?
解答:
在HMaster、RegionServer内部,建立了RpcServer实例,并与Client三者之间实现了Rpc调用,HBase0.95内部引入了Google-Protobuf做为中间数据组织方式,并在Protobuf提供的Rpc接口之上,实现了基于服务的Rpc实现,本文详细阐述了HBase-Rpc实现细节。
HBase的RPC Protocol
在HMaster、RegionServer内部,实现了rpc 多个protocol来完成管理和应用逻辑,具体以下protocol以下:
HMaster支持的Rpc协议:
MasterMonitorProtocol,Client与Master之间的通讯,Master是RpcServer端,主要实现HBase集群监控的目的。
MasterAdminProtocol,Client与Master之间的通讯,Master是RpcServer端,主要实现HBase表格的管理。例如TableSchema的更改,Table-Region的迁移、合并、下线(Offline)、上线(Online)以及负载平衡,以及Table的删除、快照等相关功能。
RegionServerStatusProtoco,RegionServer与Master之间的通讯,Master是RpcServer端,负责提供RegionServer向HMaster状态汇报的服务。
RegionServer支持的Rpc协议:
ClientProtocol,Client与RegionServer之间的通讯,RegionServer是RpcServer端,主要实现用户的读写请求。例如get、multiGet、mutate、scan、bulkLoadHFile、执行Coprocessor等。
AdminProtocols,Client与RegionServer之间的通讯,RegionServer是RpcServer端,主要实现Region、服务、文件的管理。例如storefile信息、Region的操做、WAL操做、Server的开关等。
(备注:以上提到的Client能够是用户Api、也能够是RegionServer或者HMaster)
HBase-RPC实现机制分析
RpcServer配置三个队列:
1)普通队列callQueue,绝大部分Call请求存在该队列中:callQueue上maxQueueLength为${ipc.server.max.callqueue.length},默认是${hbase.master.handler.count}*DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER,目前0.95.1中,每一个Handler上CallQueue的最大个数默认值(DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER)为10。
2)优先级队列: PriorityQueue。若是设置priorityHandlerCount的个数,会建立与callQueue至关容量的queue存储Call,该优先级队列对应的Handler的个数由rpcServer实例化时传入。
3)拷贝队列:replicationQueue。因为RpcServer由HMaster和RegionServer共用,该功能仅为RegionServer提供,queue的大小为${ipc.server.max.callqueue.size}指定,默认为1024*1024*1024,handler的个数为hbase.regionserver.replication.handler.count。
RpcServer由三个模块组成:
Listener ===Queue=== Responder
这里以HBaseAdmin.listTables为例, 分析一个Rpc请求的函数调用过程:
1) RpcClient建立一个BlockingRpcChannel。
2)以channel为参数建立执行RPC请求须要的stub,此时的stub已经被封装在具体Service下,stub下定义了可执行的rpc接口。
3)stub调用对应的接口,实际内部channel调用callBlockingMethod方法。
RpcClient内实现了protobuf提供的BlockingRpcChannel接口方法callBlockingMethod, @OverridepublicMessage callBlockingMethod(MethodDescriptor md, RpcController controller,Message param, Message returnType)throwsServiceException {returnthis.rpcClient.callBlockingMethod(md, controller, param, returnType, this.ticket,this.isa, this.rpcTimeout);}
经过以上的实现细节,最终转换成rpcClient的调用,使用MethodDescriptor封装了不一样rpc函数,使用Message基类能够接收基于Message的不一样的Request和Response对象。
4)RpcClient建立Call对象,查找或者建立合适的Connection,并唤醒Connection。
5)Connection等待Call的Response,同时rpcClient调用函数中,会使用connection.writeRequest(Call call)将请求写入到RpcServer网络流中。
6)等待Call的Response,而后层层返回给更上层接口,从而完成这次RPC调用。
RPCServer收到的Rpc报文的内部组织以下:
Magic
(4Byte)
Version
(1Byte)
AuthMethod
(1Byte)
Connection
HeaderLength
(4Byte)
ConnectionHeader
Request
“HBas”
验证RpcServer的CURRENT_VERSION
与RPC报文一致
目前支持三类:
AuthMethod.SIMPLE
AuthMethod.KERBEROS
AuthMethod.DIGEST
RPC.proto定义
RPCProtos.ConnectionHeader
message ConnectionHeader {
optional UserInformation userInfo = 1;
optional string serviceName = 2;
// Cell block codec we will use sending over optional cell blocks. Server throws exception
// if cannot deal.
optional string cellBlockCodecClass = 3 [default = "org.apache.hadoop.hbase.codec.KeyValueCodec"];
// Compressor we will use if cell block is compressed. Server will throw exception if not supported.
// Class must implement hadoop’s CompressionCodec Interface
optional string cellBlockCompressorClass = 4;
}
序列化以后的数据
整个Request存储是通过编码以后的byte数组,包括以下几个部分:
RequestHeaderLength(RawVarint32)
RequestHeader
ParamSize(RawVarint32)
Param
CellScanner
RPC.proto定义:
message RequestHeader {
// Monotonically increasing callId to keep track of RPC requests and their response
optional uint32 callId = 1;
optional RPCTInfo traceInfo = 2;
optional string methodName = 3;
// If true, then a pb Message param follows.
optional bool requestParam = 4;
// If present, then an encoded data block follows.
optional CellBlockMeta cellBlockMeta = 5;
// TODO: Have client specify priority
}
序列化以后的数据
并从Header中确认是否存在Param和CellScanner,若是确认存在的状况下,会继续访问。
Protobuf的基本类型Message,
Request的Param继承了Message,
这个须要获取的Method类型决定。
从功能上讲,RpcServer上包含了三个模块,
1)Listener。包含了多个Reader线程,经过Selector获取ServerSocketChannel接收来自RpcClient发送来的Connection,并从中重构Call实例,添加到CallQueue队列中。
”IPC Server listener on 60021″ daemon prio=10 tid=0x00007f7210a97800 nid=0x14c6 runnable [0x00007f720e8d0000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c43cae68> (a sun.nio.ch.Util$2)
- locked <0x00000000c43cae50> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4322ca8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
at org.apache.hadoop.hbase.ipc.RpcServer$Listener.run(RpcServer.java:646)
2)Handler。负责执行Call,调用Service的方法,而后返回Pair<Message,CellScanner>
“IPC Server handler 0 on 60021″ daemon prio=10 tid=0x00007f7210eab000 nid=0x14c7 waiting on condition [0x00007f720e7cf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c43cad90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399)
at org.apache.hadoop.hbase.ipc.RpcServer$Handler.run(RpcServer.java:1804)
3) Responder。负责把Call的结果返回给RpcClient。
”IPC Server Responder” daemon prio=10 tid=0x00007f7210a97000 nid=0x14c5 runnable [0x00007f720e9d1000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c4407078> (a sun.nio.ch.Util$2)
- locked <0x00000000c4407060> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4345b68> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.doRunLoop(RpcServer.java:833)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.run(RpcServer.java:816)
RpcClient为Rpc请求创建Connection,经过Connection将Call发送RpcServer,而后RpcClient等待结果的返回。
10. 的
11. 的
12. 的
13. 的
14. 的
3.4 Zookeeper
1. 写出你对 zookeeper 的理解
解答:
2. 的
3. 的
4. 的
3.5 Storm
1. storm 若是碰上了复杂逻辑,须要算很长的时间,你怎么去优化
解答:
拆分复杂的业务到多个bolt中,这样能够利用bolt的tree将速度提高
提升并行度
2. 开发流程,容错机制
解答:
开发流程:
写主类(设计spout和bolt的分发机制)
写spout收集数据
写bolt处理数据,根据数据量和业务的复杂程度,设计并行度。
容错机制:
采用ack和fail进行容错,失败的数据从新发送。
3. storm和spark-streaming:为何用storm不一样spark-streaming
解答:
4. 的
5. 的
6. 的
7. 的
3.6 Flume
1. flume管道内存,flume宕机了数据丢失怎么解决
解答:
一、Flume的channel分为不少种,能够将数据写入到文件
二、防止非首个agent宕机的方法数能够作集群或者主备
2. flume配置方式,flume集群(问的很详细)
解答:
Flume的配置围绕着source、channel、sink叙述,flume的集群是作在agent上的,而非机器上。
3. flume不采集Nginx日志,经过Logger4j采集日志,优缺点是什么?
解答:
优势:Nginx的日志格式是固定的,可是缺乏sessionid,经过logger4j采集的日志是带有sessionid的,而session能够经过redis共享,保证了集群日志中的同一session落到不一样的tomcat时,sessionId仍是同样的,并且logger4j的方式比较稳定,不会宕机。
缺点:不够灵活,logger4j的方式和项目结合过于紧密,而flume的方式比较灵活,拔插式比较好,不会影响项目性能。
4. flume和kafka采集日志区别,采集日志时中间停了,怎么记录以前的日志。
解答:
Flume采集日志是经过流的方式直接将日志收集到存储层,而kafka试讲日志缓存在kafka集群,待后期能够采集到存储层。
Flume采集中间停了,能够采用文件的方式记录以前的日志,而kafka是采用offset的方式记录以前的日志。
5. 的
6. 的
3.7 Kafka
1. Kafka容错机制
解答:
分区备份,存在主备partition
2. kafka数据流向
解答:
Producer à leader partition à follower partition(半数以上) àconsumer
3. kafka+spark-streaming结合丢数据怎么解决?
解答:
spark streaming从1.2开始提供了数据的零丢失,想享受这个特性,须要知足以下条件:
数据输入须要可靠的sources和可靠的receivers
应用metadata必须经过应用driver checkpoint
WAL(write ahead log)
可靠的sources和receivers
spark streaming能够经过多种方式做为数据sources(包括kafka),输入数据经过receivers接收,经过replication存储于spark中(为了faultolerance,默认复制到两个spark executors),若是数据复制完成,receivers能够知道(例如kafka中更新offsets到zookeeper中)。这样当receivers在接收数据过程当中crash掉,不会有数据丢失,receivers没有复制的数据,当receiver恢复后从新接收。
metadata checkpoint
可靠的sources和receivers,能够使数据在receivers失败后恢复,然而在driver失败后恢复是比较复杂的,一种方法是经过checkpoint metadata到HDFS或者S3。metadata包括:
configuration
code
一些排队等待处理但没有完成的RDD(仅仅是metadata,而不是data)
这样当driver失败时,能够经过metadata checkpoint,重构应用程序并知道执行到那个地方。
数据可能丢失的场景
可靠的sources和receivers,以及metadata checkpoint也不能够保证数据的不丢失,例如:
两个executor获得计算数据,并保存在他们的内存中
receivers知道数据已经输入
executors开始计算数据
driver忽然失败
driver失败,那么executors都会被kill掉
由于executor被kill掉,那么他们内存中得数据都会丢失,可是这些数据再也不被处理
executor中的数据不可恢复
WAL
为了不上面情景的出现,spark streaming 1.2引入了WAL。全部接收的数据经过receivers写入HDFS或者S3中checkpoint目录,这样当driver失败后,executor中数据丢失后,能够经过checkpoint恢复。
At-Least-Once
尽管WAL能够保证数据零丢失,可是不能保证exactly-once,例以下面场景:
Receivers接收完数据并保存到HDFS或S3
在更新offset前,receivers失败了
Spark Streaming觉得数据接收成功,可是Kafka觉得数据没有接收成功,由于offset没有更新到zookeeper
随后receiver恢复了
从WAL能够读取的数据从新消费一次,由于使用的kafka High-Level消费API,从zookeeper中保存的offsets开始消费
WAL的缺点
经过上面描述,WAL有两个缺点:
下降了receivers的性能,由于数据还要存储到HDFS等分布式文件系统
对于一些resources,可能存在重复的数据,好比Kafka,在Kafka中存在一份数据,在Spark Streaming也存在一份(以WAL的形式存储在hadoop API兼容的文件系统中)
Kafka direct API
为了WAL的性能损失和exactly-once,spark streaming1.3中使用Kafka direct API。很是巧妙,Spark driver计算下个batch的offsets,指导executor消费对应的topics和partitions。消费Kafka消息,就像消费文件系统文件同样。
再也不须要kafka receivers,executor直接经过Kafka API消费数据
WAL再也不须要,若是从失败恢复,能够从新消费
exactly-once获得了保证,不会再从WAL中重复读取数据
总结
主要说的是spark streaming经过各类方式来保证数据不丢失,并保证exactly-once,每一个版本都是spark streaming愈来愈稳定,愈来愈向生产环境使用发展。
4. kafka中存储目录data/dir.....topic1和topic2怎么存储的,存储结构,data.....目录下有多少个分区,每一个分区的存储格式是什么样的?
解答:
一、topic是按照“主题名-分区”存储的
二、分区个数由配置文件决定
三、每一个分区下最重要的两个文件是0000000000.log和000000.index,0000000.log以默认1G大小回滚。
5. 的
6. D 的
3.8 Spark
1. mr和spark区别,怎么理解spark-rdd
解答:
Mr是文件方式的分布式计算框架,是将中间结果和最终结果记录在文件中,map和reduce的数据分发也是在文件中。
spark是内存迭代式的计算框架,计算的中间结果能够缓存内存,也能够缓存硬盘,可是不是每一步计算都须要缓存的。
Spark-rdd是一个数据的分区记录集合………………
2. Spark应用转换流程
解答:
一、spark应用提交后,经历了一系列的转换,最后成为task在每一个节点上执行
二、RDD的Action算子触发Job的提交,生成RDD DAG
三、由DAGScheduler将RDD DAG转化为Stage DAG,每一个Stage中产生相应的Task集合
四、TaskScheduler将任务分发到Executor执行
五、每一个任务对应相应的一个数据块,只用用户定义的函数处理数据块
3. Driver运行在Worker上
解答:
经过org.apache.spark.deploy.Client类执行做业,做业运行命令以下:
做业执行流程描述:
一、客户端提交做业给Master
二、Master让一个Worker启动Driver,即SchedulerBackend。Worker建立一个DriverRunner线程,DriverRunner启动SchedulerBackend进程。
三、另外Master还会让其他Worker启动Exeuctor,即ExecutorBackend。Worker建立一个ExecutorRunner线程,ExecutorRunner会启动ExecutorBackend进程。
四、ExecutorBackend启动后会向Driver的SchedulerBackend注册。SchedulerBackend进程中包含DAGScheduler,它会根据用户程序,生成执行计划,并调度执行。对于每一个stage的task,都会被存放到TaskScheduler中,ExecutorBackend向SchedulerBackend汇报的时候把TaskScheduler中的task调度到ExecutorBackend执行。
五、全部stage都完成后做业结束。
4. Driver运行在客户端
解答:
做业执行流程描述:
一、客户端启动后直接运行用户程序,启动Driver相关的工做:DAGScheduler和BlockManagerMaster等。
二、客户端的Driver向Master注册。
三、Master还会让Worker启动Exeuctor。Worker建立一个ExecutorRunner线程,ExecutorRunner会启动ExecutorBackend进程。
四、ExecutorBackend启动后会向Driver的SchedulerBackend注册。Driver的DAGScheduler解析做业并生成相应的Stage,每一个Stage包含的Task经过TaskScheduler分配给Executor执行。
五、全部stage都完成后做业结束。
5. 的
6. 的
7. 的
8. 的
3.9 Sqoop
1. 命令:
sqoop import --connect jdbc:mysql://192.168.56.204:3306/sqoop --username hive --password hive --table jobinfo --target-dir /sqoop/test7 --inline-lob-limit 16777216 --fields-terminated-by '\t' -m 2
sqoop create-hive-table --connect jdbc:mysql://192.168.56.204:3306/sqoop --table jobinfo --username hive --password hive --hive-table sqtest --fields-terminated-by "\t" --lines-terminated-by "\n";
2. sqoop在导入数据到mysql中,如何让数据不重复导入?若是存在数据问题sqoop如何处理?
解答:
Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,能够将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也能够将HDFS的数据导进到关系型数据库中。
首先需如下要准备:
第一:hadoop的NameNode节点下lib文件夹中要有相应数据库驱动的jar包和sqoop的jar包。
第二:预先在相应的数据库建立Table,注:在HDFS的某个目录上的数据格式要和相应的表中的字段数量一致。
因为我这里使用的是Oracle数据库而且是使用Java来操做的。因此下面的代码以及截图都是以Java的例子:
首先标准化HDFS中文件格式,以下图:
Java代码以下:
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://192.168.115.5:9000");
conf.set("hadoop.job.ugi", "hadooper,hadoopgroup");
conf.set("mapred.job.tracker", "192.168.115.5:9001");
ArrayList<String> list = new ArrayList<String>(); // 定义一个list
list.add("--table");
list.add("A_BAAT_CLIENT"); // Oracle中的表。未来数据要导入到这个表中。
list.add("--export-dir");
list.add("/home/hadoop/traffic/capuse/near7date/activeUser/capuse_near7_activeUser_2013-02-06.log"); // hdfs上的目录。这个目录下的数据要导入到a_baat_client这个表中。
list.add("--connect");
list.add("jdbc:oracle:thin:@10.18.96.107:1521:life"); // Oracle的连接
list.add("--username");
list.add("TRAFFIC"); // Oracle的用户名
list.add("--password");
list.add("TRAFFIC"); // Oracle的密码
list.add("--input-fields-terminated-by");
list.add("|"); // 数据分隔符号
list.add("-m");
list.add("1");// 定义mapreduce的数量。
String[] arg = new String[1];
ExportTool exporter = new ExportTool();
Sqoop sqoop = new Sqoop(exporter);
sqoop.setConf(conf);
arg = list.toArray(new String[0]);
int result = Sqoop.runSqoop(sqoop, arg);
System.out.println("res:" + result); // 打印执行结果。
最后再在Main方法中运行便可,生成后表数据以下图所示:
经过上面的操做以及代码便可在Java中实现把HDFS数据生成对应的表数据;
不过除了能够用Java来实现,使用基本的命令也是能够的,命令以下:
在Hadoop bin目录中:
sqoop export --connect jdbc:oracle:thin:@10.18.96.107:1521:life \
--table A_BAAT_CLIENT --username TRAFFIC --password TRAFFIC \
--input-fields-terminated-by '|' \
--export-dir /home/hadoop/traffic/capuse/near7date/activeUser/test.log -m 1
意思和上面Java中代码同样。
注意:
一、数据库表名、用户名、密码使用大写(这有可能会出现问题,由于我在测试过程当中,使用小写时出现错误,出现No Columns这个经典错误。因此推荐大写,固然这不是必须);
二、预先建好相应的Table;
3. 的
4. 的
5. 的
6. 的
3.10其余
3.10.1 Redis
1. Redis,传统数据库,hbase,hive 每一个之间的区别
解答:
redis:分布式缓存,强调缓存,内存中数据
传统数据库:注重关系
hbase:列式数据库,没法作关系数据库的主外键,用于存储海量数据,底层基于hdfs
hive:数据仓库工具,底层是mapreduce。不是数据库,不能用来作用户的交互存储
2. 是
3.10.2 数据库
1. 反向索引
解答:
倒排索引(Inverted index)
适用范围:搜索引擎,关键字查询
基本原理及要点:为什么叫倒排索引?一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。
以英文为例,下面是要被索引的文本:
T0 = “it is what it is”
T1 = “what is it”
T2 = “it is a banana”
咱们就能获得下面的反向文件索引:
“a”: {2}
“banana”: {2}
“is”: {0, 1, 2}
“it”: {0, 1, 2}
“what”: {0, 1}
检索的条件”what”,”is”和”it”将对应集合的交集。
正向索引开发出来用来存储每一个文档的单词的列表。正向索引的查询每每知足每一个文档有序 频繁的全文查询和每一个单词在校验文档中的验证这样的查询。在正向索引中,文档占据了中心的位置,每一个文档指向了一个它所包含的索引项的序列。也就是说文档指向了它包含的那些单词,而反向索引则是单词指向了包含它的文档,很容易看到这个反向的关系。
2. 数据库的三大范式?
解答:
数据库范式1NF 2NF 3NF BCNF(实例)
设计范式(范式,数据库设计范式,数据库的设计范式)是符合某一种级别的关系模式的集合。构造数据库必须遵循必定的规则。在关系数据库中,这种规则就是范式。关系数据库中的关系必须知足必定的要求,即知足不一样的范式。目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF)和第六范式(6NF)。知足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步知足更多要求的称为第二范式(2NF),其他范式以次类推。通常说来,数据库只需知足第三范式(3NF)就好了。下面咱们举例介绍第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。
在建立一个数据库的过程当中,范化是将其转化为一些表的过程,这种方法能够使从数据库获得的结果更加明确。这样可能使数据库产生重复数据,从而致使建立多余的表。范化是在识别数据库中的数据元素、关系,以及定义所需的表和各表中的项目这些初始工做以后的一个细化的过程。
下面是范化的一个例子 Customer Item purchased Purchase price Thomas Shirt $40 Maria Tennis shoes $35 Evelyn Shirt $40 Pajaro Trousers $25
若是上面这个表用于保存物品的价格,而你想要删除其中的一个顾客,这时你就必须同时删除一个价格。范化就是要解决这个问题,你能够将这个表化为两个表,一个用于存储每一个顾客和他所买物品的信息,另外一个用于存储每件产品和其价格的信息,这样对其中一个表作添加或删除操做就不会影响另外一个表。
关系数据库的几种设计范式介绍
1 第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不知足第一范式(1NF)的数据库就不是关系数据库。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。若是出现重复的属性,就可能须要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。例如,对于图3-2 中的员工信息表,不能将员工信息都放在一列中显示,也不能将其中的两列或多列在一列中显示;员工信息表的每一行只表示一个员工的信息,一个员工的信息在表中只出现一次。简而言之,第一范式就是无重复的列。
2 第二范式(2NF)
第二范式(2NF)是在第一范式(1NF)的基础上创建起来的,即知足第二范式(2NF)必须先知足第一范式(1NF)。第二范式(2NF)要求数据库表中的每一个实例或行必须能够被唯一地区分。为实现区分一般须要为表加上一个列,以存储各个实例的唯一标识。如图3-2 员工信息表中加上了员工编号(emp_id)列,由于每一个员工的员工编号是唯一的,所以每一个员工能够被唯一区分。这个唯一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性彻底依赖于主关键字。所谓彻底依赖是指不能存在仅依赖主关键字一部分的属性,若是存在,那么这个属性和主关键字的这一部分应该分离出来造成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分一般须要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
3 第三范式(3NF)
知足第三范式(3NF)必须先知足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每一个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在图3-2的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。若是不存在部门信息表,则根据第三范式(3NF)也应该构建它,不然就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。
数据库设计三大范式应用实例剖析
数据库的设计范式是数据库设计所须要知足的规范,知足这些规范的数据库是简洁的、结构明晰的,同时,不会发生插入(insert)、删除(delete)和更新(update)操做异常。反之则是乱七八糟,不只给数据库的编程人员制造麻烦,并且面目可憎,可能存储了大量不须要的冗余信息。
设计范式是否是很难懂呢?非也,大学教材上给咱们一堆数学公式咱们固然看不懂,也记不住。因此咱们不少人就根本不按照范式来设计数据库。
实质上,设计范式用很形象、很简洁的话语就能说清楚,道明白。本文将对范式进行通俗地说明,并以笔者曾经设计的一个简单论坛的数据库为例来说解怎样将这些范式应用于实际工程。
范式说明
第一范式(1NF):数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
例如,以下的数据库表是符合第一范式的:
字段1 字段2 字段3 字段4
而这样的数据库表是不符合第一范式的:
字段1 字段2 字段3 字段4
字段3.1 字段3.2
很显然,在当前的任何关系数据库管理系统(DBMS)中,傻瓜也不可能作出不符合第一范式的数据库,由于这些DBMS不容许你把数据库表的一列再分红二列或多列。所以,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的。
第二范式(2NF):数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的状况),也即全部非关键字段都彻底依赖于任意一组候选关键字。
假定选课关系表为SelectCourse(学号, 姓名, 年龄, 课程名称, 成绩, 学分),关键字为组合关键字(学号, 课程名称),由于存在以下决定关系:
(学号, 课程名称) → (姓名, 年龄, 成绩, 学分)
这个数据库表不知足第二范式,由于存在以下决定关系:
(课程名称) → (学分)
(学号) → (姓名, 年龄)
即存在组合关键字中的字段决定非关键字的状况。
因为不符合2NF,这个选课关系表会存在以下问题:
(1) 数据冗余:
同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
(2) 更新异常:
若调整了某门课程的学分,数据表中全部行的"学分"值都要更新,不然会出现同一门课程学分不一样的状况。
(3) 插入异常:
假设要开设一门新的课程,暂时尚未人选修。这样,因为尚未"学号"关键字,课程名称和学分也没法记录入数据库。
(4) 删除异常:
假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。可是,与此同时,课程名称和学分信息也被删除了。很显然,这也会致使插入异常。
把选课关系表SelectCourse改成以下三个表:
学生:Student(学号, 姓名, 年龄);
课程:Course(课程名称, 学分);
选课关系:SelectCourse(学号, 课程名称, 成绩)。
这样的数据库表是符合第二范式的, 消除了数据冗余、更新异常、插入异常和删除异常。
另外,全部单关键字的数据库表都符合第二范式,由于不可能存在组合关键字。
第三范式(3NF):在第二范式的基础上,数据表中若是不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是若是存在"A → B → C"的决定关系,则C传递函数依赖于A。所以,知足第三范式的数据库表应该不存在以下依赖关系:
关键字段 → 非关键字段x → 非关键字段y
假定学生关系表为Student(学号, 姓名, 年龄, 所在学院, 学院地点, 学院电话),关键字为单一关键字"学号",由于存在以下决定关系:
(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)
这个数据库是符合2NF的,可是不符合3NF,由于存在以下决定关系:
(学号) → (所在学院) → (学院地点, 学院电话)
即存在非关键字段"学院地点"、"学院电话"对关键字段"学号"的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的状况,读者可自行分析得知。
把学生关系表分为以下两个表:
学生:(学号, 姓名, 年龄, 所在学院);
学院:(学院, 地点, 电话)。
这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。
鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中若是不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。
假设仓库管理关系表为StorehouseManage(仓库ID, 存储物品ID, 管理员ID, 数量),且有一个管理员只在一个仓库工做;一个仓库能够存储多种物品。这个数据库表中存在以下决定关系:
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
因此,(仓库ID, 存储物品ID)和(管理员ID, 存储物品ID)都是StorehouseManage的候选关键字,表中的惟一非关键字段为数量,它是符合第三范式的。可是,因为存在以下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的状况,因此其不符合BCNF范式。它会出现以下异常状况:
(1) 删除异常:
当仓库被清空后,全部"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。
(2) 插入异常:
当仓库没有存储任何物品时,没法给仓库分配管理员。
(3) 更新异常:
若是仓库换了管理员,则表中全部行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:
仓库管理:StorehouseManage(仓库ID, 管理员ID);
仓库:Storehouse(仓库ID, 存储物品ID, 数量)。
这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。
范式应用
咱们来逐步搞定一个论坛的数据库,有以下信息:
(1) 用户:用户名,email,主页,电话,联系地址
(2) 帖子:发帖标题,发帖内容,回复标题,回复内容
第一次咱们将数据库设计为仅仅存在表:
用户名 email 主页 电话 联系地址 发帖标题 发帖内容 回复标题 回复内容
这个数据库表符合第一范式,可是没有任何一组候选关键字能决定数据库表的整行,惟一的关键字段用户名也不能彻底决定整个元组。咱们须要增长"发帖ID"、"回复ID"字段,即将表修改成:
用户名 email 主页 电话 联系地址 发帖ID 发帖标题 发帖内容 回复ID 回复标题 回复内容
这样数据表中的关键字(用户名,发帖ID,回复ID)能决定整行:
(用户名,发帖ID,回复ID) → (email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)
可是,这样的设计不符合第二范式,由于存在以下决定关系:
(用户名) → (email,主页,电话,联系地址)
(发帖ID) → (发帖标题,发帖内容)
(回复ID) → (回复标题,回复内容)
即非关键字段部分函数依赖于候选关键字段,很明显,这个设计会致使大量的数据冗余和操做异常。
咱们将数据库表分解为(带下划线的为关键字):
(1) 用户信息:用户名,email,主页,电话,联系地址
(2) 帖子信息:发帖ID,标题,内容
(3) 回复信息:回复ID,标题,内容
(4) 发贴:用户名,发帖ID
(5) 回复:发帖ID,回复ID
这样的设计是知足第一、二、3范式和BCNF范式要求的,可是这样的设计是否是最好的呢?
不必定。
观察可知,第4项"发帖"中的"用户名"和"发帖ID"之间是1:N的关系,所以咱们能够把"发帖"合并到第2项的"帖子信息"中;第5项"回复"中的"发帖ID"和"回复ID"之间也是1:N的关系,所以咱们能够把"回复"合并到第3项的"回复信息"中。这样能够必定量地减小数据冗余,新的设计为:
(1) 用户信息:用户名,email,主页,电话,联系地址
(2) 帖子信息:用户名,发帖ID,标题,内容
(3) 回复信息:发帖ID,回复ID,标题,内容
数据库表1显然知足全部范式的要求;
数据库表2中存在非关键字“标题”、“内容”对关键字段“发帖ID”的部分函数依赖,即不知足第二范式的要求,可是这一设计并不会致使数据冗余和操做异常;
数据库表3中也存在非关键字段"标题"、"内容"对关键字段"回复ID"的部分函数依赖,也不知足第二范式的要求,可是与数据库表2类似,这一设计也不会致使数据冗余和操做异常。
由此能够看出,并不必定要强行知足范式的要求,对于1:N关系,当1的一边合并到N的那边后,N的那边就再也不知足第二范式了,可是这种设计反而比较好!
对于M:N的关系,不能将M一边或N一边合并到另外一边去,这样会致使不符合范式要求,同时致使操做异常和数据冗余。
对于1:1的关系,咱们能够将左边的1或者右边的1合并到另外一边去,设计致使不符合范式要求,可是并不会致使操做异常和数据冗余。
3.
4. 是
第4部分 解答题
第4部分
4.1 Hadoop解答题
4.1.1 MapReduce编程题
1. 当前日志采样格式为,请用你最熟悉的语言编写一个 mapreduce,并计算第四列每一个元素出现的个数。
1. a,b,c,d
2. b,b,f,e
3. a,a,c,f
2. 给定 a、b 两个文件,各存放 50 亿个 url,每一个 url 各占 64 字节,内存限制是 4G,让你找出 a、b 文件共同的 url?
解答:
方案 1:将大文件分红可以被内存加载的小文件。
能够估计每一个文件安的大小为 50G×64=320G,远远大于内存限制的 4G。因此不可能将其彻底加载到内存中处理。考虑采起分而治之的方法。
s 遍历文件 a,对每一个 url 求取 ,而后根据所取得的值将 url 分别存储到 1000 个小文件(记为 )中。
这样每一个小文件的大约为 300M。
s 遍历文件 b,采起和 a 相同的方式将 url 分别存储到 1000 各小文件(记为 )。这样处理后,全部可能相同的 url 都在对应的小文件( )中,不对应的小文件不可能有相同的 url。而后咱们只要求出 1000 对小文件中相同的 url 便可。
s 求每对小文件中相同的 url 时,能够把其中一个小文件的 url 存储到 hash_set 中。而后遍历另外一个小文件的每一个 url,看其是否在刚才构建的 hash_set 中,若是是,那么就是共同的 url,存到文件里面就能够了。
方案 2:内存映射成 BIT 最小存储单元。
若是容许有必定的错误率,能够使用 Bloom filter,4G 内存大概能够表示 340 亿 bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit,而后挨个读取另一个文件的url,检查是否与Bloom filter,若是是,那么该 url 应该是共同的 url(注意会有必定的错误率)。
3. 有 10 个文件,每一个文件 1G,每一个文件的每一行存放的都是用户的 query,每一个文件的 query 均可能重复。要求你按照query 的频度排序。
解答:
方案 1:
s 顺序读取 10 个文件,按照 hash(query)%10 的结果将 query 写入到另外 10 个文件(记为 )中。这样新生成的文件每一个的大小大约也 1G(假设 hash 函数是随机的)。
s 找一台内存在 2G 左右的机器,依次对 用 hash_map(query, query_count)来统计每一个 query 出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的 query 和对应的 query_cout 输出到文件中。这样获得了 10 个排好序的文件(记为 )。
s 对 这 10 个文件进行归并排序(内排序与外排序相结合)。
方案 2:
通常 query 的总量是有限的,只是重复的次数比较多而已,可能对于全部的 query,一次性就能够加入到内存了。这样,咱们就能够采用 trie 树/hash_map 等直接来统计每一个 query 出现的次数,而后按出现
次数作快速/堆/归并排序就能够了。
方案 3:
与方案 1 相似,但在作完 hash,分红多个文件后,能够交给多个文件来处理,采用分布式的架构来处
理(好比 MapReduce),最后再进行合并。
//通常在大文件中找出出现频率高的,先把大文件映射成小文件,模 1000,在小文件中找到高频的
4. 有一个 1G 大小的一个文件,里面每一行是一个词,词的大小不超过 16 字节,内存限制大小是 1M。返回频数最高的 100 个词。
解答:
方案 1:顺序读文件中,对于每一个词 x,取 ,而后按照该值存到 5000 个小文件(记为 )中。这样每一个文件大概是 200k 左右。若是其中的有的文件超过了 1M 大小,还能够按照相似的方法继续往下分,知道分解获得的小文件的大小都不超过 1M。 对每一个小文件,统计每一个文件中出现的词以及相应的频率(能够采用 trie 树/hash_map 等),并取出出现频率最大的 100 个词(能够用含 100 个结 点的最小堆),并把 100词及相应的频率存入文件,这样又获得了 5000 个文件。下一步就是把这 5000 个文件进行归并(相似与归并排序)的过程了。
方案2:
1. 将文件逐行读写到另外一个文件中,并将每行单词全变成小写
2. 十六次循环执行,将每行单词按照a-z写到不一样文件里
3. 最后相同的单词都写在了通一个文件里
4. 再将文件读写到各自另外一个文件里,内容是“单词 个数”
5. 定义一个treemap,大小是100,依次插入大的,移除小的
6. 最后得出结果
5. 海量日志数据,提取出某日访问百度次数最多的那个 IP。
解答:
1. 先根据日期在日志文件中提取出ip,根据ip哈希进行分写N个文件。
2. 采用mapreduce的word cont
方案 1:首先是这一天,而且是访问百度的日志中的 IP 取出来,逐个写入到一个大文件中。注意到 IP是 32 位的,最多有 个 IP。一样能够采用映射的方法,好比模 1000,把整个大文件映射为 1000 个小文件,再找出每一个小文中出现频率最大的 IP(能够采用 hash_map 进行频率统计,而后再找出频率最大的几个)及相应的频率。而后再在这 1000 个最大的 IP 中,找出那个频率最大的 IP,即为所求。
6. 在 2.5 亿个整数中找出不重复的整数,内存不足以容纳这 2.5 亿个整数。
解答:
方案 1:采用 2-Bitmap(每一个数分配 2bit,00 表示不存在,01 表示出现一次,10 表示屡次,11 无心义)进 行,共需内存 内存,还能够接受。而后扫描这 2.5 亿个整数,查看 Bitmap 中相对应位,若是是00 变 01,01 变 10,10 保持不变。所描完过后,查看 bitmap,把对应位是 01 的整数输出便可。
方案 2:也可采用上题相似的方法,进行划分小文件的方法。而后在小文件中找出不重复的整数,并排序。而后再进行归并,注意去除重复的元素。
方案3:
1. 将2.5亿个整数重写到一个文件里,内个整数占一行。
2. 进行对半排序重写到新的文件里,这样最后2.5亿个整数在文件里即是有序的了
3. 读取文本,将不重复的写到一个新的文件里便可。
7. 海量数据分布在 100 台电脑中,想个办法高校统计出这批数据的 TOP10。
解答:
方案 1:(方法不正确,取出来得不必定是top10)
s 在每台电脑上求出 TOP10,能够采用包含 10 个元素的堆完成(TOP10 小,用最大堆,TOP10 大,用最小堆)。好比求 TOP10 大,咱们首先取前 10 个元素调整成最小堆,若是发现,而后扫描后面的数据,并与堆顶元素比较,若是比堆顶元素大,那么用该元素替换堆顶,而后再调整为最小堆。最后堆中的元 素就是 TOP10 大。
s 求出每台电脑上的 TOP10 后,而后把这 100 台电脑上的 TOP10 组合起来,共 1000 个数据,再利用上面相似的方法求出 TOP10 就能够了。
8. 怎么在海量数据中找出重复次数最多的一个?
解答:
方案 1:(同上,方法错误)
先作 hash,而后求模映射为小文件,求出每一个小文件中重复次数最多的一个,并记录重复次数。而后找出上一步求出的数据中重复次数最多的一个就是所求(具体参考前面的题)。
正确的方法,先排除
9. 上千万或上亿数据(有重复),统计其中出现次数最多的前 N 个数据。
解答:
10. 1000 万字符串,其中有些是重复的,须要把重复的所有去掉,保留没有重复的字符串。请怎么设计和实现?
解答:
11. 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前 10 个词,请给出思想,给出时间复杂度分析。
解答:
方案 1:这题是考虑时间效率。用 trie 树统计每一个词出现的次数,时间复杂度是 O(n*le)(le 表示单词的平准长 度)。而后是找出出现最频繁的前 10 个词,能够用堆来实现,前面的题中已经讲到了,时间复杂度是 O(n*lg10)。因此总的时间复杂度,是 O(n*le)与 O(n*lg10)中较大的哪个。
12. 一个文本文件,找出前 10 个常常出现的词,但此次文件比较长,说是上亿行或十亿行,总之没法一次读入内存,问最优解。
解答:
13. 100w 个数中找出最大的 100 个数。
解答:
14.
15. D
16. D
17. D
第5部分 处理海量数据问题之六把密匙
第5部分
5.1 密匙1、分而治之/Hash映射 + Hash统计 + 堆/快速/归并排序
一、海量日志数据,提取出某日访问百度次数最多的那个IP。
既然是海量数据处理,那么可想而知,给咱们的数据那就必定是海量的。针对这个数据的海量,咱们如何着手呢?对的,无非就是分而治之/hash映射 + hash统计 + 堆/快速/归并排序,说白了,就是先映射,然后统计,最后排序:
1. 分而治之/hash映射:针对数据太大,内存受限,只能是:把大文件化成(取模映射)小文件,即16字方针:大而化小,各个击破,缩小规模,逐个解决
2. hash统计:当大文件转化了小文件,那么咱们即可以采用常规的hash_map(ip,value)来进行频率统计。
3. 堆/快速排序:统计完了以后,便进行排序(可采起堆排序),获得次数最多的IP。
具体而论,则是: “首先是这一天,而且是访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有个2^32个IP。一样能够采用映射的方 法,好比模1000,把整个大文件映射为1000个小文件,再找出每一个小文中出现频率最大的IP(能够采用hash_map进行频率统计,而后再找出频率 最大的几个)及相应的频率。而后再在这1000个最大的IP中,找出那个频率最大的IP,即为所求。”--十道海量数据处理面试题与十个方法大总结。
注:Hash取模是一种等价映射,不会存在同一个元素分散到不一样小文件中去的状况,即这里采用的是mod1000算法,那么相同的IP在hash后,只可能落在同一个文件中,不可能被分散的。
那到底什么是hash映射呢?我换个角度举个浅显直白的例子,如本文的URL是:http://blog.csdn.net/v_july_v/article/details/7382693,当我把这个URL发表在微博上,便被映射成了:http://t.cn/zOixljh,于此,咱们发现URL自己的长度被缩短了,但这两个URL对应的文章的是同一篇即本文。OK,有兴趣的,还能够再了解下一致性hash算法,见此文第五部分:http://blog.csdn.net/v_july_v/article/details/6879101。
二、搜索引擎会经过日志文件把用户每次检索使用的全部检索串都记录下来,每一个查询串的长度为1-255字节。
假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是1千万,但若是除去重复后,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门),请你统计最热门的10个查询串,要求使用的内存不能超过1G。
由上面第1题,咱们知道,数据大则划为小的,但若是数据规模比较小,能一次性装入内存呢?好比这第2题,虽然有一千万个Query,可是因为重复度比较 高,所以事实上只有300万的Query,每一个Query255Byte,所以咱们能够考虑把他们都放进内存中去,而如今只是须要一个合适的数据结构,在 这里,Hash Table绝对是咱们优先的选择。因此咱们摒弃分而治之/hash映射的方法,直接上hash统计,而后排序。So,
1. hash 统计:先对这批海量数据预处理(维护一个Key为Query字串,Value为该Query出现次数的HashTable,即 hash_map(Query,Value),每次读取一个Query,若是该字串不在Table中,那么加入该字串,而且将Value值设为1;若是该 字串在Table中,那么将该字串的计数加一便可。最终咱们在O(N)的时间复杂度内用Hash表完成了统计;
2. 堆排序:第二步、借助堆 这个数据结构,找出Top K,时间复杂度为N‘logK。即借助堆结构,咱们能够在log量级的时间内查找和调整/移动。所以,维护一个K(该题目中是10)大小的小根堆,而后遍 历300万的Query,分别和根元素进行对比因此,咱们最终的时间复杂度是:O(N) + N'*O(logK),(N为1000万,N’为300万)。
别忘了这篇文章中所述的堆排序思路:“维 护k个元素的最小堆,即用容量为k的最小堆存储最早遍历到的k个数,并假设它们便是最大的k个数,建堆费时O(k),并调整堆(费时O(logk))后, 有k1>k2>...kmin(kmin设为小顶堆中最小元素)。继续遍历数列,每次遍历一个元素x,与堆顶元素比较,若 x>kmin,则更新堆(用时logk),不然不更新堆。这样下来,总费时O(k*logk+(n-k)*logk)=O(n*logk)。此方法 得益于在堆中,查找等各项操做时间复杂度均为logk。”--第三章续、Top K算法问题的实现。
固然,你也能够采用trie树,关键字域存该查询串出现的次数,没有出现为0。最后用10个元素的最小推来对出现频率进行排序。
三、有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。
由上面那两个例题,分而治之 + hash统计 + 堆/快速排序这个套路,咱们已经开始有了屡试不爽的感受。下面,再拿几道再多多验证下。请看此第3题:又是文件很大,又是内存受限,咋办?还能怎么办呢?无非仍是:
1. 分 而治之/hash映射:顺序读文件中,对于每一个词x,取hash(x)%5000,而后按照该值存到5000个小文件(记为 x0,x1,...x4999)中。这样每一个文件大概是200k左右。若是其中的有的文件超过了1M大小,还能够按照相似的方法继续往下分,直到分解获得 的小文件的大小都不超过1M。
2. hash统计:对每一个小文件,采用trie树/hash_map等统计每一个文件中出现的词以及相应的频率。
3. 堆/归并排序:取出出现频率最大的100个词(能够用含100个结点的最小堆),并把100个词及相应的频率存入文件,这样又获得了5000个文件。最后就是把这5000个文件进行归并(相似于归并排序)的过程了。
四、海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。
此题与上面第3题相似,
1. 堆排序:在每台电脑上求出TOP10,能够采用包含10个元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。好比求TOP10大,咱们首先取前10个元素调整成最小堆,若是发现,而后扫描后面的数据,并与堆顶元素比较,若是比堆顶元素大,那么用该元素替换堆顶,而后再调整为最小堆。最后堆中的元素就是TOP10大。
2. 求出每台电脑上的TOP10后,而后把这100台电脑上的TOP10组合起来,共1000个数据,再利用上面相似的方法求出TOP10就能够了。
上述第4题的此解法,经读者反应有问题,如举个例子如好比求2个文件中的top2,照你这种算法,若是第一个文件里有
a 49次
b 50次
c 2次
d 1次
第二个文件里有
a 9次
b 1次
c 11次
d 10次
虽然第 一个文件里出来top2是b(50次),a(49次),第二个文件里出来top2是c(11次),d(10次),而后2个top2:b(50次)a(49 次)与c(11次)d(10次)归并,则算出全部的文件的top2是b(50 次),a(49 次),但其实是a(58 次),b(51 次)。是否真是如此呢?若真如此,那做何解决呢?
正如老梦所述:
首先,先把全部的数据遍历一遍作一次hash(保证相同的数据条目划分到同一台电脑上进行运算),而后根据hash结果从新分布到100台电脑中,接下来的算法按照以前的便可。
最后因为a可能出如今不一样的电脑,各有必定的次数,再对每一个相同条目进行求和(因为上一步骤中hash以后,也方便每台电脑只须要对本身分到的条目内进行求和,不涉及到别的电脑,规模缩小)。
五、有10个文件,每一个文件1G,每一个文件的每一行存放的都是用户的query,每一个文件的query均可能重复。要求你按照query的频度排序。
直接上:
1. hash映射:顺序读取10个文件,按照hash(query)%10的结果将query写入到另外10个文件(记为)中。这样新生成的文件每一个的大小大约也1G(假设hash函数是随机的)。
2. hash统计:找一台内存在2G左右的机器,依次对用hash_map(query, query_count)来统计每一个query出现的次数。注:hash_map(query,query_count)是用来统计每一个query的出现次数,不是存储他们的值,出现一次,则count+1。
3. 堆/快速/归并排序:利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样获得了10个排好序的文件(记为)。对这10个文件进行归并排序(内排序与外排序相结合)。
除此以外,此题还有如下两个方法:
方案2:通常query的总量是有限的,只是重复的次数比较多而已,可能对于全部的query,一次性就能够加入到内存了。这样,咱们就能够采用trie树/hash_map等直接来统计每一个query出现的次数,而后按出现次数作快速/堆/归并排序就能够了。
方案3:与方案1相似,但在作完hash,分红多个文件后,能够交给多个文件来处理,采用分布式的架构来处理(好比MapReduce),最后再进行合并。
六、 给定a、b两个文件,各存放50亿个url,每一个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
能够估计每一个文件安的大小为5G×64=320G,远远大于内存限制的4G。因此不可能将其彻底加载到内存中处理。考虑采起分而治之的方法。
1. 分而治之/hash映射:遍历文件a,对每一个url求取 ,而后根据所取得的值将url分别存储到1000个小文件(记为 )中。这样每一个小文件的大约为300M。遍历文件b,采起和a相同的方式将url分别存储到1000小文件中(记为 )。这样处理后,全部可能相同的url都在对应的小文件( )中,不对应的小文件不可能有相同的url。而后咱们只要求出1000对小文件中相同的url便可。
2. hash统计:求每对小文件中相同的url时,能够把其中一个小文件的url存储到hash_set中。而后遍历另外一个小文件的每一个url,看其是否在刚才构建的hash_set中,若是是,那么就是共同的url,存到文件里面就能够了。
OK,此第一种方法:分而治之/hash映射 + hash统计 + 堆/快速/归并排序,再看最后三道题,以下:
七、怎么在海量数据中找出重复次数最多的一个?
方案1:先作hash,而后求模映射为小文件,求出每一个小文件中重复次数最多的一个,并记录重复次数。而后找出上一步求出的数据中重复次数最多的一个就是所求(具体参考前面的题)。
八、上千万或上亿数据(有重复),统计其中出现次数最多的钱N个数据。
方案1:上千万或上亿的数据,如今的机器的内存应该能存下。因此考虑采用hash_map/搜索二叉树/红黑树等来进行统计次数。而后就是取出前N个出现次数最多的数据了,能够用第2题提到的堆机制完成。
九、一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。
方案1:这题是考虑时间效率。用trie树统计每一个词出现的次数,时间复杂度是O(n*le)(le表示单词的平准长度)。而后是找出出现最频繁的前 10个词,能够用堆来实现,前面的题中已经讲到了,时间复杂度是O(n*lg10)。因此总的时间复杂度,是O(n*le)与O(n*lg10)中较大的 哪个。
接下来,我们来看第二种方法,双层捅划分。
5.2 密匙2、双层桶划分
双层桶划分----其实本质上仍是分而治之的思想,重在“分”的技巧上!
适用范围:第k大,中位数,不重复或重复的数字
基本原理及要点:由于元素范围很大,不能利用直接寻址表,因此经过屡次划分,逐步肯定范围,而后最后在一个能够接受的范围内进行。能够经过屡次缩小,双层只是一个例子。
扩展:
问题实例:
十、2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。
有点像鸽巢原理,整数个数为2^32,也就是,咱们能够将这2^32个数,划分为2^8个区域(好比用单个文件表明一个区域),而后将数据分离到不一样的区域,而后不一样的区域在利用bitmap就能够直接解决了。也就是说只要有足够的磁盘空间,就能够很方便的解决。
十一、5亿个int找它们的中位数。
这个例子比上面那个更明显。首先咱们将int划分为2^16个区域,而后读取数据统计落到各个区域里的数的个数,以后咱们根据统计结果就能够判断中位数 落到那个区域,同时知道这个区域中的第几大数恰好是中位数。而后第二次扫描咱们只统计落在这个区域中的那些数就能够了。
实际上,若是不是 int是int64,咱们能够通过3次这样的划分便可下降到能够接受的程度。便可以先将int64分红2^24个区域,而后肯定区域的第几大数,在将该区 域分红2^20个子区域,而后肯定是子区域的第几大数,而后子区域里的数的个数只有2^20,就能够直接利用direct addr table进行统计了。
5.3 密匙三:Bloom filter/Bitmap
Bloom filter
关于什么是Bloom filter,请参看此文:海量数据处理之Bloom Filter详解。
适用范围:能够用来实现数据字典,进行数据的判重,或者集合求交集
基本原理及要点:
对于原理来讲很简单,位数组+k个独立hash函数。将hash函数对应的值的位数组置1,查找时若是发现全部hash函数对应位都是1说明存在,很明 显这个过程并不保证查找的结果是100%正确的。同时也不支持删除一个已经插入的关键字,由于该关键字对应的位会牵动到其余的关键字。因此一个简单的改进 就是 counting Bloom filter,用一个counter数组代替位数组,就能够支持删除了。
还有一个比较重要的问题,如何 根据输入元素个数n,肯定位数组m的大小及hash函数个数。当hash函数个数k=(ln2)*(m/n)时错误率最小。在错误率不大于E的状况下,m 至少要等于n*lg(1/E)才能表示任意n个元素的集合。但m还应该更大些,由于还要保证bit数组里至少一半为0,则m应该>=nlg(1 /E)*lge 大概就是nlg(1/E)1.44倍(lg表示以2为底的对数)。
举个例子咱们假设错误率为0.01,则此时m应大概是n的13倍。这样k大概是8个。
注意这里m与n的单位不一样,m是bit为单位,而n则是以元素个数为单位(准确的说是不一样元素的个数)。一般单个元素的长度都是有不少bit的。因此使用bloom filter内存上一般都是节省的。
扩展:
Bloom filter将集合中的元素映射到位数组中,用k(k为哈希函数个数)个映射位是否全1表示元素在不在这个集合中。Counting bloom filter(CBF)将位数组中的每一位扩展为一个counter,从而支持了元素的删除操做。Spectral Bloom Filter(SBF)将其与集合元素的出现次数关联。SBF采用counter中的最小值来近似表示元素的出现频率。
十二、给你A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL。若是是三个乃至n个文件呢?
根据这个问题咱们来计算下内存的占用,4G=2^32大概是40亿*8大概是340亿,n=50亿,若是按出错率0.01算须要的大概是650亿个 bit。如今可用的是340亿,相差并很少,这样可能会使出错率上升些。另外若是这些urlip是一一对应的,就能够转换成ip,则大大简单了。
同时,上文的第5题:给定a、b两个文件,各存放50亿个url,每一个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?若是容许有 必定的错误率,能够使用Bloom filter,4G内存大概能够表示340亿bit。将其中一个文件中的url使用Bloom filter映射为这340亿bit,而后挨个读取另一个文件的url,检查是否与Bloom filter,若是是,那么该url应该是共同的url(注意会有必定的错误率)。
Bitmap
至于什么是Bitmap,请看此文:http://blog.csdn.net/v_july_v/article/details/6685962。下面关于Bitmap的应用,直接上题,以下第九、10道:
1三、在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。
方案1:采用2-Bitmap(每一个数分配2bit,00表示不存在,01表示出现一次,10表示屡次,11无心义)进行,共需内存2^32 * 2 bit=1 GB内存,还能够接受。而后扫描这2.5亿个整数,查看Bitmap中相对应位,若是是00变01,01变10,10保持不变。所描完过后,查看 bitmap,把对应位是01的整数输出便可。
方案2:也可采用与第1题相似的方法,进行划分小文件的方法。而后在小文件中找出不重复的整数,并排序。而后再进行归并,注意去除重复的元素。
1四、腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,而后再给一个数,如何快速判断这个数是否在那40亿个数当中?
方案1:frome oo,用位图/Bitmap的方法,申请512M的内存,一个bit位表明一个unsigned int值。读入40亿个数,设置相应的bit位,读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。
5.4 密匙4、Trie树/数据库/倒排索引
Trie树
适用范围:数据量大,重复多,可是数据种类小能够放入内存
基本原理及要点:实现方式,节点孩子的表示方式
扩展:压缩实现。
问题实例:
1. 有10个文件,每一个文件1G,每一个文件的每一行都存放的是用户的query,每一个文件的query均可能重复。要你按照query的频度排序。
2. 1000万字符串,其中有些是相同的(重复),须要把重复的所有去掉,保留没有重复的字符串。请问怎么设计和实现?
3. 寻找热门查询:查询串的重复度比较高,虽然总数是1千万,但若是除去重复后,不超过3百万个,每一个不超过255字节。
4. 上面的第8题:一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词。其解决方法是:用trie树统计每一个词出现的次数,时间复杂度是O(n*le)(le表示单词的平准长度),而后是找出出现最频繁的前10个词。
更多有关Trie树的介绍,请参见此文:从Trie树(字典树)谈到后缀树。
数据库索引
适用范围:大数据量的增删改查
基本原理及要点:利用数据的设计实现方法,对海量数据的增删改查进行处理。
关于数据库索引及其优化,更多可参见此文:http://www.cnblogs.com/pkuoliver/archive/2011/08/17/mass-data-topic-7-index-and-optimize.html。同时,关于MySQL索引背后的数据结构及算法原理,这里还有一篇很好的文章:http://www.codinglabs.org/html/theory-of-mysql-index.html。
倒排索引(Inverted index)
适用范围:搜索引擎,关键字查询
基本原理及要点:为什么叫倒排索引?一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。
以英文为例,下面是要被索引的文本:
T0 = "it is what it is"
T1 = "what is it"
T2 = "it is a banana"
咱们就能获得下面的反向文件索引:
"a": {2}
"banana": {2}
"is": {0, 1, 2}
"it": {0, 1, 2}
"what": {0, 1}
检索的条件"what","is"和"it"将对应集合的交集。
正向索引开发出来用来存储每一个文档的单词的列表。正向索引的查询每每知足每一个文档有序频繁的全文查询和每一个单词在校验文档中的验证这样的查询。在正向索 引中,文档占据了中心的位置,每一个文档指向了一个它所包含的索引项的序列。也就是说文档指向了它包含的那些单词,而反向索引则是单词指向了包含它的文档, 很容易看到这个反向的关系。
扩展:
问题实例:文档检索系统,查询那些文件包含了某单词,好比常见的学术论文的关键字搜索。
关于倒排索引的应用,更多请参见:第二十3、四章:杨氏矩阵查找,倒排索引关键词Hash不重复编码实践,及第二十六章:基于给定的文档生成倒排索引的编码与实践。
5.5 密匙5、外排序
适用范围:大数据的排序,去重
基本原理及要点:外排序的归并方法,置换选择败者树原理,最优归并树
扩展:
问题实例:
1).有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16个字节,内存限制大小是1M。返回频数最高的100个词。
这个数据具备很明显的特色,词的大小为16个字节,可是内存只有1M作hash明显不够,因此能够用来排序。内存能够当输入缓冲区使用。
关于多路归并算法及外排序的具体应用场景,请参见此文:第十章、如何给10^7个数据量的磁盘文件排序。
5.6 密匙6、分布式处理之Mapreduce
适用范围:数据量大,可是数据种类小能够放入内存
基本原理及要点:将数据交给不一样的机器去处理,数据划分,结果归约。
扩展:
问题实例:
1. The canonical example application of MapReduce is a process to count the appearances of each different word in a set of documents:
2. 海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。
3. 一共有N个机器,每一个机器上有N个数。每一个机器最多存O(N)个数并对它们操做。如何找到N^2个数的中数(median)?
更多具体阐述请参见:从Hadhoop框架与MapReduce模式中谈海量数据处理,及MapReduce技术的初步了解与学习。
的
18.
19. 的
第6部分 设计题
5.7 日志收集分析系统
1. 日志分布在各个业务系统中,咱们须要对当天的日志进行实时汇总统计,同时又能离线查询历史的汇总数据(PV、UV、IP)
解答:
一、经过flume将不一样系统的日志收集到kafka中
二、经过storm实时的处理PV、UV、IP
三、经过kafka的consumer将日志生产到hbase中。
四、经过离线的mapreduce或者hive,处理hbase中的数据
2. Hive语言实现word count
解答:
1.建表
2.分组(group by)统计wordcount
select word,count(1) from table1 group by word;
3. 实时数据统计会用到哪些技术,他们各自的应用场景及区别是什么?
解答:
flume:日志收集系统,主要用于系统日志的收集
kafka:消息队列,进行消息的缓存和系统的解耦
storm:实时计算框架,进行流式的计算。
4. 的
5. 的
6. 的
5.8 MapReduce
1. 有两个文本文件,文件中的数据按行存放,请编写MapReduce程序,找到两个文件中彼此不相同的行(写出思路便可)
解答:
写个mapreduce链 用依赖关系,一共三个mapreduce,第一个处理第一个文件,第二个处理第二个文件,第三个处理前两个的输出结果,第一个mapreduce将文件去重,第二个mapreduce也将文件去重,第三个作wordcount,wordcount为1的结果就是不一样的
2. 共同朋友
1. A B CD E F
2. B A CD E
3. C A B E
4. D B E
5. E A BC D
6. F A
第一个字母表示本人,其余事他的朋友,找出有共同朋友的人,和共同的朋友是谁
解答:
思路:例如A,他的朋友是B\C\D\E\F\,那么BC的共同朋友就是A。因此将BC做为key,将A做为value,在map端输出便可!其余的朋友循环处理。
import java.io.IOException;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
10. import org.apache.hadoop.mapreduce.Mapper;
11. import org.apache.hadoop.mapreduce.Reducer;
12. import org.apache.hadoop.mapreduce.Mapper.Context;
13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
15. import org.apache.hadoop.util.GenericOptionsParser;
public class FindFriend {
public static class ChangeMapper extends Mapper<Object, Text, Text,
Text>{
@Override
public void map(Object key, Text value, Context context) throws
IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
Text owner = new Text();
Set<String> set = new TreeSet<String>();
owner.set(itr.nextToken());
while (itr.hasMoreTokens()) {
set.add(itr.nextToken());
}
String[] friends = new String[set.size()];
friends = set.toArray(friends);
for(int i=0;i<friends.length;i++){
for(int j=i+1;j<friends.length;j++){
String outputkey = friends[i]+friends[j];
context.write(new Text(outputkey),owner);
}
}
}
}
public static class FindReducer extends Reducer<Text,Text,Text,Text>
{
public void reduce(Text key, Iterable<Text> values,
Context context) throws IOException,
InterruptedException {
String commonfriends ="";
for (Text val : values) {
if(commonfriends == ""){
commonfriends = val.toString();
}else{
commonfriends =
commonfriends+":"+val.toString();
}
}
context.write(key, new
Text(commonfriends));
}
}
public static void main(String[] args) throws IOException,
InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length < 2) {
System.err.println("args error");
System.exit(2);
}
Job job = new Job(conf, "word count");
job.setJarByClass(FindFriend.class);
job.setMapperClass(ChangeMapper.class);
job.setCombinerClass(FindReducer.class);
job.setReducerClass(FindReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
for (int i = 0; i < otherArgs.length - 1; ++i) {
FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
}
FileOutputFormat.setOutputPath(job,
new Path(otherArgs[otherArgs.length - 1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
结果:
1. AB E:C:D
2. AC E:B
3. AD B:E
4. AE C:B:D
5. BC A:E
6. BD A:E
7. BE C:D:A
8. BF A
9. CD E:A:B
10. CE A:B
11. CF A
12. DE B:A
13. DF A
14. EF A
3. 的
4. 的
5. 的
6. 的
5.9 优化
1. 若是要存储海量的小文件(大小都是几百K-几M)请简述本身的设计方案
解答:
1.将小文件打成har文件存储
2.将小文件序列化到hdfs中
2.
3. 的
第7部分 涉及Java基础部分
1. ArrayList、Vector、LinkedList的区别及其优缺点?HashMap、HashTable的区别及优缺点?
解答:
ArrayList 和Vector是采用数组方式存储数据的,是根据索引来访问元素的,均可以根据须要自动扩展内部数据长度,以便增长和插入元素,都容许直接序号索引元素,可是插入数据要涉及到数组元素移动等内存操做,因此索引数据快插入数据慢,他们最大的区别就是synchronized同步的使用。
LinkedList使用双向链表实现存储,按序号索引数据须要进行向前或向后遍历,可是插入数据时只须要记录本项的先后项便可,因此插入数度较快!
若是只是查找特定位置的元素或只在集合的末端增长、移除元素,那么使用Vector或ArrayList均可以。若是是对其它指定位置的插入、删除操做,最好选择LinkedList
HashMap、HashTable的区别及其优缺点:
HashTable 中的方法是同步的 HashMap的方法在缺省状况下是非同步的 所以在多线程环境下须要作额外的同步机制。
HashTable不容许有null值 key和value都不容许,而HashMap容许有null值 key和value都容许 所以HashMap 使用containKey()来判断是否存在某个键。
HashTable 使用Enumeration ,而HashMap使用iterator。
Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类。
2. 的
3. 的
第8部分 十道海量数据处理面试题
第6部分
第7部分
第8部分
8.1 海量日志数据,提取出某日访问百度次数最多的那个 IP 。
此题,在我以前的一篇文章算法里头有所提到,当时给出的方案是:IP 的数目仍是有限的,最多 2^32个,因此能够考虑使用 hash 将 ip 直接存入内存,而后进行统计。再详细介绍下此方案:首先是这一天,而且是访问百度的日志中的 IP 取出来,逐个写入到一个大文件中。注意到 IP 是 32 位的,最多有个 2^32 个 IP。一样能够采用映射的方法,好比模 1000,把整个大文件映射为 1000 个小文件,再找出每一个小文中出现频率最大的 IP(能够采用 hash_map 进行频率统计,而后再找出频率最大的几个)及相应的频率。而后再在这 1000 个最大的 IP 中,找出那个频率最大的 IP,即为所求。
8.2 2 、搜 索引擎会经过日志文件把用户每次检索使用的全部检索串都记录下来,每一个查询串的长度为1-255 字节。假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是 1 千万,但若是除去重复后,不超过 3 百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的10 个查询串,要求使用的内存不能超过 1G。
典型的 Top K 算法,仍是在这篇文章里头有所阐述。文中,给出的最终算法是:第一步、先对这批海量数据预处理,在 O(N)的时间内用 Hash 表完成排序;而后,第二步、借助堆这个数据结构,找出 TopK,时间复杂度为 N‗logK。即,借助堆结构,咱们能够在 log 量级的时间内查找和调整/移动。所以,维护一个 K(该题目中是 10)大小的小根堆,而后遍历 300 万的 Query,分别和根元素进行对比因此,咱们最终的时间复杂度是:O(N) + N'*O(logK),(N 为 1000 万,N‘为 300 万)。ok,更多,详情,请参考原文。或者:采用 trie 树,关键字域存该查询串出现的次数,没有出现为 0。最后用 10 个元素的最小推来对出现频率进行排序。
8.3 有一个 1G 过 大小的一个文件,里面每一行是一个词,词的大小不超过 16 字节,内存限制大小是
1M 。返回频数最高的 100 个词。方案:顺序读文件中,对于每一个词 x,取 hash(x)%5000,而后按照该值存到 5000 个小文件(记为
www.aboutyun.com
x0,x1,...x4999)中。这样每一个文件大概是 200k 左右。若是其中的有的文件超过了 1M 大小,还能够按照相似的方法继续往下分,直到分解获得的小文件的大小都不超过 1M。 对每一个小文件,统计每一个文件中出现的词以及相应的频率(能够采用 trie 树/hash_map等),并取出出现频率最大的 100 个词(能够用含 100 个结点的最小堆),并把 100 个词及相应的频率存入文件,这样又获得了 5000个文件。下一步就是把这 5000 个文件进行归并(相似与归并排序)的过程了。
8.4 4 有 10 个文件 件,每一个文件 1G ,每一个文件的每一行存放的都是用户的 query ,每一个文件的 query照 均可能重复。
要求你按照 query 的频度排序。仍是典型的 TOP K 算法,解决方案以下:
方案 1:顺序读取 10 个文件,按照 hash(query)%10 的结果将 query 写入到另外 10 个文件(记为)中。这样新生成的文件每一个的大小大约也 1G(假设 hash 函数是随机的)。找一台内存在 2G 左右的机器,依次对用 hash_map(query, query_count)来统计每一个 query 出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query 和对应的 query_cout 输出到文件中。这样获得了 10 个排好序的文件(记为)。对这 10 个文件进行归并排序(内排序与外排序相结合)。
方案 2:通常 query 的总量是有限的,只是重复的次数比较多而已,可能对于全部的 query,一次性就能够加入到内存了。这样,咱们就能够采用trie 树/hash_map 等直接来统计每一个 query 出现的次数,而后按出现次数作快速/堆/归并排序就能够了。
方案 3:与方案 1 相似,但在作完 hash,分红多个文件后,能够交给多个文件来处理,采用分布式的架构来处理(好比 MapReduce),最后再进行合并。
8.5 五、 给定 a、、b 两个文件,各存放50 亿个 url ,每一个 url 各占 64 字节,内存限制是 4G ,让你找出 a 、b 文件共同的 url ?
方案 1:能够估计每一个文件安的大小为 5G×64=320G,远远大于内存限制的 4G。因此不可能将其彻底
加载到内存中处理。考虑采起分而治之的方法。
遍历文件 a,对每一个 url 求取 hash(url)%1000,而后根据所取得的值将 url 分别存储到 1000 个小文件
(记为 a0,a1,...,a999)中。这样每一个小文件的大约为 300M。
遍历文件 b,采起和 a 相同的方式将 url 分别存储到 1000 小文件(记为 b0,b1,...,b999)。这样处理后,
全部可能相同的 url 都在对应的小文件(a0vsb0,a1vsb1,...,a999vsb999)中,不对应的小文件不可能有相
www.aboutyun.com
同的 url。而后咱们只要求出 1000 对小文件中相同的 url 便可。
求每对小文件中相同的 url 时,能够把其中一个小文件的 url 存储到 hash_set 中。而后遍历另外一个小
文件的每一个 url,看其是否在刚才构建的 hash_set 中,若是是,那么就是共同的url,存到文件里面就能够
了。
方案 2:若是容许有必定的错误率,能够使用 Bloom filter,4G 内存大概能够表示 340 亿 bit。将其中
一个文件中的url使用Bloom filter映射为这340亿bit,而后挨个读取另一个文件的url,检查是否与Bloom
filter,若是是,那么该 url 应该是共同的 url(注意会有必定的错误率)。
Bloom filter 往后会在本 BLOG 内详细阐述。
8.6 在 2.5 亿个整数中找出不重复的整数,注,内存不足以容纳这 2.5 亿个整数。
方案 1:采用 2-Bitmap(每一个数分配 2bit,00 表示不存在,01 表示出现一次,10 表示屡次,11 无心
义)进行,共需内存内存,还能够接受。而后扫描这2.5 亿个整数,查看 Bitmap 中相对应位,若是是 00
变 01,01 变 10,10 保持不变。所描完过后,查看 bitmap,把对应位是 01 的整数输出便可。
方案 2:也可采用与第 1 题相似的方法,进行划分小文件的方法。而后在小文件中找出不重复的整数,
并排序。而后再进行归并,注意去除重复的元素。
8.7 腾讯面试题:给 40 亿个不重复的 unsigned int 的整数,没排过序的,而后再给一个数,如何快那速判断这个数是否在那 40 亿个数当中?
与上第 6 题相似,个人第一反应时快速排序+二分查找。如下是其它更好的方法: 方案 1:oo,申请
512M 的内存,一个 bit 位表明一个 unsigned int 值。读入 40 亿个数,设置相应的 bit 位,读入要查询的数,
查看相应 bit 位是否为 1,为 1 表示存在,为 0 表示不存在。
dizengrong: 方案 2:这个问题在《编程珠玑》里有很好的描述,你们能够参考下面的思路,探讨一
下:又由于 2^32 为 40 亿多,因此给定一个数可能在,也可能不在其中;这里咱们把 40 亿个数中的每一
个用 32 位的二进制来表示假设这 40 亿个数开始放在一个文件中。
而后将这 40 亿个数分红两类: 1.最高位为 0 2.最高位为 1 并将这两类分别写入到两个文件中,其中一
个文件中数的个数<=20 亿,而另外一个>=20 亿(这至关于折半了);与要查找的数的最高位比较并接着进
入相应的文件再查找
再而后把这个文件为又分红两类: 1.次最高位为 0 2.次最高位为 1
并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10 亿,而另外一个>=10 亿(这至关于
折半了); 与要查找的数的次最高位比较并接着进入相应的文件再查找。 ....... 以此类推,就能够找到了,
并且时间复杂度为 O(logn),方案 2 完。
附:这里,再简单介绍下,位图方法: 使用位图法判断整形数组是否存在重复判断集合中存在重复
是常见编程任务之一,当集合中数据量比较大时咱们一般但愿少进行几回扫描,这时双重循环法就不可取
了。
位图法比较适合于这种状况,它的作法是按照集合中最大元素max建立一个长度为max+1的新数组,
而后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到 5 就给新数组的第六个元素置 1,这样下
次再遇到 5 想置位时发现新数组的第六个元素已是 1 了,这说明此次的数据确定和之前的数据存在着重
复。这种给新数组初始化时置零其后置一的作法相似于位图的处理方法故称位图法。它的运算次数最坏的
状况为 2N。若是已知数组的最大值即能事先给新数组定长的话效率还能提升一倍。
8.8 8 、怎么在海量数据中找出重复次数最多的一个?
方案 1:先作 hash,而后求模映射为小文件,求出每一个小文件中重复次数最多的一个,并记录重复次数。
而后找出上一步求出的数据中重复次数最多的一个就是所求(具体参考前面的题)。
8.9 9 、上千万或上亿数据(有重复),统计其中出现次数最多的钱 N 个数据。
方案 1:上千万或上亿的数据,如今的机器的内存应该能存下。因此考虑采用 hash_map/搜索二叉树/红黑树等来进行统计次数。而后就是取出前 N 个出现次数最多的数据了,能够用第 2 题提到的堆机制完成。
8.1010 、一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10 个词,请给出
思想,给出时间复杂度分析。
方案 1:
这题是考虑时间效率。用 trie 树统计每一个词出现的次数,时间复杂度是O(n*le)(le 表示单词的平准长度)。而后是找出出现最频繁的前 10 个词,能够用堆来实现,前面的题中已经讲到了,时间复杂度是 O(n*lg10)。因此总的时间复杂度,是O(n*le)与 O(n*lg10)中较大的哪个。附、100w 个数中找出最大的 100 个数。
方案1:
在前面的题中,咱们已经提到了,用一个含100个元素的最小堆完成。复杂度为O(100w*lg100)。
方案 2:
采用快速排序的思想,每次分割以后只考虑比轴大的一部分,知道比轴大的一部分在比 100多的时候,采用传统排序算法排序,取前 100 个。复杂度为 O(100w*100)。
方案 3:
采用局部淘汰法。选取前 100 个元素,并排序,记为序列 L。而后一次扫描剩余的元素 x,与排好序的 100 个元素中最小的元素比,若是比这个最小的要大,那么把这个最小的元素删除,并把 x 利用插入排序的思想,插入到序列 L 中。依次循环,知道扫描了全部的元素。复杂度为 O(100w*100)。
第9部分 遗留
3十一、在线安装ssh的命令以及文件解压的命令?
3十二、把公钥都追加到受权文件的命令?该命令是否在root用户下执行?
31三、HadoopHA集群中,各个服务的启动和关闭的顺序?
31四、HDFS中的block块默认保存几份?默认大小多少?
31五、NameNode中的meta数据是存放在NameNode自身,仍是DataNode等其余节点?DatNOde节点自身是否有Meta数据存在?
31六、下列那个程序一般与NameNode在一个节点启动?
31七、下面那个程序负责HDFS数据存储?
31八、 在HadoopHA集群中,简述Zookeeper的主要做用,以及启动和查看状态的命令?
31九、HBase在进行模型设计时重点在什么地方?一张表中国定义多少个Column Family最合适?为何?
320、如何提升HBase客户端的读写性能?请举例说明。
32一、基于HadoopHA集群进行MapReduce开发时,Configuration如何设置hbase.zookeeper,quorum属性的值?
32二、 在hadoop开发过程当中使用过哪些算法?其应用场景是什么?
32三、MapReduce程序如何发布?若是MapReduce中涉及到了第三方的jar包,该如何处理?
32四、在实际工做中使用过哪些集群的运维工具,请分别阐述其做用。
32五、hadoop中combiner的做用?
32六、IO的原理,IO模型有几种?
32七、Windows用什么样的模型,Linux用什么样的模型?
32八、一台机器如何应对那么多的请求访问,高并发到底怎么实现,一个请求怎么产生的,
在服务端怎么处理的,最后怎么返回给用户的,整个的环节操做系统是怎么控制的?
32九、hdfs的client端,复制到第三个副本时宕机,hdfs怎么恢复保证下次写第三副本?block块信息是先写dataNode仍是先写nameNode?
330、快排现场写程序实现?
33一、jvm的内存是怎么分配原理?
33二、毒酒问题---1000桶酒,其中1桶有毒。而一旦吃了,毒性会在1周后发做。问最少须要多少只老鼠可在一周内找出毒酒?
33三、用栈实现队列?
33四、链表倒序实现?
33五、多线程模型怎样(生产,消费者)?平时并发多线程都用哪些实现方式?
33六、synchonized是同步悲观锁吗?互斥?怎么写同步提升效率?
33七、4亿个数字,找出哪些重复的,要用最小的比较次数,写程序实现。
33八、java是传值仍是传址?
33九、 java处理多线程,另外一线程一直等待?
340、一个网络商城1天大概产生多少G的日志?
34一、大概有多少条日志记录(在不清洗的状况下)?
34二、日访问量大概有多少个?
34三、注册数大概多少?
34四、咱们的日志是否是除了apache的访问日志是否是还有其余的日志?
34五、假设咱们有其余的日志是否是能够对这个日志有其余的业务分析?这些业务分析都有什么?
34六、问:大家的服务器有多少台?
34七、问:大家服务器的内存多大?
34八、问:大家的服务器怎么分布的?(这里说地理位置分布,最好也从机架方面也谈谈)
34九、问:你日常在公司都干些什么(一些建议)
350、hbase怎么预分区?
35一、hbase怎么给web前台提供接口来访问(HTABLE能够提供对HTABLE的访问,可是怎么查询同一条记录的多个版本数据)?
35二、.htable API有没有线程安全问题,在程序中是单例仍是多例?
35三、咱们的hbase大概在公司业务中(主要是网上商城)大概都几个表,几个表簇,大概都存什么样的数据?
35四、hbase的并发问题?
Storm问题:
35五、metaq消息队列 zookeeper集群 storm集群(包括zeromq,jzmq,和storm自己)就能够完成对商城推荐系统功能吗?还有没有其余的中间件?
35六、storm怎么完成对单词的计数?(我的看完storm一直都认为他是流处理,好像没有积攒数据的能力,都是处理完以后直接分发给下一个组件)
35七、storm其余的一些面试常常问的问题?
二十3、面试题(18道):
35八、大家的集群规模?
开发集群:10台(8台可用)8核cpu
35九、大家的数据是用什么导入到数据库的?导入到什么数据库?
处理以前的导入:经过hadoop命令导入到hdfs文件系统
处理完成以后的导出:利用hive处理完成以后的数据,经过sqoop导出到mysql数据库中,以供报表层使用。
360、大家业务数据量多大?有多少行数据?(面试了三家,都问这个问题)
开发时使用的是部分数据,不是全量数据,有将近一亿行(八、9千万,具体不详,通常开发中也没人会特别关心这个问题)
36一、大家处理数据是直接读数据库的数据仍是读文本数据?
将日志数据导入到hdfs以后进行处理
36二、大家写hive的hql语句,大概有多少条?
不清楚,我本身写的时候也没有作过统计
36三、大家提交的job任务大概有多少个?这些job执行完大概用多少时间?(面试了三家,都问这个问题)
没统计过,加上测试的,会与不少
36四、hive跟hbase的区别是?
36五、你在项目中主要的工做任务是?
利用hive分析数据
36六、你在项目中遇到了哪些难题,是怎么解决的?
某些任务执行时间过长,且失败率太高,检查日志后发现没有执行完就失败,缘由出在hadoop的job的timeout太短(相对于集群的能力来讲),设置长一点便可
36七、你本身写过udf函数么?写了哪些?
这个我没有写过
36八、你的项目提交到job的时候数据量有多大?(面试了三家,都问这个问题)
不清楚是要问什么
36九、reduce后输出的数据量有多大?
370、一个网络商城1天大概产生多少G的日志? 4tb
37一、大概有多少条日志记录(在不清洗的状况下)? 7-8百万条
37二、日访问量大概有多少个?百万
37三、注册数大概多少?不清楚几十万吧
37四、咱们的日志是否是除了apache的访问日志是否是还有其余的日志?关注信息
37五、假设咱们有其余的日志是否是能够对这个日志有其余的业务分析?这些业务分析都有什么?
二十4、面试题(1道):
37六、有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。
请用5分钟时间,找出重复出现最多的前10条。
分析:
常规方法是先排序,在遍历一次,找出重复最多的前10条。可是排序的算法复杂度最低为nlgn。
能够设计一个hash_table,hash_map<string, int>,依次读取一千万条短信,加载到hash_table表中,而且统计重复的次数,与此同时维护一张最多10条的短信表。
这样遍历一次就能找出最多的前10条,算法复杂度为O(n)。
二十5、面试题(5道):
37七、job的运行流程(提交一个job的流程)?
37八、Hadoop生态圈中各类框架的运用场景?
37九、hive中的压缩格式RCFile、TextFile、SequenceFile各有什么区别?
以上3种格式同样大的文件哪一个占用空间大小.还有Hadoop中的一个HA压缩。
380、假如:Flume收集到的数据不少个小文件,我须要写MR处理时将这些文件合并
(是在MR中进行优化,不让一个小文件一个MapReduce)
他们公司主要作的是中国电信的流量计费为主,专门写MR。
38三、解释“hadoop”和“hadoop生态系统”两个概念。
38四、说明Hadoop 2.0的基本构成。
38五、相比于HDFS1.0, HDFS 2.0最主要的改进在哪几方面?
38六、试使用“步骤1,步骤2,步骤3…..”说明YARN中运行应用程序的基本流程。
38七、“MapReduce 2.0”与“YARN”是否等同,尝试解释说明。
38八、MapReduce 2.0中,MRAppMaster主要做用是什么,MRAppMaster如何实现任务容错的?
38九、为何会产生yarn,它解决了什么问题,有什么优点?
39七、Hadoop体系结构(HDFS与MapReduce的体系结构)、Hadoop相比传统数据存储方式(好比mysql)的优点?
39八、Hadoop集群的搭建步骤、Hadoop集群搭建过程当中碰到了哪些常见问题(好比datanode没有起来)、Hadoop集群管理(如何动态增长和卸载节点、safe mode是什么、经常使用的命令kill等)?
39九、HDFS的namenode与secondarynamenode的工做原理(重点是日志拉取和合并过程)、hadoop 1.x的HDFS的HA方案(namenode挂掉的状况如何处理、datanode挂掉的状况如何处理)?
400、HDFS的经常使用shell命令有哪些?分别对应哪些Client Java API?:显示文件列表、建立目录、文件上传与下载、文件内容查看、删除文件
40一、HDFS的文件上传与下载底层工做原理(或HDFS部分源码分析):FileSystem的create()和open()方法源码分析?
40二、MapReduce计算模型、MapReduce基础知识点(MapReduce新旧API的使用、在linux命令行运行MapReduce程序、自定义Hadoop数据类型)?
40三、MapReduce执行流程:“天龙八步”,计数器、自定义分区、自定义排序、自定义分组、如何对value进行排序:次排序+自定义分组、归约?
40四、MapReduce的shuffle工做原理、MapReduce工做原理(MapReduce源码、InputStream源码、waitForCompletion()源码)、jobtracker如何建立map任务和reduce任务是面试的重点。
40五、MapReduce进阶知识:Hadoop的几种文件格式、常见输入输出格式化类、多输入多输出机制、MapReduce的常见算法(各类join原理和优缺点、次排序和总排序)?
40六、MapReduce性能优化(shuffle调优、压缩算法、更换调度器、设置InputSplit大小减小map任务数量、map和reduce的slot如何设置、数据倾斜原理和如何解决)?
40七、HBase的体系结构和搭建步骤、shell命令与Java API、HBase做为MapReduce的输入输出源、高级JavaAPI、工做原理(重点是combine和split原理)、行键设计原则、性能优化?
40八、Hive的工做原理、两种元数据存放方式、几种表之间的区别、数据导入的几种方式、几种文件格式、UDF函数、性能调优(重点是join的时候如何放置大小表)?
40九、Zookeeper、Flume、Pig、Sqoop的基本概念和使用方式,ZooKeeper被问到过其如何维护高可用(若是某个节点挂掉了它的处理机制)?
4十、Hadoop2:体系结构、HDFS HA、YARN?
4十一、关系型数据库和非关系型数据库的区别?
提示:
关系型数据库经过外键关联来创建表与表之间的关系,非关系型数据库一般指数据以对象的形式存储在数据库中,而对象之间的关系经过每一个对象自身的属性来决定。
对数据库高并发读写、高可扩展性和高可用性的需求,对海量数据的高效率存储和访问的需求,存储的结构不同,非关系数据库是列式存储,在存储结构上更加自由。
4十二、hive的两张表关联,使用mapreduce是怎么写的?
提示:打标记笛卡尔乘积
41三、hive相对于Oracle来讲有那些优势?
提示:
hive是数据仓库,oracle是数据库,hive可以存储海量数据,hive还有更重要的做用就是数据分析,最主要的是免费。
41四、如今咱们要对Oracle和HBase中的某些表进行更新,你是怎么操做?
提示:
disable '表名'
alter '代表', NAME => '列名', VERSIONS=>3
enable '表名'
41五、HBase接收数据,若是短期导入数量过多的话就会被锁,该怎么办? 集群数16台 ,高可用性的环境。
参考:
经过调用HTable.setAutoFlush(false)方法能够将HTable写客户端的自动flush关闭,这样能够批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存时,才实际向HBase服务端发起写请求。默认状况下auto flush是开启的。
41六、说说大家作的hadoop项目流程?
41七、大家公司的服务器架构是怎么样的(分别说下web跟hadoop)?
41八、假若有1000W用户同时访问同一个页面,怎么处理?
提示:优化代码、静态化页面、增长缓存机制、数据库集群、库表散列。。。
41九、怎样将mysql的数据导入到hbase中?不能使用sqoop,速度太慢了
提示:
A、一种能够加快批量写入速度的方法是经过预先建立一些空的regions,这样当数据写入HBase时,会按照region分区状况,在集群内作数据的负载均衡。
B、hbase里面有这样一个hfileoutputformat类,他的实现能够将数据转换成hfile格式,经过new 一个这个类,进行相关配置,这样会在hdfs下面产生一个文件,这个时候利用hbase提供的jruby的loadtable.rb脚本就能够进行批量导入。
420、在hadoop组中你主要负责那部分?
提示:负责编写mapreduce程序,各个部分都要参加
42一、怎么知道hbase表里哪些作索引?哪些没作索引?
提示:
有且仅有一个:rowkey,因此hbase的快速查找创建在rowkey的基础的,而不能像通常的关系型数据库那样创建多个索引来达到多条件查找的效果。
42二、hdfs的原理以及各个模块的职责
42三、mapreduce的工做原理
42四、map方法是如何调用reduce方法的
42五、fsimage和edit的区别?
提示:fsimage:是存储元数据的镜像文件,而edit只是保存的操做日志。
42六、hadoop1和hadoop2的区别?
提示:
(1) hdfs的namenode和mapreduce的jobtracker都是单点。
(2) namenode所在的服务器的内存不够用时,那么集群就不能工做了。
(3)mapreduce集群的资源利用率比较低。
单NN的架构使得HDFS在集群扩展性和性能上都有潜在的问题,在集群规模变大后,NN成为了性能的瓶颈。Hadoop 2.0里的HDFS Federation就是为了解决这两个问题而开发的。扩大NN容量,共享DN数据,且方便客户端访问。
42七、hdfs中的block默认报错几份?
提示:3份
42八、哪一个程序一般与nn在一个节点启动?并作分析
提示:jobtrack,将二者放在一块儿,减小网络访问,IO访问的时间,提升了效率。
42九、列举几个配置文件优化?
430、写出你对zookeeper的理解
提示:大部分分布式应用须要一个主控、协调器或控制器来管理物理分布的子进程(如资源、任务分配等)。目前,大部分应用须要开发私有的协调程序,缺少一个通用的机制协调程序的反复编写浪费,且难以造成通用、伸缩性好的协调器。
ZooKeeper:提供通用的分布式锁服务,用以协调分布式应用。
43一、datanode首次加入cluster的时候,若是log报告不兼容文件版本,那须要namenode执行格式化操做,这样处理的缘由是?
提示:
这样处理是不合理的,由于那么namenode格式化操做,是对文件系统进行格式化,namenode格式化时清空dfs/name下空两个目录下的全部文件,以后,会在目录dfs.name.dir下建立文件。
文本不兼容,有可能时namenode 与 datanode 的 数据里的namespaceID、clusterID不一致,找到两个ID位置,修改成同样便可解决。
43二、谈谈数据倾斜,如何发生的,并给出优化方案。
缘由:
(1)key分布不均匀
(2)业务数据自己的特性
(3)建表时考虑不周
(4)某些SQL语句自己就有数据倾斜
map处理数据量的差别取决于上一个stage的reduce输出,因此如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在。
优化:参数调节;
43三、介绍一下HBase过滤器
43四、mapreduce基本执行过程
43五、谈谈hadoop1和hadoop2的区别
43六、谈谈HBase集群安装注意事项?