大数据处理技术导论(5) | Datawhale组队学习46期


项目地址 https://github.com/datawhalechina/juicy-bigdata,感谢项目团队的付出。
本次学习任务是完成 期中大作业

6. 1 面试题

6.1.1 简述Hadoop小文件弊端

过多的小文件会加重 namenode 负担,增加寻址成本,降低处理效率,最终导致集群整体性能下降。

6.1.2 HDFS中DataNode挂掉如何处理?

HDFS namenodeHDFS datenode 具有周期性心跳通信机制,检查发现某个数据的副本数量小于冗余因子时,说明有 datanode 节点宕机,HDFS 就会启动数据冗余复制,为它生成新的副本。

登录故障节点,执行如下命令:

hdfs --daemon start datanode

6.1.3 HDFS中NameNode挂掉如何处理?

HDFS namenode 宕机时,首先到远程挂载的网络文件系统中获取备份的元数据信息,放到第二名称节点上进行恢复,并把第二名称节点作为名称节点来使用。

6.1.4 HBase读写流程?

  • hbase 写流程

1、客户端写入数据的流程
1)由客户端发起写数据请求,首先会与zookeeper建立连接
2)从 zookeeper 中获取 hbase:meta 表被哪一个 regionserve所管理
3)连接 hbase:meta 表中获取对应的 regionserver 地址 (从meta表中获取当前要写入数据的表对应的region所管理的regionserver) 只会返回一个 regionserver 地址
4)与要写入数据的 regionserver 建立连接,然后开始写入数据,将数据首先会写入到HLog,然后将数据写入到对应store模块中的memstore中
(可能会写多个),Hlog 写入磁盘后,memstore 开始写入磁盘,写入完毕后,表示 hbase 数据写入完成。

2、服务器内部的操作
异步操作
5)随着客户端不断地写入数据,memstore中的数据会越来多,当内存中的数据达到阈值(128M/1h)的时候,放入到blockchache中,生成新的memstore接收用户过来的数据,然后当blockcache的大小达到一定阈值(0.85)的时候,开始触发flush机制,将数据最终刷新到HDFS中形成小的Hfile文件。

6)随着不断地刷新,storefile不断地在HDFS上生成小HFIle文件,当小的HFile文件达到阈值的时候(3个及3个以上),就会触发Compaction机制,将小的HFile合并成一个大的HFile.

7)随着不断地合并,大的HFile文件会越来越大,当达到一定阈值(最终10G)的时候,会触发分裂机制(split),将大的HFile文件进行一分为二,同时管理这个大的HFile的region也会被一分为二,形成两个新的region和两个新的HFile文件,一对一的进行管理,将原来旧的region和分裂之前大的HFile文件慢慢地就会下线处理。

  • hbase 读流程
    1)是由客户端发起读取数据的请求,首先会与zookeeper建立连接
    2)从zookeeper中获取一个hbase:meta表位置信息,被哪一个regionserver所管理着
    hbase:meta表:hbase的元数据表,在这个表中存储了自定义表相关的元数据,包括表名,表有哪些列簇,表有哪些reguion,每个region存储的位置,每个region被哪个regionserver所管理,这个表也是存储在某一个region上的,并且这个meta表只会被一个regionserver所管理。这个表的位置信息只有zookeeper知道。
    3)连接这个meta表对应的regionserver,从meta表中获取当前你要读取的这个表对应的regionsever是谁。
    当一个表多个region怎么办呢?
    如果我们获取数据是以get的方式,只会返回一个regionserver
    如果我们获取数据是以scan的方式,会将所有的region对应的regionserver的地址全部返回。
    4)连接要读取表的对应的regionserver,从regionserver上的开始读取数据:
    读取顺序:memstore–>blockcache–>storefile–>Hfile中
    注意:如果是scan操作,就不仅仅去blockcache了,而是所有都会去找。

6.1.5 MapReduce为什么一定要有Shuffle过程

Shuffle 是 MapReduce 整个工作流程的核心环节。是指针对Map输出结果进行分区、排序和合并等处理,并交给Reduce的过程。

6.1.6 MapReduce中的三次排序

1)当map函数产生输出时,会首先写入内存的环形缓冲区,当达到设定的阀值,在刷写磁盘之前,后台线程会将缓冲区的数据划分成相应的分区。在每个分区中,后台线程按键进行内排序

2)在Map任务完成之前,磁盘上存在多个已经分好区,并排好序的,大小和缓冲区一样的溢写文件,这时溢写文件将被合并成一个已分区且已排序的输出文件。由于溢写文件已经经过第一次排序,所有合并文件只需要再做一次排序即可使输出文件整体有序。

3)在reduce阶段,需要将多个Map任务的输出文件copy到ReduceTask中后合并,由于经过第二次排序,所以合并文件时只需再做一次排序即可使输出文件整体有序

在这3次排序中第一次是内存缓冲区做的内排序,使用的算法是快速排序,第二次排序和第三次排序都是在文件合并阶段发生的,使用的是归并排序。

6.1.7 MapReduce为什么不能产生过多小文件

默认情况下,TextInputFormat对任务的切片机制是按照文件规划切片,不管有多少个小文件,都会是单独的切片,都会交给一个maptask,这样,如果有大量的小文件就会产生大量的maptask,处理效率低。

6.2 实战

python hadoop streaming 配置参数含义:
-D stream.map.output.field.separator :设置 map 输出中 key 和 value 的分隔符
-D stream.num.map.output.key.fields :设置 map 程序分隔符的位置,该位置之前的部分作为 key,之后的部分作为 value
-D map.output.key.field.separator : 设置 map 输出分区时 key 内部的分割符
-D mapreduce.partition.keypartitioner.options : 指定分桶时,key 按照分隔符切割后,其中用于分桶 key 所占的列数(配合 -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 使用)
-D stream.reduce.output.field.separator:设置 reduce 输出中 key 和 value 的分隔符
-D stream.num.reduce.output.key.fields:设置 reduce 程序分隔符的位置

'mapreduce.partition.keypartitioner.options':'-k1,2' 表示设置按前两个字段进行分区
根据自己的理解,完成了方法1的部分代码:

from mrjob.job import MRJob
from mrjob.step import MRStep


class Project1(MRJob):
    def mapper(self, _, line):
        userID, locID, time = line.split(",")
        #填入mapper的具体步骤
        yield userID, 1
        yield locID, 1
        yield time, 1

    def combiner(self, key, values):
        #填入combiner的具体步骤
        pass


    def reducer_init(self):
        # 填入reducer_init的具体步骤
        pass


    def reducer(self, key, values):
        userID, locID = key.split(",")
        # 填入reducer的具体步骤
        yield key, sum(values)

    def reducer_sort(self, key, _):
        userID, locID, v = key.split("#")
        yield locID, f'{userID},{v}'

    SORT_VALUES = True

    def steps(self):
        #填入配置参数
        JOBCONF1 = {
            'mapreduce.map.output.key.field.separator': ",",
            'mapreduce.partition.keypartitioner.options': '-k1,1 -k2,2',
            # Below is not necessary, but you can still do it
            # 'mapreduce.job.output.key.comparator.class': 'org.apache.hadoop.mapreduce.lib.partition.KeyFieldBasedComparator',
            # 'mapreduce.partition.keycomparator.options': '-k1,1 -k2,2',
        }
        # 填入配置参数
        JOBCONF2 = {
            'mapreduce.map.output.key.field.separator': "#",
            'mapreduce.partition.keypartitioner.options': '-k1,1',
            'mapreduce.job.output.key.comparator.class': 'org.apache.hadoop.mapreduce.lib.partition.KeyFieldBasedComparator',
            'mapreduce.partition.keycomparator.options': '-k1,1',
        }
        return [
            MRStep(jobconf=JOBCONF1, mapper=self.mapper, combiner=self.combiner, reducer_init=self.reducer_init,
                   reducer=self.reducer),
            MRStep(jobconf=JOBCONF2, reducer=self.reducer_sort)
        ]


if __name__ == '__main__':
    Project1.run()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值