大数据Hadoop生态圈常用面试题
面试总结
1.生产环境中有多少个reduce
该问题可以总结为:
1.一个task的map数量由谁来决定? input split的大小间接决定了一个job拥有多少个map
默认input大小是64M可以通过修改mapred.min.split.size参数决定input split的大小从而影响map数量
a. map的数量通常是由输入文件的总块数决定的,正常的map数量的并行规
模大致是每一个Node是10~100个,比较合理的情况是每个map执行的时间
至少超过1分钟,这是由于hadoop的每一个map任务在初始化时需要一定的
时间
b.由于一个map对应一个split分块,因此map也由分片split大小决定,这个参数可以修改,修改文件为mapred.min.split.size
c.mapred.map.tasks:这个参数设置的map数量仅仅是一个提示,只有当
InputFormat 决定了map任务的个数比mapred.map.tasks值小时才起作用
d.通过使用JobConf 的conf.setNumMapTasks(int num)方法来手动地设置:这个
方法能够用来增加map任务的个数,但是不能设定任务的个数小于Hadoop
系统通过分割输入数据得到的值。
2.一个task的reduce数量由谁来决定?
a.一个task的reduce数量,由partition决定,正确的reduce任务的 个数应该
是0.95或者1.75 ×(节点数 × mapred.tasktracker.tasks.maximum参数值)
b.MR中mapred.tasktracker.reduce.task.maximum属性的值来指定reduce的数
量。
3.Reduce可以通过什么设置来增加任务个数?
通过设定JobConf 的conf.setNumReduceTasks(int num)方法来增加任务个数。
4.map和reduce的数量过多会导致什么情况?
太多的map和reduce也会导致整个hadoop框架因为过度的系统资源开销而使任
务失败。所以用户在提交map/reduce作业时应该在一个合理的范围内,这样既可
以增强系统负载匀衡,也可以降低任务失败的开销。
2.reduce如何输出到不同文件目录
a.Hadoop内置的输出文件格式有:
1)FileOutputFormat
2)TextOutputFormat
3)SequenceFileOutputFormat
4)MultipleOutputs
5) NullOutputFormat
用场景是在MR中进行了逻辑处理,同时输出文件已经在MR中进行了输出,而
不需要在输出的情况;
6)LazyOutputFormat
没有调用write就不会产生空文件;
b.实现方法步骤:(根据key和value值输出数据到不同目录)
1)自定义主类(主类其实就是修改了输出的方式而已),在main方法中使用hadoop
的内置输出文件格式:MultipleOutputs
"ignore", TextOutputFormat.class,LongWritable.class, Text.class);
MultipleOutputs.addNamedOutput(job,"other",TextOutputFormat.class,LongWritable.class,Text.class);
2) 自定义reducer(因为要根据key和value的值输出数据到不同目录,所以需要自定义逻辑)
if(v.toString().startsWith("ignore")){
out.write("ignore", key, v, "ign");
}else{
out.write("other", key, v, "oth");
3)可以看到输出的数据确实根据value的不同值被写入了不同的文件目录中,但是这里同样可以看到有默认的文件生成,
同时注意到这个文件的大小是0,这个暂时还没解决
3.二次排序:
实现简要步骤为
1.构造(用户标识,时间)作为key, 时间和其他信息(比如访问页面)作为value,然后进入map流程
2.在缺省的reduce的,传入参数为 单个key和value的集合,这会导致相同的用户标识和相同的时间被分在同一组,比如用户标识为11111的
1点00一个reduce, 用户标识为11111的 1点01另外一组,这不符合要求.所以需要更改缺省分组,需要由原来的按(用户标识,时间)
改成按(用户标识)分组就行了。这样reduce是传入参数变为户标识为11111 的value集合为(1点00 访问页面page1, 1点01 访问页面page2,
1点05 访问页面page3),然后在reduce方法里写自己的统计逻辑就行了。
3.当然1和2步之间,有2个重要细节要处理:确定key的排序规则和确定分区规则(分区规则保证map后分配数据到reduce按照用户标识来散列,
而不是按缺省的用户标识+时间来散列)
4.hbase rowkey的设计原则
1.HBase中rowkey可以唯一标识一行记录在HBase查询的时候,有以下几种方式:
通过get方式,指定rowkey获取唯一一条记录
通过scan方式,设置startRow和stopRow参数进行范围匹配
全表扫描,即直接扫描整张表中所有行记录
2.rowkey的长度原则:rowkey建议越短越好,最好不要超过16个字节,原因是
a.数据持久化文件Hfile是按照keyvalue存储的如果rowkey过长。比如超过100字节,
那1000w行数据,光rowkey就要占用100*1000w=10亿个字节,将近1G数据,这样会极大影响HFile的存储效率;
b.Memstore将缓存部分数据到内存,如果rowkey过长内存的有效利用率就会降低,系统就不能缓存更多的数据,这样会降低检索效率
c.目前操作系统都是64位系统,内存8字节对齐,控制在16个字节,8字节的整数倍利用了操作系统的最佳特性
3.rowkey散列原则
如果rowkey按照时间戳方式递增,建议将rowkey的高位作为散列字段,由程序随机生成,低位放时间字段,这样提升数据均衡分布在每个Regionserver
以实现负载均衡的几率如果没有散列字段,首字段直接是时间信息,所有的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中
在个别的RegionServer上,造成热点问题,会降低查询效率。
4.rowkey唯一原则
必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此设计rowkey的时候要充分利用这个排序的特点,将经常读取的数据存储到一块,
将最近可能会被访问的数据放到一块。
5.Hbase的热点数据怎么处理
a.热点是什么怎么来的:Hbase中的行是按照rowkey的字典顺序排序的,热点发生在大量的client直接访问集群的一个或极少数个节点
(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用,
这也会影响同一个RegionServer上的其他region。 为了避免写热点,设计rowkey使得不同行在同一个region,但是在更多数据情况下,
数据应该被写入集群的多个region,而不是一个。
b.解决办法一:加盐,是在rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀以使得它和之前的rowkey的开头不同。
分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,
以避免热点。
5.order by与sort by的区别
a.hive中的ORDER BY语句和关系数据库中的sql语法相似。他会对查询结果做全局排序,这意味着所有的数据会传送到一个Reduce任务上,这样会
导致在大数量的情况下,花费大量时间。
b.SORT BY不是全局排序,其在数据进入reducer前完成排序,因此在有多个reduce任务情况下,SORT BY只能保证每个reduce的输出有序,
而不能保证全局有序 *hive中通过set mapred.reduce.tasks=3;来设定reduce的数量*
c.一点小知识:DISTRIBUTE BY可以按指定字段将数据划分到不同的reduce中
当DISTRIBUTE BY的字段和SORT BY的字段相同时,可以用CLUSTER BY来代替 DISTRIBUTE BY with SORT BY。
7.从本地往hadoop集群导数据,导完后发现hadoop上面没有数据,问题可能是什么(自己总结的不一定准确)
1.数据节点没有启动:datenode
2.未关闭安全模式:hadoop dfsadmin -safemode leave
3.namenode与集群间网络通讯出现问题,namenode无法得到datanode的相应
9.多线程问题总结:
a、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了这个对象后,线程就进入了初始状态;
b、当该对象调用了start()方法,就进入可运行状态;
c、进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;
d、进入运行状态后情况就比较复杂了
e.1、run()方法或main()方法结束后,线程就进入终止状态;
f.2、当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。
当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;
i.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到可运行状态,这时与其他进程处于同等竞争状态,
OS有可能会接着又让这个进程进入运行状态;
j.4、当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,
将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),
一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;
h.5、当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,
是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,
但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,
一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。
Java总结
1.多线程有几种实现方法,都是什么,同步有几种实现方法,都是什么?
多线程有两种实现方法,分别是继承thread类与实现Runnable接口
同步的实现方法有两种,分别是synchronized,wait,notify
2.构造方法:a.所有的类中,都有一个默认的无参构造方法,重写构造方法后,默认的构造方法失效,构造方法主要在new对象时来做默认初始化
构造方法也可以有参数,可以根据参数的不同,调用不同的构造方法
b.子类继承父类后,不能继承父类的构造方法,在new 子类的构造方法时,默认去执行父类的无参构造方法,如果父类是重写为
有参数的构造方法的话,那父类也要加上一个无参的构造方法,不论子类调用的是有参数还是无参构造方法都会默认去找父类的
无参数的构造方法
与类相同
没有返回值类型,不能用return
一般用public修饰
3.重写/覆盖:在父子继承关系下,子类将从父类继承过来的方法,完全重写编写的过程叫做重写(方法一模一样,内容不相同)
要求:有继承关系
重新去编写父类的成员
方法名,参数列表,返回值类型一样
访问修饰符不能更加严格
抛出异常不能更加广泛
4.重载:在同一个类中,方法名相同,参数列表不同,所引起的两个方法的差异叫做重载
要求:在同一个类中
方法名相同
参数列表不同(类型,个数,顺序)
与访问修饰符无关,与返回值无关,与抛出异常无关
5.父类声明子类实现,就是用父类的类型来接收new 子类的对象,调用方法时只能调用父类和子类都有的方法(同名,使用的是子类的方法),
不能调用子类独有的方法
7.集合:继承collection(接口)的集合:Set(接口),List(接口),其中Set分为HashSet和TreeSet,List集合主要有ArrayList和LinkedList
List是有序的(按照添加顺序排序),先添加的元素在前面,后添的元素在后面,使用此接口能精确的控制每个元素插入的位置(类似于数组的下标),List允许有相同的元素
实现List接口的常用类有ArrayList,LinkedList,Vector
ArrayList:当我们向集合指定位置插入元素时,此位置后面的元素会自动往后移动,因此ArrayList插入和删除元素性能都比较低,但遍历元素的性能比较高
LinkedList:链表集合,他保存元素是按照地址存放,他保存前一个元素和后一个元素的内存地址,因此它插入和删除性能比较高,但遍历元素性能比较低
Set是无序的(不按照添加顺序排序),里面没有重复对象,主要有两个实现类:HashSet(无序,无重复的集合),TreeSet(有序,无重复的集合,需要人为排序,英文字母排序)
list可以利用下标和迭代器来取值,而set不可以,set只能用迭代器取值
Map集合不是继承collection的,他的每一元素都包含一对键对象和值对象。包括HashMap和TreeMap
向Map集合中加入元素时必须提供一对键对象和值对象,key要保证唯一不重复,否则会被覆盖
HashMap:key无序无重复
TreeMap:key有序无重复,按照字典的顺序排列
1.mr中使用了哪些接口?(或者是抽象类)
inputformat : getSplits(), getRecorReader()
outputformat: checkOutputSpaces(), getRecotdWriter();
Mapper/Reducer: configure(), close(), map(),reduce();
Partitioner: configure() , getPartition();
2.MR的过程:
input -----> map----->combiner----->shuffer---> reduce----->output
input :对数据进行split分片处理,产生K1值和V1值,传给map
map: 数据整理,把数据整理成K2和V2,
combiner:如果map输出内容比较多,reduce计算比较慢,我们可以加个combiner
map端的本地化reduce,减少map输出;
shuffer:相同的数据放到一个分区
partiton:如果reduce不是一个,shuffler做一个分区,将相同的K值,分到一个区;
排序方式
hash方式;
reduce:shuff分区结束后交给reduce进行计算,形成K3 V 3
output: 将reduce处理完的 K3和V3交给output输出;
a. 客户端编写好mapreduce程序,提交job到jobtracker;
b. Jobtracker进行检查操作,确定输出目录是否存在,存在抛出错误;
c. Jobtracker根据输入计算输入分片input split、配置job的资源、初始化作业、分配任务;
d. 每个input split创建一个map任务,tasktracker执行编写好的map函数;
e. Combiner阶段是可选的,它是一个本地化的reduce操作,合并重复key的值;
f. Shuffle一开始就是map做输出操作,并对结果进行排序,内存使用达到阀值就会spill,把溢出文件写
磁盘,写磁盘前有个排序操作,map输出全部做完后,会合并溢出文件,这个过程中还有个
Partitioner操作,一个partitioner对应一个reduce作业,reduce开启复制线程,复制对应的map输
出文件,复制时候reduce还会进行排序操作和合并文件操作
g. 传输完成,执行编写好的reduce函数,结果保存到hdfs上。
3.mr怎么处理小文件;
小文件坏处:hadoop处理海量数据,海量小文件的话呢,hadoop处理起来压力太大,假如有一万个文件,上传,就要开10000个map,首先是hadoop压力大,其次,每个小文件太小10M,造成map(64M)资源浪费,用不尽,所以要处理下文件,防止资源浪费,方法一般采用两种:
1.输入过程合并处理:1.在linux 10000个文件上传到HDFS时候,用脚本形成二进制文件流上传,上传的过程中就合并成了一个文件。
2.如果在hdfs中有大量小文件,首先进行清洗,把10000个小文件清洗成一个文件或者几个文件,写个map(1.前提10000小文件格式相同,2.不会有太多的小文件 一千万个小文件,首先会在操作系统上传时就处理完了,但是要是问可以说,分批做,每一万个存储到一个目录中,对一个目录进行map清洗)),其次,进行reduce计算
4.(hadoop下的数据类型)context输出类型
一般java的数据类型都能用
一般用:LongWritable 、IntWritable、Text
更适合网络传递。
5.sqoop具体命令
mysql导入到HDFS中:bin/sqoop import --connect jdbc:mysql://192.168.8.222:3306/test --username sqoop --password sqoop --table sss -m 1
HDFS导出到mysql中:bin/sqoop export --connect jdbc:mysql://192.168.8.222:3306/test --username sqoop --password sqoop --table sss --export-dir hdfs://h91:9000/user/hadoop/sss/part-m-00000
增量抽取mysql数据到HDFS中:
类型1(字段增长):bin/sqoop import --connect jdbc:mysql://192.168.8.101:3306/test --username sqoop --password sqoop --table sss -m 1 --target-dir /user/hadoop/a --check-column id --incremental append --last-value 3
类型2(时间增长):bin/sqoop import --connect jdbc:mysql://192.168.8.101:3306/test --username sqoop --password sqoop --table ss2 -m 1 --target-dir /user/hadoop/a --incremental lastmodified --check-column sj --last-value '2015-11-20 22:34:15'
mysql导入到 hive中:bin/sqoop import --connect jdbc:mysql://192.168.8.101:3306/test --username sqoop --password sqoop --table sss --hive-import -m 1 --hive-table tb1 --fields-terminated-by ','
Oracle导入到HDFS中:bin/sqoop import --connect jdbc:oracle:thin:@192.168.8.222:1521:TEST --username SCOTT --password abc --verbose -m 1
--table S1 (表名字 和 用户名要大写 )
mysql导入到Hbase中: bin/sqoop import --connect jdbc:mysql://192.168.8.101:3306/test --username sqoop --password sqoop --table t3
--hbase-table qqq --column-family ccf --hbase-row-key id --hbase-create-table
7.flume的组成部份
Flume以agent为最小的独立运行单位。一个agent就是一个JVM。单agent由Source、Sink和Channel三大组件构成。
Source:完成对日志数据的收集,分成 transtion 和 event 打入到channel之中。
Channel:主要提供一个队列的功能,对source提供中的数据进行简单的缓存。
Sink:取出Channel中的数据,进行相应的存储文件系统,数据库,或者提交到远程服务器。
8.hive分区 如何将数据定义到哪一个分区中
Create table logs(ts bigint,line string) Partitioned by (dt string,country string);
Load data local inpath ‘/home/hadoop/par/file01.txt’ into table logs partition (dt=’ 2012-06-02’,country=’cn’);
9.如何从编程的脚度讲解MR的过程
对数据进行分片把数据解析成k1/v1形式传给map;
Map对k1/v1进行截取、运算等操作生成k2/v2传给reduce;
Reduce对相同key的值进行计算,生成最终结果k3/v3输出
10.MR中有没有只有MAP的
有,只对数据进行分片,解析成key/value形式后,直接输出结果不进行reduce端的分组和排序。可以进行数据清洗。
11.MAP输出端的组成部份
Combiner、shuffle、partitioner
12.MR中的 K是什么意思
Kmeans聚类算法中的初始中心点;
13.hbase如何导入数据
使用MapReduce Job方式,根据Hbase API编写java脚本,将文本文件用文件流的方式截取,然后存储到多个字符串数组中,在put方法下,通过对表中的列族进行for循环遍历列名,用if判断列名后进行for循环调用put.add的方法对列族下每一个列进行设值,每个列族下有几个了就赋值几次!没有表先对先创建表。
15.如何用MR实现join
要用mr实现jion,首先要区分左右表,在map中进行这个操作,区分左右表的方法主要是用标志法,对value值进行切割,保证链接列在key值,剩余列和左右表标志在value中,在reduce中通过value中的标志位来区分左右表输出,通过笛卡尔积来实现jion输出。
16.MAP如何排序
在map中要实现排序,可以用tree map 集合将数据放入集合中集合将自动针对key值通过字典进行排序。
17.65M的任务会分成几个块
正常来说hadoop集群的块默认大小为64m,这个值是可调的,最小值为64m,以64m为例,将65m数据存入hdfs中将最少分成两个块进行分布式存储。
18.公司有多少个节点点,每天产生多少数据量
公司有150个节点,每天产生的数据量有1.2TB。
19.JVM调优
JVM调优可以调节JVM最大可用内存。
20.MAP端可不可排序
map本身没有排序的方法实现,但是可以和tree map集合结合起来使用,这样就可以实现map端的排序了。
21.怎么编写脚本 跑hadoop JOB?
在linux系统中跑hadoop的JOB可以用streaming来实现,提前编写好脚本,将其放入contab -e 中设定好时间就可以了。
22.HIVE 优化?
1.输出小文件合并
hive.merge.smallfiles.avgsize 设为5000000
增加map数量,可提高hive运行速度
set mapred.reduce.tasks=10;
2.map join
大小表join时通过使用hint的方式指定join时使用mapjoin。
/*+ mapjoin(小表)*/
3.hive索引
4.优先过滤数据,减少每个阶段的数据量,对分区表加以分区,同时只选择需要使用的字段
5.根据不同的使用目的优化使用方法
6.尽量原子化操作,尽量避免一个sql包含复杂逻辑
7.join操作小表放在join的左边
8.如果union all的部分个数大于2,或者union部分数据量大,应拆分成多个insert into语句。
1.参数优化,小于6M自动合并
2.加功能,改成分区表,做join写成任务流
3.mapjoin
4.加索引
5.先where 再join
6.加小型的sql
23.HDFS上怎么做目录管理?
mr分析上传,管理功能业务,每小时产生目录,定期删除,但是要保留原始数据后再删除;
第一,我们分析,做时间比较长的分析,历史数据量比较大,2G/日 一年
第二,预期多少数据,但是没有达到预期数据,但是没有达到,所以我离职了
坑:公司地址:
部门结构:
自我评价一下技术方面:避重就轻,大数据学的都可以,公司需求都能实现,后期要提高扩展的部分
我们公司有一些加班:能不能接受,加班正常,互联网行业都要加班,咱们公司是不是有点加班补助,保证对自己负责,才能热爱我的工作,对公司负责;
24.数据量这么小 为什么用hadoop?
Hadoop 是一个能够对大量数据进行分布式处理的软件框架。具有可靠、高效、可伸缩的特点。
25.介绍下你的项目都针对那些客户群?
1.大型电商,产品种类、数量多,客户访问量大,累积数据量庞大
2.app智能语音,需要更多的文字语言及语音数据
3.环境监测,大量的各种传感器不间断产生庞大的数据
26.介绍下 hive下的表结构?
hive的表逻辑上由存储的数据和描述表格中的数据形式的相关元数据
组成。表存储的数据存放在分布式文件系统里,例如HDFS,元数据存
储在关系数据库里,当我们创建一张hive的表,还没有为表加载数据
的时候,该表在分布式文件系统,例如hdfs上就是一个文件夹(文件
目录)。
27.MPP数据库 和 hadoop的区别,MPP数据库和oracle的区别?
其实MPP架构的关系型数据库与Hadoop的理论基础是极其相似的,都是将运算分布到节点中独立运算后进行结果合并。个人觉得区别仅仅在于前者跑的是SQL,后者底层处理则是MapReduce程序。
但是我们会经常听到对于MPP而言,虽说是宣称也可以横向扩展Scale OUT,但是这种扩展一般是扩到100左右,而Hadoop一般可以扩展1000+,这也是经常被大家拿来区分这两种技术的一个说词。
这是为什么呢?其实可以从CAP(一致性,可用性和分区容错性)理论上来找到一些理由。因为MPP始终还是DB,一定要考虑C(Consistency 一致性,一致性 (逻辑),稳定性),其次考虑 A(Availability n.可用性;有效性;实用性),最后才在可能的情况下尽量做好P(Partition-tolerance)。而Hadoop就是为了并行处理和存储设计的,所有数据都是以文件存储,所以优先考虑的是P,然后是A,最后再考虑C。所以后者的可扩展性当然好于前者。
以下几个方面制约了MPP数据库的扩展
1、高可用:MPP DB是通过Hash计算来确定数据行所在的物理机器(而Hadoop无需此操作),对存储位置的不透明导致MPP的高可用很难办。
2、并行任务:数据是按照Hash来切分了,但是任务没有。每个任务,无论大小都要到每个节点去走一圈。
3、文件系统:数据切分了,但是文件数没有变少,每个表在每个节点上一定有一到多个文件。同样节点数越多,存储的表就越多,导致每个文件系统上有上万甚至十万多个文件。
4、网络瓶颈:MPP强调对等的网络,点对点的连接也消耗了大量的网络带宽,限制了网络上的线性扩展(想象一台机器可能要给1000台机器发送信息)。更多的节点并没有提供更高的网络带宽,反而导致每个组节点间平均带宽降低。
5、其他关系数据库的枷锁:比如锁、日志、权限、管理节点瓶颈等均限制了MPP规模的扩大。
但是MPP数据库有对SQL的完整兼容和一些事务处理功能,对于用户来说,在实际的使用场景中,如果数据扩展需求不是特别大,需要的处理节点不多,数据都是结构化数据,习惯使用传统RDBMS的很多特性的场景,可以考虑MPP如Greenplum/Gbase等。
但是如果有很多非结构化数据,或者数据量巨大,有需要扩展到成百上千个数据节点需求的,这个时候Hadoop是更好的选择。
29.推荐系统用到那些算法?(结合业务讲解)
(1)基于流行度的算法非常简单粗暴,类似于各大新闻、微博热榜等,根据PV、UV、日均PV或分享率等数据来按某种热度排序来推荐给用户。
(2)协同过滤算法:分析各个用户对item(条款)的评价(通过浏览记录、购买记录等);
依据用户对item的评价计算得出所有用户之间的相似度;
选出与当前用户最相似的N个用户;
将这N个用户评价最高并且当前用户又被浏览过的item推荐给当前用户;
(3)基于内用的算法:比如现在系统里有一个用户和一条新闻,通过分析用户的行为以及新闻的文本内容,我们提取出数个关键字进行匹配。
(4)基于模型的算法:有很多,介绍其中比较简单的方法——logistics回归预测,比如年龄与购买护肤品这个行为并不呈强关联,性别与购买护肤品也不强关联,但当我们把年龄与性别综 合在一起考虑时,他们便和购买行为产生了强关联。
30.谈下hadoop和spark的区别与前景?
答:区别:hadoop是使用廉价的,异构的机器来做分布式存储与计算,用于分布式批处理计算,常用于数据挖掘、分析;spark对硬件的要求稍高,对内存/CPU是有较高要求的,spark是一个 基于内存计算的开源的集群计算系统,目的是让数据分析更加快速,除了能够提供交互式查询外,它还可以优化迭代工作负载。
31.hbase的存储结构?
答:Hbase中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过256M就要被分割成两个,由HRegionServer管理,管理哪些HRegion由Hmaster分配。 HRegion存取一个子表时,会创建一个HRegion对象,然后对表的每个列族(Column Family)创建一个store实例,每个store都会有0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile,HFile就是实际的存储文件,因此,一个HRegion还拥有一个MemStore实例。
36.MR 分析活跃用户
MR分析vmall日志,获取访问ip,以及对应移动端型号,特定时间内访问次数超过一定数量的归类为活跃用户
37.hive有哪些方式保存元数据,各有哪些特点
hive的数据模型包括:database、table、partition和bucket。
1.Database:相当于关系数据库里的命名空间(namespace),它的作用是将用户和数据库的应用隔离到不同的数据库或模式中
2.表(table):hive的表逻辑上由存储的数据和描述表格中的数据形式的相关元数据组成。
Hive里的表友两种类型一种叫托管表,这种表的数据文件存储在hive的数据仓库里,一种叫外部表,这种表的数据文件
可以存放在hive数据仓库外部的分布式文件系统上,也可以放到hive数据仓库里(注意:hive的数据仓库也就是hdfs上的一个目录,
这个目录是hive数据文件存储的默认路径,它可以在hive的配置文件里进行配置,最终也会存放到元数据库里)。
3.分区(partition):hive里分区的概念是根据“分区列”的值对表的数据进行粗略划分的机制,
在hive存储上就体现在表的主目录(hive的表实际显示就是一个文件夹)下的一个子目录,这个文件夹的名字就是
我们定义的分区列的名字,没有实际操作经验的人可能会认为分区列是表的某个字段,其实不是这样,分区列不是表里的某个字段,
而是独立的列,我们根据这个列存储表的里的数据文件。
4.桶(bucket):上面的table和partition都是目录级别的拆分数据,bucket则是对数据源数据文件本身来拆分数据。
38.mapreduce中,combiner,partition作用?
combiner :实现的功能跟reduce差不多,接收map的值,经过计算后给reduce,它的key,value类型要跟reduce完全一样,当reduce业务复杂时可以用
Partition:将输出的结果分别保存在不同的文件中
40.hive与hbase的区别
hive:
1.数据保存在hdfs上,以hdfs格式保存数据,映射为hive中的表结构
2.支持sql语言,调用MR
3.不能做实时操作
4.相对数据量较小
Hbase:
1.Hbase自己的存储机构
2.不支持sql语言,不调用MR
3.可以支持实时操作
4.相对数据量大,对于反复使用的数据比较适用
42.块大小 对内存的影响?
Hadoop块大小:文件的block块大小,需要根据我们的实际生产中来更改block的大小,如果block定义的太小,大的文件都会被切分成太多的小文件,减慢用户上传效率,如果block定义的太大,那么太多的小文件可能都会存到一个block块中,虽然不浪费硬盘资源,可是还是会增加namenode的管理内存压
43.hadoop 版本
答:0.20.x版本最后演化成了现在的1.0.x版本
0.23.x版本最后演化成了现在的2.x版本
Hadoop 1.0 指的是1.x(0.20.x),0.21,0.22
hadoop 2.0 指的是2.x,0.23.x
CDH3,CDH4分别对应了hadoop1.0 hadoop2.0
45.解释下hbase实时查询的原理
答:实时查询,可以认为是从内存中查询,一般响应时间在1秒内。HBase的机制是数据先写入到内存中,当数据量达到一定的量(如128M),再写入磁盘中, 在内存中,是不进行数据的更新或合并操作的,只增加数据,这使得用户的写操作只要进入内存中就可以立即返回,保证了HBase I/O的高性能。
46.zookeeper 为什么要 基数个?
答:zookeeper有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。
因为选主过程中,推荐的server只用获得半数以上的投票也就是n/2+1票数,才能当选leader
zookeeper 原理机器宕机半数以上自动停止工作,基数可选leader;
1.hive SQL语句中 select from where group by having order by 的执行顺序?
from--where--group by--having--select--order by,
from:需要从哪个数据表检索数据
where:过滤表中数据的条件
group by:如何将上面过滤出的数据分组
having:对上面已经分组的数据进行过滤的条件
select:查看结果集中的哪个列,或列的计算结果
order by :按照什么样的顺序来查看返回的数据
4.使用Linux命令查询file1 里面空行的所在行号
sed -n "/^$/=" file1
grep -n ^$ file1
awk "/^$/{print NR}" file1
5.有文件chengji.txt 内容如下:
张三 40
李四 50
王五 60
请用Linux命令计算第二列的和并输出:
aa1=`cat chengji.txt |grep 张三 |awk '{print $2}'`
aa2=`cat chengji.txt |grep 李四 |awk '{print $2}'`
aa3=`cat chengji.txt |grep 王五 |awk '{print $2}'`
expr $aa1 + $aa2 + $aa3
6.有文件dim_city.txt 如何加载dim_city表中
load data local inpath"./dim_city.txt" insert into table dim_city;
7.请列出正常工作的hadoop集群中hadoop都分别需要启动哪些进程,他们的作用分别是什么,尽可能些全面
1.Namenode:
Namenode 管理者文件系统的Namespace。它维护着文件系统树(filesystem tree)以及文件树中所有的文件和文件夹的元数据(metadata)。管理这些信息的文件有两个,分别是Namespace 镜像文件(Namespace image)和操作日志文件(edit log),这些信息被Cache在RAM中,当然,这两个文件也会被持久化存储在本地硬盘。Namenode记录着每个文件中各个块所在的数据节点的位置信息,但是他并不持久化存储这些信息,因为这些信息会在系统启动时从数据节点重建。
2.JobTracter
JobTracker后台程序用来连接应用程序与Hadoop。用户代码提交到集群以后,由JobTracker决定哪个文件将被处理,并且为 不同的task分配节点。同时,它还监控所有的task,一旦某个task失败了,JobTracker就会自动重新开启这个task,在大多数情况下这 个task会被放在不用的节点上。每个Hadoop集群只有一个JobTracker,一般运行在集群的Master节点上。
3.SecondaryNameNode
Secondary NameNode是一个用来监控HDFS状态的辅助后台程序。就想NameNode一样,每个集群都有一个Secondary NameNode,并且部署在一个单独的服务器上。Secondary NameNode不同于NameNode,它不接受或者记录任何实时的数据变化,但是,它会与NameNode进行通信,以便定期地保存HDFS元数据的 快照。由于NameNode是单点的,通过Secondary NameNode的快照功能,可以将NameNode的宕机时间和数据损失降低到最小。同时,如果NameNode发生问题,Secondary NameNode可以及时地作为备用NameNode使用。
4.TaskTracker
TaskTracker与负责存储数据的DataNode相结合,其处理结构上也遵循主/从架构。JobTracker位于主节点,统领 MapReduce工作;而TaskTrackers位于从节点,独立管理各自的task。每个TaskTracker负责独立执行具体的task,而 JobTracker负责分配task。虽然每个从节点仅有一个唯一的一个TaskTracker,但是每个TaskTracker可以产生多个java 虚拟机(JVM),用于并行处理多个map以及reduce任务。TaskTracker的一个重要职责就是与JobTracker交互。如果 JobTracker无法准时地获取TaskTracker提交的信息,JobTracker就判定TaskTracker已经崩溃,并将任务分配给其他 节点处理
5.DataNode
Datanode是文件系统的工作节点,他们根据客户端或者是namenode的调度存储和检索数据,并且定期向namenode发送他们所存储的块(block)的列表。
集群中的每个服务器都运行一个DataNode后台程序,这个后台程序负责把HDFS数据块读写到本地的文件系统。当需要通过客户端读/写某个 数据时,先由NameNode告诉客户端去哪个DataNode进行具体的读/写操作,然后,客户端直接与这个DataNode服务器上的后台程序进行通 信,并且对相关的数据块进行读/写操作。
10.hive如何将下表table_1中的数据
col1 col2 col3
a b 1,2,3
c d 4,5,6
变为:
col1 col2 col 3
a b 1
a b 2
a b 3
c d 4
c d 5
c d 6
create table table_1(col1 string,col2 string,col3 string)
select col1,col2,name from table_1 LATERAL VIEW explode(split(col3,',')) col3 as name;
1,hadoop中需要配置哪些配置文件其作用是什么以?
1、dfs.hosts 记录即将作为datanode加入集群的机器列表
2、mapred.hosts 记录即将作为tasktracker加入集群的机器列表
3、dfs.hosts.exclude mapred.hosts.exclude 分别包含待移除的机器列表
4、master 记录运行辅助namenode的机器列表
5、slave 记录运行datanode和tasktracker的机器列表
6、hadoop-env.sh 记录脚本要用的环境变量,以运行hadoop
7、core-site.xml hadoop core的配置项,例如hdfs和mapreduce常用的i/o设置等
8、hdfs-site.xml hadoop守护进程的配置项,包括namenode、辅助namenode和datanode等
9、mapred-site.xml mapreduce守护进程的配置项,包括jobtracker和tasktracker
10、hadoop-metrics.properties 控制metrics在hadoop上如何发布的属性
11、log4j.properties 系统日志文件、namenode审计日志、tasktracker子进程的任务日志的属性
2,HDFS的存储机机制是什么
Hdfs是分布式文件系统,它将一个文件分为一个或几个块来存储,块是最小的存储单位,默认是64m,每一个块都有一个全局id,hdfs中有主节点namenode和从节点datanode,nn保存元数据:文件系统的目录树信息;文件和块的对应关系;块存放位置,dn保存实际数据,在本地文件系统中产生两个文件:实际数据文件和校验码文件。
3,怎么查看,删除,移动,拷贝HDFS上的文件
Hadoop fs -ls /user/hadoop
Hadoop fs -cat
Hadoop fs -rmr
Hadoop fs -mv
Hadoop fs -cp
Hadoop fs -mkdir
4,hadoop中COMBINER的作用?
Combiner它是一个本地化的reduce操作,合并重复key的值;
5,MR的工作原理,请举个例子说明MR是怎么运作的.
以WordCount为例,
a. 初始化Configuration、
b. 构建一个job、
c. 装载WordCount,map,reduce类:map的实现方法中,根据输入的分片,截取每个词作为key,1作为value代表每个词出现一次,装到context容器中,reduce的实现方法中,会对数据分组和排序,对传递的value作用迭代器,对相同的key循环遍历求和,代表每个词出现的次数、
d. 设置key/value的输出格式,输出结果。
6,HIVE数据库与ORACLE数据库有什么区别,目前HIVE数据库不支持哪些函数?
a. 查询语言。由于 SQL 被广泛的应用在数据仓库中,因此,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者可以很方便的使用 Hive 进行开发。
b. 数据存储位置。Hive 是建立在 Hadoop 之上的,所有 Hive 的数据都是存储在 HDFS 中的。而数据库则可以将数据保存在块设备或者本地文件系统中。
c. 数据格式。Hive 中没有定义专门的数据格式,数据格式可以由用户指定,用户定义数据格式需要指定三个属性:列分隔符(通常为空格、”\t”、”\x001″)、行分隔符 (”\n”)以及读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile)。由于在加载数据的过程中,不需要从用户数据格式到 Hive 定义的数据格式的转换,因此,Hive 在加载的过程中不会对数据本身进行任何修改,而只是将数据内容复制或者移动到相应的 HDFS 目录中。而在数据库中,不同的数据库有不同的存储引擎,定义了自己的数据格式。所有数据都会按照一定的组织存储,因此,数据库加载数据的过程会比较耗时。
d. 数据更新。由于 Hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive 中不支持对数据的改写和添加,所有的数据都是在加载的时候中确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET 修改数据。
e. 索引。之前已经说过,Hive 在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些 Key 建立索引。Hive 要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大数据量的访问,Hive 仍然可以体现出优势。数据库中,通常会针对一个或者几个列建立索引,因此对于少量的特定条件的数据的访问,数据库可以有很高的效率,较低的延迟。由于数据 的访问延迟较高,决定了 Hive 不适合在线数据查询。
f. 执行。Hive 中大多数查询的执行是通过 Hadoop 提供的 MapReduce 来实现的(类似 select * from tbl 的查询不需要 MapReduce)。而数据库通常有自己的执行引擎。
g. 执行延迟。之前提到,Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架。由于 MapReduce 本身具有较高的延迟,因此在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时 候,Hive 的并行计算显然能体现出优势。
h. 可扩展性。由于 Hive 是建立在 Hadoop 之上的,因此 Hive 的可扩展性是和 Hadoop 的可扩展性是一致的(世界上最大的 Hadoop 集群在 Yahoo!,2009年的规模在 4000 台节点左右)。而数据库由于 ACID 语义的严格限制,扩展行非常有限。目前最先进的并行数据库 Oracle 在理论上的扩展能力也只有 100 台左右。
i. 数据规模。由于 Hive 建立在集群上并可以利用 MapReduce 进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。
Hive不支持的函数:decode、rownum、to_char、replace、||、nvl、months_between、add_months、rollup、cube、rank() over、dense_rank() over、row_number() over
7,HBASE常用基本命令,创建表,添加记录,查看记录,删除记录
Create ‘tablename’,’column family’
Put ‘tablename’,’rowkey’,’column family:’,’value’
Put ‘tablename’,’rowkey’,’column family:column’,’value’
Scan ‘tablename’
scan 'user_test',{COLUMNS =>'info:username',LIMIT =>10, STARTROW => 'test',STOPROW=>'test2'}
scan 'tablename',{COLUMNS => 'column family'}
Get ‘tablename’,’rowkey’
Get ‘tablename’,’rowkey’,’column family’
Get ‘tablename’,’rowkey’,’column family:column’
delete 'tablename','rowkey','column family:column'
Deleteall ‘tablename’,’rowkey’
删除列族: disable ‘tablename’
Alter ‘tablename’,{NAME=>’column family’,METHOD=>’delete’}
删除表: disable ‘tablename’
Drop ‘tablename’
8,使用如下示例数据及数据说明情况,分别实现(1)该数据在HIVE库中建表,(2)数据导入到所建表中,(3)使用所建数据表,使用HQL统计2014-12-31账期手机用户上网总流量.
数据说明 文件为test.txt字段分割符为|
9,编写HIVE自定义函数实现ORACLE数据库中的addmonths函数功能,然后封装到HIVE函数库中
addmonths(data a,int b)函数功能简单说明,求传入日期a经过B月后的日期是多少?
1.列出安装Hadoop流程步骤
a) 创建hadoop账号
b) 更改ip
c) 安装Java 更改/etc/profile 配置环境变量
d) 修改host文件域名
e) 安装ssh 配置无密码登录
f) 解压hadoop
g) 配置hadoop conf下面的配置文件
h) Hadoop namenode -format 格式化
i) Start 启动
2.列出hadoop集群启动中的所有进程和进程的作用
a) Namenode 管理集群,记录namenode文件信息
b) Secondname 可以做备份,对一定范围内的数据做快照
c) Datanode 存储数据
d) Jobtarcker 管理任务,分配任务
e) Tasktracker 执行任务
3.启动报nameNode错误 如何解决
a) 检查hdfs有没有启动成功
b) 检查输入文件是不是存在
4.写出下列执行命令
杀死一个job
Hadoop job -list 取得job id
Hadoop job kill job id
删除hdfs上的 /temp/aa 目录
Hadoop –daemon.sh start datanode
加入一个新的节点或删除一个节点 刷新集群状态的命令
5.列出你所知道的调度器 说明其工作方法
a) Fifo schedular 默认的调度器 先进先出
b) Capacity schedular 计算能力调度器 选择占用内存小 优先级高的
c) Fair schedular 调肚脐 公平调度器 所有job 占用相同资源
7.用你最熟悉的语言辨析一个map reduce 计算第四个原色的个数
a) Wordcount
8.你认为java streating pipe 开发map reduce 优缺点
a) Java 编写map reduce可以实现复杂的逻辑,如果需求简单,则显得繁琐
b) Hivesql 基本都是针对Hive中表数据进行编写,对复杂的逻辑很难实现
9.Hive 有哪些保存元数据的方式并有哪些特点
a) 内存数据库 derby
b) 本地MySQL 常用
c) 远程mysql
11.简述hadoop实现join的及各种方式
reduce side join是一种最简单的join方式,其主要思想如下:
在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源的key/value数据对,对每条数据打一个标签(tag),比如:tag=0表示来自文件File1,tag=2表示来自文件File2。即:map阶段的主要任务是对不同文件中的数据打标签。
在reduce阶段,reduce函数获取key相同的来自File1和File2文件的value list, 然后对于同一个key,对File1和File2中的数据进行join(笛卡尔乘积)。即:reduce阶段进行实际的连接操作。
2.2 map side join
之所以存在reduce side join,是因为在map阶段不能获取所有需要的join字段,即:同一个key对应的字段可能位于不同map中。Reduce side join是非常低效的,因为shuffle阶段要进行大量的数据传输。
Map side join是针对以下场景进行的优化:两个待连接表中,有一个表非常大,而另一个表非常小,以至于小表可以直接存放到内存中。这样,我们可以将小表复制多份,让每个map task内存中存在一份(比如存放到hash table中),然后只扫描大表:对于大表中的每一条记录key/value,在hash table中查找是否有相同的key的记录,如果有,则连接后输出即可。
为了支持文件的复制,Hadoop提供了一个类DistributedCache,使用该类的方法如下:
(1)用户使用静态方法DistributedCache.addCacheFile()指定要复制的文件,它的参数是文件的URI(如果是HDFS上的文件,可以这样:hdfs://namenode:9000/home/XXX/file,其中9000是自己配置的NameNode端口号)。JobTracker在作业启动之前会获取这个URI列表,并将相应的文件拷贝到各个TaskTracker的本地磁盘上。(2)用户使用DistributedCache.getLocalCacheFiles()方法获取文件目录,并使用标准的文件读写API读取相应的文件。
2.3 SemiJoin
SemiJoin,也叫半连接,是从分布式数据库中借鉴过来的方法。它的产生动机是:对于reduce side join,跨机器的数据传输量非常大,这成了join操作的一个瓶颈,如果能够在map端过滤掉不会参加join操作的数据,则可以大大节省网络IO。
实现方法很简单:选取一个小表,假设是File1,将其参与join的key抽取出来,保存到文件File3中,File3文件一般很小,可以放到内存中。在map阶段,使用DistributedCache将File3复制到各个TaskTracker上,然后将File2中不在File3中的key对应的记录过滤掉,剩下的reduce阶段的工作与reduce side join相同。
15.Combiner 和partition的作用
Combiner作用是map输出阶段的数据相同的key值的进行合并,
16.combine分为map端和reduce端,作用是把同一个key的键值对合并在一起,可以自定义的。 combine函数把一个map函数产生的
1.hive内部表和外部表区别
2.1、在导入数据到外部表,数据并没有移动到自己的数据仓库目录下,也就是说外部表中的数据并不是由它自己来管理的!而表则不一样; 2、在删除表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的! 那么,应该如何选择使用哪种表呢?在大多数情况没有太多的区别,因此选择只是个人喜好的问题。但是作为一个经验,如果所有处理都需要由Hive完成,那么你应该创建表,否则使用外部表!
5.Mapreduce怎么处理数据倾斜
6.map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完,此称之为数据倾斜。 用hadoop程序进行数据关联时,常碰到数据倾斜的情况,这里提供一种解决方法。 (1)设置一个hash份数N,用来对条数众多的key进行打散。 (2)对有多条重复key的那份数据进行处理:从1到N将数字加在key后面作为新key,如果需要和另一份数据关联的话,则要重写比较类和分发类。如此实现多条key的平均分发。 int iNum = iNum % iHashNum; String strKey = key + CTRLC + String.valueOf(iNum) + CTRLB + “B”; (3)上一步之后,key被平均分散到很多不同的reduce节点。如果需要和其他数据关联,为了保证每个reduce节点上都有关联的key,对另一份单一key的数据进行处理:循环的从1到N将数字加在key后面作为新key for(int i = 0; i < iHashNum; ++i){ String strKey =key + CTRLC + String.valueOf(i) ; output.collect(new Text(strKey), new Text(strValues));} 以此解决数据倾斜的问题,经试验大大减少了程序的运行时间。但此方法会成倍的增加其中一份数据的数据量,以增加shuffle数据量为代价,所以使用此方法时,要多次试验,取一个最佳的hash份数值。 用上述的方法虽然可以解决数据倾斜,但是当关联的数据量巨大时,如果成倍的增长某份数据,会导致reduce shuffle的数据量变的巨大,得不偿失,从而无法解决运行时间慢的问题。
9.Hbase内部是什么机制
在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的。HBase 接到命令后存下变化信息,或者写入失败抛出异常。默认情况下,执行写入时会写到两个地方:预写式日志(write-ahead log,也称HLog)和MemStore(见图2-1)。HBase 的默认方式是把写入动作记录在这两个地方,以保证数据持久化。只有当这两个地方的变化信息都写入并确认后,才认为写动作完成。
MemStore 是内存里的写入缓冲区,HBase 中数据在永久写入硬盘之前在这里累积。当MemStore 填满后,其中的数据会刷写到硬盘,生成一个HFile。HFile 是HBase 使用的底层存储格式。HFile 对应于列族,一个列族可以有多个HFile,但一个HFile 不能存储多个列族的数据。在集群的每个节点上,每个列族有一个MemStore。
大型分布式系统中硬件故障很常见,HBase 也不例外。设想一下,如果MemStore还没有刷写,服务器就崩溃了,内存中没有写入硬盘的数据就会丢失。HBase 的应对办法是在写动作完成之前先写入WAL。HBase 集群中每台服务器维护一个WAL 来记录发生的变化。WAL 是底层文件系统上的一个文件。直到WAL 新记录成功写入后,写动作才被认为成功完成。这可以保证HBase 和支撑它的文件系统满足持久性。大多数情况下,HBase 使用Hadoop 分布式文件系统(HDFS)来作为底层文件系统。
如果HBase 服务器宕机,没有从MemStore 里刷写到HFile 的数据将可以通过回放WAL 来恢复。你不需要手工执行。Hbase 的内部机制中有恢复流程部分来处理。每台HBase 服务器有一个WAL,这台服务器上的所有表(和它们的列族)共享这个WAL。
你可能想到,写入时跳过WAL 应该会提升写性能。但我们不建议禁用WAL,除非你愿意在出问题时丢失数据。如果你想测试一下,如下代码可以禁用WAL: 注意:不写入 WAL 会在RegionServer 故障时增加丢失数据的风险。关闭WAL,出现故障时HBase 可能无法恢复数据,没有刷写到硬盘的所有写入数据都会丢失。
11.我们在开发分布式计算job的是不是可以去掉reduce
由于MapReduce计算输入和输出都是基于HDFS文件,所以大多数公司的做法是把mysql或sqlserver的数据导入到HDFS,计算完后再导出到常规的数据库中,这是MapReduce不够灵活的地方之一。 MapReduce优势在于提供了比较简单的分布式计算编程模型,使开发此类程序变得非常简单
狭隘的来讲,MapReduce是把计算任务给规范化了, MapReduce把业务逻辑给拆分成2个大部分,Map和Reduce,可以先在Map部分把任务计算一半后,扔给Reduce部分继续后面的计算。 当然在Map部分把计算任务全做完也是可以的。
如果把小明产品经理的需求放到Hadoop来做,其处理流程大致如下:
1. 把100G数据导入到HDFS
2. 按照Mapreduce的接口编写处理逻辑,分Map、Reduce两部分。
3. 把程序包提交到Mapreduce平台上,存储在HDFS里。
4. 平台中有个叫Jobtracker进程的角色进行分发任务。
5. 如果有5台机器进行计算的话,就会提前运行5个叫TaskTracker的slave进程
6. Jobtracker把任务分发到TaskTracker后,TaskTracker把开始动态加载jar包,创建个独立进程执行Map部分,然后把结果写入到HDFS上。
7. 如果有Reduce部分,TaskTracker会创建个独立进程把Map输出的HDFS文件,通过RPC方式远程拉取到本地,拉取成功后,Reduce开始计算后续任务。
8. Reduce再把结果写入到HDFS中
9. 从HDFS中把结果导出。
13.Hdfs数据压缩算法
14.1、在HDFS之上将数据压缩好后,再存储到HDFS 2、在HDFS内部支持数据压缩,这里又可以分为几种方法: 2.1、压缩工作在DataNode上完成,这里又分两种方法: 2.1.1、数据接收完后,再压缩 这个方法对HDFS的改动最小,但效果最低,只需要在block文件close后,调用压缩工具,将block文件压缩一下,然后再打开block文件时解压一下即可,几行代码就可以搞定 2.1.2、边接收数据边压缩,使用第三方提供的压缩库 效率和复杂度折中方法,Hook住系统的write和read操作,在数据写入磁盘之前,先压缩一下,但write和read对外的接口行为不变,比如:原始大小为100KB的数据,压缩后大小为10KB,当写入100KB后,仍对调用者返回100KB,而不是10KB 2.2、压缩工作交给DFSClient做,DataNode只接收和存储 这个方法效果最高,压缩分散地推给了HDFS客户端,但DataNode需要知道什么时候一个block块接收完成了。 推荐最终实现采用2.2这个方法,该方法需要修改的HDFS代码量也不大,但效果最高。
17.Hive底层和数据库交互原理
Hive和Hbase有各自不同的特征:hive是高延迟、结构化和面向分析的,hbase是低延迟、非结构化和面向编程的。Hive数据仓库在hadoop上是高延迟的。Hive集成Hbase就是为了使用hbase的一些特性。
Hive集成HBase可以有效利用HBase数据库的存储特性,如行更新和列索引等。在集成的过程中注意维持HBase jar包的一致性。Hive集成HBase需要在Hive表和HBase表之间建立映射关系,也就是Hive表的列(columns)和列类型(column types)与HBase表的列族(column families)及列限定词(column qualifiers)建立关联。每一个在Hive表中的域都存在于HBase中,而在Hive表中不需要包含所有HBase中的列。HBase中的RowKey对应到Hive中为选择一个域使用:key来对应,列族(cf:)映射到Hive中的其它所有域,列为(cf:cq)。
21.Reduce后输出的量有多大
22.找到离存数据最近的一台机器运行和这个数据相关的map任务,reduce是按照你整理出的key有多少个来决定的。一个机器很难说,处理的快的处理多一点,保持所有机器使用平衡。
23.Mapreduce掌握情况 和 hive hsql掌握情况
Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构
化的数据文件映射为一张数据库表,并提供完整的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行,通过自己的SQL 去查询分析需
要的内容,这套SQL 简称Hive SQL,使不熟悉mapreduce 的用户很方便的利用SQL 语言查询,汇总,分析数据。而mapreduce开发人员可以把
己写的mapper 和reducer 作为插件来支持Hive 做更复杂的数据分析。 它与关系型数据库的SQL 略有不同,但支持了绝大多数的语句如DDL、DML 以及常见的聚合函数、连接查询、条件查询。HIVE不适合用于联机
online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。 HIVE的特点:可伸缩(在Hadoop的集群上动态的添加设备),可扩展,容错,输入格式的松散耦合。
25.Datanode在什么情况下不备份
26.在配置文件中datanode的数量设置为1时
28.Hdfs体系结构
我们首先介绍HDFS的体系结构,HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。HDFS允许用户以文件的形式存储数据。从内部来看,文件被分成若干个数据块,而且这若干个数据块存放在一组DataNode上。NameNode执行文件系统的命名空间操作,比如打开、关闭、重命名文件或目录等,它也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写请求,并在NameNode的统一调度下进行数据块的创建、删除和复制工作。
NameNode和DataNode都被设计成可以在普通商用计算机上运行。这些计算机通常运行的是GNU/Linux操作系统。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署NameNode和DataNode。一个典型的部署场景是集群中的一台机器运行一个NameNode实例,其他机器分别运行一个DataNode实例。当然,并不排除一台机器运行多个DataNode实例的情况。集群中单一的NameNode的设计则大大简化了系统的架构。NameNode是所有HDFS元数据的管理者,用户数据永远不会经过NameNode。
33.数据库三大范式
34.第一范式,又称1NF,它指的是在一个应用中的数据都可以组织成由行和列的表格形式,且表格的任意一个行列交叉点即单元格,都不可再划分为行和列的形式,实际上任意一张表格都满足1NF; 第二范式,又称2NF,它指的是在满足1NF的基础上,一张数据表中的任何非主键字段都全部依赖于主键字段,没有任何非主键字段只依赖于主键字段的一部分。即,可以由主键字段来唯一的确定一条记录。比如学号+课程号的联合主键,可以唯一的确定某个成绩是哪个学员的哪门课的成绩,缺少学号或者缺少课程号,都不能确定成绩的意义。 第三范式,又称3NF,它是指在满足2NF的基础上,数据表的任何非主键字段之间都不产生函数依赖,即非主键字段之间没有依赖关系,全部只依赖于主键字段。例如将学员姓名和所属班级名称放在同一张表中是不科学的,因为学员依赖于班级,可将学员信息和班级信息单独存放,以满足3NF。
1.hive 实现统计的查询语句是什么?
Select phonenum,sum(upload+download) as ll from table group by phonenum
2.生产环境中为什么建议使用外部表?
因为外部表在hive中只是 保存映射信息,在hive中即使删除表也只是删除了元数据信息。
如今有 10 个文件夹 ,每个文件夹都有 1000000 个 url.如今让你找出top1000000url。
不思考歪斜,功能,运用 2 个 job,第一个 job 直接用 filesystem 读取 10 个文件夹作为map 输入,url 做 key,reduce 计算个 url 的 sum, 下一个 job map 顶用 url 作 key,运用-sum 作二次排序,reduce 中取 top10000000
第二种方法,建 hive 表 A,挂分区 channel,每个文件夹是一个分区.
select x.url,x.c from(select url,count(1) as c from A where channel ='' group by
url)x order by x.c desc limie 1000000;
6、hadoop 中 Combiner 的效果?
combiner 也是一个 reduce,它可以削减 map 到 reudce 的数据传输,进步 shuff 速度。牢记平均值不要用。需求输入=map 的输出,输出=reduce 的输入。
1、海量日志数据,提取出某日访问百度次数最多的那个 IP。
首先是这一天,并且是访问百度的日志中的 IP 取出来,逐个写入到一个大文件中。注意到IP 是 32 位的,最多有个 2^32 个 IP。同样可以采用映射的方法, 比如模 1000,把整个,大文件映射为 1000 个小文件,再找出每个小文中出现频率最大的 IP(可以采用 hash_map进行频率统计,然后再找出频率最大 的几个)及相应的频率。然后再在这 1000 个最大的IP 中,找出那个频率最大的 IP,即为所求。
或者如下阐述(雪域之鹰):
算法思想:分而治之+Hash
(1).IP 地址最多有 2^32=4G 种取值情况,所以不能完全加载到内存中处理;
(2).可以考虑采用“分而治之”的思想,按照 IP 地址的 Hash(IP)%1024 值,把海量 IP日志分别存储到 1024 个小文件中。这样,每个小文件最多包含 4MB 个 IP 地址;
(3).对于每一个小文件,可以构建一个 IP 为 key,出现次数为 value 的 Hash map,同时记录当前出现次数最多的那个 IP 地址;
(4).可以得到 1024 个小文件中的出现次数最多的 IP,再依据常规的排序算法得到总体上出现次数最多的 IP;
假设目前有一千万个记录(这些查询串的重复度比较高,虽然总数是 1 千万,但如果除去重复后,不超过 3 百万个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。),请你统计最热门的 10 个查询串,要求使用的内存不能超过 1G。
第一步、先对这批海量数据预处理,在 O(N)的时间内用 Hash 表完成统计
第二步、借助堆这个数据结构,找出 Top K,时间复杂度为 N‘logK。 即,借助堆结构,我们可以在 log 量级的时间内查找和调整/移动。因此,维护一个 K(该题目中是 10)大小的小根堆,然后遍历 300 万的 Query,分别 和根元素进行对比所以,我们最终的时间复杂度是:O(N) + N’*O(logK),(N 为 1000 万,N’为 300 万)或者:采用 trie 树,关键字域存该查询串出现的次数,没有出现为 0。最后用 10 个元素的最小推来对出现频率进行排序。
方案:顺序读文件中,对于每个词 x,取 hash(x)%5000,然后按照该值存到 5000 个小文件(记为 x0,x1,…x4999)中。这样每个文件大概是 200k 左右。 如果其中的有的文件超过了 1M 大小,还可以按照类似的方法继续往下分,直到分解得到
的小文件的大小都不超过 1M。 对每个小文件,统计每个文件中出现的词以及相应的频率(可以采用 trie 树/hash_map 等),
并取出出现频率最大的 100 个词(可以用含 100 个结 点的最小堆),并把 100 个词及相应的频率存入文件,这样又得到了 5000 个文件。下一步就是把这 5000 个文件进行归并(类似与归并排序)的过程了。
4、有 10 个文件,每个文件 1G,每个文件的每一行存放的都是用户的 query,每个文件的query 都可能重复。要求你按照 query 的频度排序。
方案 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),最后再进行合并。
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)
中,不对应的小文件不可能有相同的 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(注意会有一定的错误率)。
6、在 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 题类似的方法,进行划分小文件的方法。然后在小文件中找出不重复的整数,并排序。然后再进行归并,注意去除重复的元素。
7、腾讯面试题:给 40 亿个不重复的 unsigned int 的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那 40 亿个数当中?
方案 1:oo,申请 512M 的内存,一个 bit 位代表一个 unsigned int 值。读入 40 亿个数,设置相应的 bit 位,读入要查询的数,查看相应 bit 位是否为 1,为 1 表示存在,为 0 表示不存在。
方案 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、怎么在海量数据中找出重复次数最多的一个?
方案 1:先做 hash,然后求模映射为小文件,求出每个小文件中重复次数最多的一个,并记录重复次数。然后找出上一步求出的数据中重复次数最多的一个就是所求
9、上千万或上亿数据(有重复),统计其中出现次数最多的钱 N 个数据。
方案 1:上千万或上亿的数据,现在的机器的内存应该能存下。所以考虑采用 hash_map/搜索二叉树/红黑树等来进行统计次数。然后就是取出前 N 个出现次数最多的数据了
10、一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前 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)。
二、Hashing
适用范围:快速查找,删除的基本数据结构,通常需要总数据量可以放入内存
基本原理及要点:
hash 函数选择,针对字符串,整数,排列,具体相应的 hash 方法。
碰撞处理,一种是 open hashing,也称为拉链法;另一种就是 closed hashing,也称开
地址法,opened addressing。
扩展:
d-left hashing 中的 d 是多个的意思,我们先简化这个问题,看一看 2-left hashing。2-left hashing 指的是将一个哈希表分成长度相等的两半,分别叫做 T1 和 T2,给 T1 和 T2 分别配备一个哈希函数,h1 和 h2。在存储一个新的 key 时,同 时用两个哈希函数进行计算,得出两个地址 h1[key]和 h2[key]。这时需要检查 T1 中的 h1[key]位置和 T2 中的 h2[key]位置,哪一个 位置已经存储的(有碰撞的)key 比较多,然后将新 key 存储在负载少的位置。如果两边一样多,比如两个位置都为空或者都存储了一个 key,就把新 key 存储在左边的 T1 子表中,2-left 也由此而来。在查找一个 key 时,必须进行两次 hash,同时查找两个位置。
问题实例:
1).海量日志数据,提取出某日访问百度次数最多的那个 IP。
IP 的数目还是有限的,最多 2^32 个,所以可以考虑使用 hash 将 ip 直接存入内存,然后进行统计。
三、bit-map
适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是 int 的 10 倍以下
基本原理及要点:使用 bit 数组来表示某些元素是否存在,比如 8 位电话号码
扩展:bloom filter 可以看做是对 bit-map 的扩展
问题实例:
- 已知某个文件内包含一些电话号码,每个号码为 8 位数字,统计不同号码的个数。 8 位最多 99 999 999,大概需要 99m 个 bit,大概 10 几 m 字节的内存即可。
2)2.5 亿个整数中找出不重复的整数的个数,内存空间不足以容纳这 2.5 亿个整数。 将 bit-map 扩展一下,用 2bit 表示一个数即可,0 表示未出现,1 表示出现一次,2 表示出现 2 次及以上。或者我们不用 2bit 来进行表示,我们用两个 bit-map 即可模拟实现这个
四、堆
适用范围:海量数据前 n 大,并且 n 比较小,堆可以放入内存
基本原理及要点:最大堆求前 n 小,最小堆求前 n 大。方法,比如求前 n 小,我们比较当前 元素与最大堆里的最大元素,如果它小于最大元素,则应该替换那个最大元素。这样最后得到的 n 个元素就是最小的 n 个。适合大数据量,求前 n 小,n 的大小比较 小的情况,这样可以扫描一遍即可得到所有的前 n 元素,效率很高。 扩展:双堆,一个最大堆与一个最小堆结合,可以用来维护中位数。
问题实例:
1)100w 个数中找最大的前 100 个数。 用一个 100 个元素大小的最小堆即可。
五、双层桶划分—-其实本质上就是【分而治之】的思想,重在“分”的技巧上!
适用范围:第 k 大,中位数,不重复或重复的数字
基本原理及要点:因为元素范围很大,不能利用直接寻址表,所以通过多次划分,逐步确定范围,然后最后在一个可以接受的范围内进行。可以通过多次缩小,双层只是一个例子。
扩展:
问题实例:
1).2.5 亿个整数中找出不重复的整数的个数,内存空间不足以容纳这 2.5 亿个整数。 有点像鸽巢原理,整数个数为 2^32,也就是,我们可以将这 2^32 个数,划分为 2^8 个区域(比如用单个文件代表一个区域),然后将数据分离到不同的区域,然后不同的区域在利用bitmap 就可以直接解决了。也就是说只要有足够的磁盘空间,就可以很方便的解决。
2).5 亿个 int 找它们的中位数。 这个例子比上面那个更明显。首先我们 将 int 划分为 2^16 个区域,然后读取数据统计落到各个区域里的数的个数,之后我们根据统计结果就可以判断中位数落到那个区域,同时知道这个区域中的第 几大数刚好是中位数。然后第二次扫描我们只统计落在这个区域中的那些数就可以了。 实际上,如果不是 int 是 int64,我们可以经过 3 次这样的划分即可降低到可以接受 的程度。即可以先将 int64 分成 2^24 个区域,然后确定区域的第几大数,在将该区域分成 2^20 个子区域,然后确定是子区域的第几大数,然后子区域里 的数的个数只有 2^20,就可以直接利用 direct addr table 进行统计了。
八、外排序
适用范围:大数据的排序,去重
基本原理及要点:外排序的归并方法,置换选择败者树原理,最优归并树
扩展:
问题实例:
1).有一个 1G 大小的一个文件,里面每一行是一个词,词的大小不超过 16 个字节,内存限制大小是 1M。返回频数最高的 100 个词。 这个数据具有很明显的特点,词的大小为 16 个字节,但是内存只有 1m 做 hash 有些不够,所以可以用来排序。内存可以当输入缓冲区使用。
九、trie 树
适用范围:数据量大,重复多,但是数据种类小可以放入内存
基本原理及要点:实现方式,节点孩子的表示方式
扩展:压缩实现。
问题实例:
1).有 10 个文件,每个文件 1G,每个文件的每一行都存放的是用户的 query,每个文件的query 都可能重复。要你按照 query 的频度排序。
2).1000 万字符串,其中有些是相同的(重复),需要把重复的全部去掉,保留没有重复的字符串。请问怎么设计和实现?
3).寻找热门查询:查询串的重复度比较高,虽然总数是 1 千万,但如果除去重复后,不超过 3 百万个,每个不超过 255 字节。
十、分布式处理 mapreduce
适用范围:数据量大,但是数据种类小可以放入内存
基本原理及要点:将数据交给不同的机器去处理,数据划分,结果归约。
扩展:
问题实例:
2).海量数据分布在 100 台电脑中,想个办法高效统计出这批数据的 TOP10。
3).一共有 N 个机器,每个机器上有 N 个数。每个机器最多存 O(N)个数并对它们操作。如何找到 N^2 个数的中数(median)?
经典问题分析
上千万 or 亿数据(有重复),统计其中出现次数最多的前 N 个数据,分两种情况:可一次读入内存,不可一次读入。
可用思路:trie 树+堆,数据库索引,划分子集分别统计,hash,分布式计算,近似统计,
外排序
所谓的是否能一次读入内存,实际上应该指去除重复后的数据量。如果去重后数据可以放入内存,我们可以为数据建立字典,比如通过 map,hashmap,trie,然后直接进行统计即可。当然在更新每条数据的出现次数的时候,我们可以利用一个堆来维护出现次数最多的前 N 个数据,当 然这样导致维护次数增加,不如完全统计后在求前 N 大效率高。
如果数据无法放入内存。一方面我们可以考虑上面的字典方法能否被改进以适应这种情形,可以做的改变就是将字典存放到硬盘上,而不是内存,这可以参考数据库的存储方法。
当然还有更好的方法,就是可以采用分布式计算,基本上就是 map-reduce 过程, 首先可以根据数据值或者把数据 hash(md5)后的值,将数据按照范围划分到不同的机子,最好可以让数据划分后可以一次读入内存,这样不同的机子负责处 理各种的数值范围,实际上就是 map。得到结果后,各个机子只需拿出各自的出现次数最多的前 N 个数据,然后汇总,选出所有的数据中出现次数最多的前 N 个数 据,这实际上就是 reduce 过程。
实际上可能想直接将数据均分到不同的机子上进行处理,这样是无法得到正确的解的。因为一个数据可能被均分到不同的机子上,而另一个则可能完全聚集到一个机子上,同时还可能存在具有相同数目的数据。比如我们要找出现次数最多的前 100 个,我 们将 1000 万的数据分布到 10 台机器上,找到每台出现次数最多的前 100 个,归并之后这样不能保证找到真正的第 100 个,因为比如出现次数最多的第 100 个可能有 1 万个,但是它被分到了10 台机子,这样在每台上只有 1 千 个,假设这些机子排名在 1000 个之前的那些都是单独分布在一台机子上的,比如有 1001 个,这样本来具有 1 万个的这个就会被淘汰,即使我们让每台机子选 出出现次数最多的 1000 个再归并,仍然会出错,因为可能存在大量个数为1001 个的发生聚集。因此不能将数据随便均分到不同机子上,而是要根据 hash 后的值将它们映射到不同的机子上处理,让不同的机器处理一个数值范围。
而外排序的方法会消耗大量的 IO,效率不会很高。而上面的分布式方法,也可以用于单机版本,也就是将总的数据根据值的范围,划分成多个不同的子文件,然后逐个处理。处理完毕之后再对这些单词的及其出现频率进行一个归并。实际上就可以利用一个外排序的归并过程。
另外,还可以考虑近似计算,也就是我们可以通过结合自然语言属性,只将那些真正实际中出现最多的那些词作为一个字典,使得这个规模可以放入内存。
1、你们的集群规模?
开发集群:10 台(8 台可用)8 核 cpu
2、你们的数据是用什么导入到数据库的?导入到什么数据库?
处理之前的导入:通过 hadoop 命令导入到 hdfs 文件系统
处理完成之后的导出:利用 hive 处理完成之后的数据,通过 sqoop 导出到 mysql 数据库中,以供报表层使用。
3、你们业务数据量多大?有多少行数据?(面试了三家,都问这个问题)
开发时使用的是部分数据,不是全量数据,有将近一亿行(8、9 千万,具体不详,一般开发中也没人会特别关心这个问题)
4、你们处理数据是直接读数据库的数据还是读文本数据?
将日志数据导入到 hdfs 之后进行处理
5、你们写hive 的hql 语句,大概有多少条?
不清楚,我自己写的时候也没有做过统计
6、你们提交的 job 任务大概有多少个?这些 job 执行完大概用多少时间?(面试了三家,都问这个问题)
没统计过,加上测试的,会与很多
9、你在项目中遇到了哪些难题,是怎么解决的?
某些任务执行时间过长,且失败率过高,检查日志后发现没有执行完就失败,原因出在hadoop 的 job 的 timeout 过短(相对于集群的能力来说),设置长一点即可
10、你自己写过 udf 函数么?写了哪些?
如简单的时间转化函数,
13、一个网络商城 1 天大概产生多少 G 的日志? 4tb
14、大概有多少条日志记录(在不清洗的情况下)? 7-8 百万条
15、日访问量大概有多少个?百万
17、我们的日志是不是除了 apache 的访问日志是不是还有其他的日志?关注信息 有一千万条短信,有重复,以文本文件的形式保存,一行一条,有重复。 请用 5 分钟时间,找出重复出现最多的前 10 条。
分析:
常规方法是先排序,在遍历一次,找出重复最多的前 10 条。但是排序的算法复杂度最低为nlgn。
可以设计一个 hash_table, hash_map
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!