haoop笔记
8:00 2019/3/141:什么是hadoop? hadoop是解决大数据问题的一整套技术方案 2:hadoop的组成? 核心框架 分布式文件系统 分布式计算框架 分布式资源分配框架 hadoop对象存储 机器计算 3:hadoop 云计算 大数据 微服务 人工智能关系 参见word学习文档 1. 现阶段,云计算的两大底层支撑技术为“虚拟化”和“大数据技术” 2. 而HADOOP则是云计算的PaaS层的解决方案之一,并不等同于PaaS,更不等同于云计算本身。 4:大数据项目的通常结构 采集数据 数据分析统计 数据展示 5:大数据项目的通常技术架构 见画图 Hadoop Common: 为其他Hadoop模块提供基础设施。 Hadoop DFS: 一个高可靠、高吞吐量的分布式文件系统 Hadoop MapReduce: 一个分布式的离线并行计算框架 Hadoop YARN: 一个新的MapReduce框架,任务调度与资源管理 6:安装一个伪分布式的hdfs a:准备安装介质 hadoop-2.8.2.tar.gz b:把安装介质上传到linux c:在linux使用hostname命令确认主机名 d:编辑/etc/hosts文件 完成ip地址和主机名的映射 在分布式的每一台机器中都需要把所有机器的ip地址和主机名的映射关系配置 注意:关闭每台机器的防火墙 systemctl stop firewalld.service 关闭 systemctl disable firewalld.service 禁止开机启动 e:配置ssh免密码登录 f:从/export/software/下面把hadoop-2.8.2.tar.gz 解压到/export/servers/下 常用目录说明: bin sbin hadoop常用的命令目录 配置到/etc/profile中 etc hadoop常用配置文件目录 share hadoop核心jar包目录 g:完成配置文件 hadoop-env.sh 配置java环境 core-site.xml hadoop核心配置 hdfs-site.xml hdfs核心配置 mapred-site.xml mr的核心配置 yarn-site.xml yarn的核心配置 h:格式化namenode环境 创建namenode保存数据的环境 hdfs namenode -format i:使用命令启动hdfs start-dfs.sh start-yarm.sh 执行完成回到命令行 可以使用jps查看关键进程是否已经在运行 namenode SecondaryNameNode datanode 还要从web页面使用http连接管理页面查看 http://192.168.21.134:50070 可以看到hdfs的管理页面 证明hdfs安装并启动成功 http://192.168.21.134:8088 可以看到mr计算任务的管理页面 证明mr yarn安装并启动成功 注意事项: a:如果某个进程没有正确启动 要学会看日志 eg: starting namenode, logging to /export/service/hadoop-2.8.2/logs/hadoop-root-namenode-text4.out 以上输出信息是说明namenode启动过程写入了哪一个日志 假设最终namenode没有启动成功 需要打开日志查看原因 b:常用命令中还有单独启动某个进程的命令 hdfs单独启动各个进程服务 hadoop-daemon.sh start namenode hadoop-daemon.sh start datanode hadoop-daemon.sh start secondarynamenode yarn单独启动各个进程服务 yarn-daemon.sh start resourcemanager yarn-daemon.sh start nodemanager 7:安装分布式 a:已有一台虚拟机基础环境配置完毕 text4 b:利用有的虚拟机复制出2台 一共3台虚拟机 复制以已及每台配置网络 参照文档即可 b1:配置每台机器的主机名(提前规划好)(text4 text5 text6) text4 —— namenode datanode secondarynamenode resourcemanager nodemanager text5 —— datanode nodemanager text6 —— datanode nodemanager b2:修改网卡配置(每台机器的ip地址是提前规划好)(192.168.21.134 192.168.21.138 192.168.21.139) b3:修改/etc/hosts文件 配置每台机器和ip地址的映射关系 c:配置3台之间可以ssh免密登录 ssh-keygen ssh-copy-id root@机器名称 c1:配置text4 text5 text6互相都可以ssh免密登录 c2:选取一台虚拟机做namenode 配置它到text5 text6免密登录 可以在多个机器之间使用scp传输文件 如果不需要输入密码 则ssh免密配置正确 scp -r(目录整体复制) 目录/文件名称 用户名@机器名:目的机器的路径 d:确保所有机器防火墙都是关闭 e:修改每台机器的hadoop配置文件 e1:把每个block(数据块)修改为有2个备份 e2:把namenode相关的ip地址都修改成了主机名 f:把已有的namenode datanode配置好的数据文件夹删除 g:在namenode节点 执行namenode格式化 hdfs namenode -format h:在namenode执行start-dfs.sh 启动hdfs 使用jps查看每台机器的进程规划 8:namenode datanode 数据目录结构讲解 namenode: 存放数据目录位置 /data/hadoop/dfs/name datanode: 存放数据目录位置 /data/hadoop/dfs/data 实际上传到datanote中的文件数据都是保存在finalized目录下 eg:从linux 往hdfs上传一个文件 a0001.data 因为配置的block副本是2分 所以3台datanode节点中只有text4 text5有数据 经验证和原有的上传文件内容一致 就以2个副本的方式保证了数据的完整性 eg:从linux往hdfs上传一个大于128m的文件hadoop-2.8.2.tar.gz(240m) 因为它大于128m(128m是hdfs中默认的一个block的大小) 所以这个压缩包被分成2个block上传 每个block还是2个备份文件 hdfs dfs -put 待上传的文件名称 要上传的hdfs的目的地路径 secondarynamenode: 存放数据目录位置 /data/hadoop/tmp/dfs/namesecondary start-all.sh 启动所有的Hadoop守护进程。包括NameNode、 Secondary NameNode、DataNode、JobTracker、 TaskTrack stop-all.sh 停止所有的Hadoop守护进程。包括NameNode、 Secondary NameNode、DataNode、JobTracker、 TaskTrack start-dfs.sh 启动Hadoop HDFS守护进程NameNode、SecondaryNameNode和DataNode stop-dfs.sh 停止Hadoop HDFS守护进程NameNode、SecondaryNameNode和DataNode hadoop-daemons.sh start namenode 单独启动NameNode守护进程 hadoop-daemons.sh stop namenode 单独停止NameNode守护进程 hadoop-daemons.sh start datanode 单独启动DataNode守护进程 hadoop-daemons.sh stop datanode 单独停止DataNode守护进程 hadoop-daemons.sh start secondarynamenode 单独启动SecondaryNameNode守护进程 hadoop-daemons.sh stop secondarynamenode 单独停止SecondaryNameNode守护进程 start-mapred.sh 启动Hadoop MapReduce守护进程JobTracker和TaskTracker stop-mapred.sh 停止Hadoop MapReduce守护进程JobTracker和TaskTracker hadoop-daemons.sh start jobtracker 单独启动JobTracker守护进程 hadoop-daemons.sh stop jobtracker 单独停止JobTracker守护进程 hadoop-daemons.sh start tasktracker 单独启动TaskTracker守护进程 hadoop-daemons.sh stop tasktracker 单独启动TaskTracker守护进程 sc文件:hdfs dfs -put aa.data /logs io nio aio思想 b:编写hdfs java客户端程序 b1:建立开发工程 建立maven工程 在pom文件中引入开发hdfs客户端需要的jar包 <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.8.2</version> </dependency> 建立普通的java工程 引入jar包 目前只是开发hdfs的java客户端 只引入hadoop安装包下share目录中common和hdfs jar包即可 b2:规划包结构 b3:编写demo测试类 创建一个配置信息封装对象(客户端处理hdfs 编写mr 处理hive 处理hase都是需要配置信息) 创建一个文件系统的客户端对象 方便处理文件数据 对文件的增删改查的java api接口使用 对某个指定目录下所有文件或者目录基本信息的查看 hdfs复习点: 1:hdfs就是一个文件系统 在操作系统之上。 通常操作系统针对hdfs叫做本地 2:hdfs的重要组成部分 namenode:存储元数据 元数据中数据都有什么? a:某个文件的某个block存储在哪个datanode上 b:每个datanode资源使用情况 c:每个文件的属性 修改时间等等信息 datanode: 真正存储文件数据 所以一个hdfs没有namenode或者namenode出问题则不能再使用 但是如果是datanode出问题 只可能是数据部分丢失 而不是hdfs不能使用 secondary namenode namenode datanode 关系 https://www.cnblogs.com/chenyaling/p/5521464.html 3:基本的理论知识 13:49 2019/3/1413:49 2019/3/14https://blog.csdn.net/lvtula/article/details/82354989 a:hdfs中namenode datanode secondarynamenode 某些主要目录或者文件的作用 https://blog.csdn.net/baiye_xing/article/details/76268495 namenode:edits fsimage version datanode:finalized version blc文件每个都有一个meta文件 secondarynamenode:edits fsimage b:namenode中edits和fsimage的作用以及其和内存的相互关系 c:namenode和secondarynamenode的工作机制 d:hdfs写流程 hdfs读流程 4:hdfs shell 5:java api操作hdfs HA hadoop集群搭建步骤: 1:对集群每一台机器需要安装什么服务进行规划。 text4:zk nn dn zkfc jn nm rm text5: zk nn dn zkfc jn nm rm text6: zk dn jn nm 2:准备每台机器的基本环境 a:3台机器之间需要免密登录 b:每台机器必须安装好jdk 8.0以上 c:集群每台机器之间时间同步 c1:设定每台机器的正确时区 timedatectl set-timezone Asia/Shanghai timedatectl set-local-rtc 1 date c2:选择集群中一台机器为主 master 让其它机器和这台机器完成时间同步 使用rdate完成集群之间时间同步 具体操作请参见保存的时间同步页面说明 3:修改hadoop集群的配置文件 按照样例配置文件修改即可 4:启动集群过程(安装过程的启动) a:启动zk b: 启动jn hadoop-daemon.sh start journalnode c:格式化nn (选取text4) d:格式化zkfc hdfs zkfc -formatZK e:把text4的nn结构复制到text5 先在text4启动nn 在text5执行 hdfs namenode bootstrapstandby 如果出现此时在text5并没有能成功复制text4的nn的目录机构 则直接可以从text4复制到text5 完成2台nn之间的复制 f:启动集群 zk启动 zkfc启动 start-dfs.sh start-yarn.sh(如果那个rm没有启动 直接可以使用守护进程) 1:什么是hadoop? hadoop是解决大数据问题的一整套技术方案 2:hadoop的组成? 核心框架 分布式文件系统 分布式计算框架 分布式资源分配框架 hadoop对象存储 机器计算 3:hadoop 云计算 大数据 微服务 人工智能关系 参见word学习文档 4:大数据项目的通常结构 采集数据 数据分析统计 数据展示 hadoop-env.sh 配置java环境 core-site.xml hadoop核心配置 hdfs-site.xml hdfs核心配置 mapred-site.xml mr的核心配置 yarn-site.xml yarn的核心配置 namenode: 存放数据目录位置 /data/hadoop/dfs/name namenode的数据文件: namenode保存的是整个hdfs的元数据 eg: 上传文件的所属 大小 修改日期 以及文件每一个block所在哪个datanode对应关系都是namenode元数据保存的 edtis:保存的是最近的日志记录(namenode接收到的命令以及解析) fsimage:保存的是namenode内存信息的镜像 seen_txid:集群状态的恢复标识 步骤解析1: 上传 1、根namenode通信请求上传文件,namenode检查目标文件是否已存在,父目录是否存在 2、namenode返回是否可以上传 3、client请求第一个 block该传输到哪些datanode服务器上 4、namenode返回3个datanode服务器ABC 5、client请求3台dn中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将真个pipeline建立完成,逐级返回客户端 6、client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位,A收到一个packet就会传给B,B传给C;A每传一个packet会放入一个应答队列等待应答 7、当一个block传输完成之后,client再次请求namenode上传第二个block的服务器。 详细步骤解析2: 下载 1、跟namenode通信查询元数据,找到文件块所在的datanode服务器 2、挑选一台datanode(就近原则,然后随机)服务器,请求建立socket流 3、datanode开始发送数据(从磁盘里面读取数据放入流,以packet为单位来做校验) 4、客户端以packet为单位接收,现在本地缓存,然后写入目标文件 HA hadoop集群搭建步骤: 1:对集群每一台机器需要安装什么服务进行规划。 text4:zk nn dn zkfc jn nm rm text5: zk nn dn zkfc jn nm rm text6: zk dn jn nm 2:准备每台机器的基本环境 a:3台机器之间需要免密登录 b:每台机器必须安装好jdk 8.0以上 c:集群每台机器之间时间同步 c1:设定每台机器的正确时区 timedatectl set-timezone Asia/Shanghai timedatectl set-local-rtc 1 date c2:选择集群中一台机器为主 master 让其它机器和这台机器完成时间同步 使用rdate完成集群之间时间同步 具体操作请参见保存的时间同步页面说明 3:修改hadoop集群的配置文件 按照样例配置文件修改即可 4:启动集群过程(安装过程的启动) a:启动zk b: 启动jn hadoop-daemon.sh start journalnode c:格式化nn (选取text4) d:格式化zkfc hdfs zkfc -formatZK e:把text4的nn结构复制到text5 先在text4启动nn 在text5执行 hdfs namenode bootstrapstandby 如果出现此时在text5并没有能成功复制text4的nn的目录机构 则直接可以从text4复制到text5 完成2台nn之间的复制 f:启动集群 zk启动 zkfc启动 start-dfs.sh start-yarn.sh(如果那个rm没有启动 直接可以使用守护进程) Zookeeper是一个分布式协调服务;就是为用户的分布式应用程序提供协调服务 A、zookeeper是为别的分布式程序服务的 B、Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务) C、Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务…… D、虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能: 管理(存储,读取)用户程序提交的数据; 并为用户程序提供数据节点监听服务; 1、Znode有两种类型: 短暂(ephemeral)(断开连接自己删除) 持久(persistent)(断开连接不删除) 2、Znode有四种形式的目录节点(默认是persistent ) PERSISTENT PERSISTENT_SEQUENTIAL(持久序列/test0000000019 ) EPHEMERAL EPHEMERAL_SEQUENTIAL 3、创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护 4、在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序 1、Zookeeper:一个leader,多个follower组成的集群 2、全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的 3、分布式读写,更新请求转发,由leader实施 4、更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行 5、数据更新原子性,一次数据更新要么成功,要么失败 6、实时性,在一定时间范围内,client能读到最新数据 4.2. zookeeper数据结构 1、层次化的目录结构,命名符合常规文件系统规范(见下图) 2、每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识 3、节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点,下一页详细讲解) 4、客户端应用可以在节点上设置监视器(后续详细讲解) yarn的流程:1:客户端向yarn发送请求,开始运行job 2:resourcemanager反馈信息,把切片资源在hdfs的存放目录发送给客户端 3:客户端调用fileinputformat的getsplits方法完成数据切片计算 4:客户端把切片资源上传到yarn指定的hdfs目录下 5:通知yarn资源已上传,请分配mrappmaster开始执行任务 6:yarn吧客户端待执行的任务放入任务队列 7:resourcemanager从某个namemodemanager选择一台机器准备运行环境(根据充足的空间判定) 8:制定后 mappermaster从指定位置获取任务资源(job.split jar job.xml) 9:mappermaster从job.spilit中确认需要运行多少maptask,想yarn的rm申请运行资源 10resourcemanager给mrappmaster反馈可用的运行maptask的资源 11mrappmaster根据yarn提供的资源开始运行maptask 12:当maptask运行完毕,mrappmaster会知道 13:重复申请资源的步骤 开始运行reducetask 14当reducetask运行完毕 回收mappmaster的占用资源 yarn只是一个分布式资源分配系统,核心是resourcemanager和nodemanager yarn只负责资源分配,不负责xuanfayunsuan sheff运行流程 map()输出结果->内存(环形缓冲区,当内存大小达到指定数值,如80%,开始溢写到本地磁盘) 溢写之前,进行了分区partition操作,分区的目的在于数据的reduce指向,分区后进行二次排序,第一次是对partitions进行排序, 第二次对各个partition中的数据进行排序,之后如果设置了combine,就会执行类似reduce的合并操作,还可以再进行压缩, 因为reduce在拷贝文件时消耗的资源与文件大小成正比 内存在达到一定比例时,开始溢写到磁盘上 当文件数据达到一定大小时,本地磁盘上会有很多溢写文件,需要再进行合并merge成一个文件 reduce拷贝copy这些文件,然后进行归并排序(再次merge),合并为一个文件作为reduce的输入数据 wordcount流程: 计算在某个目录下有n多份文件,每个文件中有n多个单词,计算每个单词出现的个数 1:yarn的resourcemanager会反馈给客户端吧切片信息存放到那个目录下,然后客户端通过调用fileinputformat的getsplits进行切片机算,得到3样数据( a:切片的描述信息jobsplit b:计算所有单词个数的jar包 c:把这次计算任务job的配置信息放入文件中的job。xml ) 2:放置后会通知yarn分配mappermaster任务,会挑选一台nodemanager机器作为mrappmaster 3:mrappmaster会根据job的描述信息 根据job。split确定需要几个 maptaskxiang yarn申请计算资源, 4:yarn反馈给mrappmaster明确的可用的计算资源 5:mrappmaster根据yarn提供的资源开始运行maptask 6:maptask从hdfs中依据job。spilt的描述的数据从hdfs 复制到本地的server,调用wordcount程序完成计算 (计算:maptask运行map方法,map方法接受的是文本中的每一行的偏移量, v是每次map方法执行时读取的一行单词) 7:map阶段执行完后在执行reduce阶段, reduce完成对map阶段输出的解过进行合并操作 reducetask的数量是程序员根据需求制定,如果不指定是1 8:reduce完成后会输出问结果文件 1yarn的resourcemanager会反馈给客户端切片信息放置的目录,然后客户端通过调用fileinputformat的getsplits进行切片机算,得到三杨树局,
(a切片的描述信息b机损所有单词的jar包c将job的藐视信息放入job。xml) 2客户端放置后通知yarn分配mrappmaster执行任务,yarn会挑选一台namenodemanager作为mrappmaster 3mrappmaster会从指定位置下获取资源,根据job。splits计算需要多少个maptask,并向yarn申请及资源 4yarn反馈资源,mrappmaster给句yarn提供的资源开始运行maptask 5maptask从hdfs中依据job。split的描述的数据从hdfs复制到本地的server,调用wordcount完成计算 1.hadoop运行原理 MapReduce HDFS 分布式文件系统(HDFS客户端的读写流程) 写: 客户端接收用户数据,并缓存到本地 当缓存足够一个HDFS大小的时候 客户端同NameNode通讯注册一个新的块 注册成功后 NameNode给客户端返回一个DateNode的列表 客户端向列表中的第一个DateNode写入块 收到所有的DateNode确认信息后,客户端删除本地缓存 客户端继续发送下一个块 重复以上步骤 所有数据发送完成后,写操作完成 读: 客户端与NameNode通讯获取文件的块位置信息,包括块的所有冗余备份的位置信息:DateNode列表 客户端获取文件位置信息后直接同有文件块的DateNode通讯,读取文件 如果第一个DateNode无法连接,客户端将自动联系下一个DateNode 如果块数据的校验值出错,则客户端需要向NameNode报告,并自动联系下一个DateNode 客户端的hadoop环境:与集群的hadoop包一样 集群入口:core-site.xml、fs.default.name 缓存块大小:fs.block.size 存多少份:fs.replication 2.mapreduce的原理 mapreduce的原理:一个MapReduce框架由一个单独的master JobTracker和集群节点每一个slave TaskTracker共同组成。 master负责调度构成一个作业的所有任务,在这些slave上,master监控它们的执行,并且重新执行已经失败的任务。 而slave仅负责执行由maste指派的任务。 3.Mapreduce数据倾斜是什么意思?怎么处理? Mapreduce数据倾斜是指我们在分片的时候导不同分片上的数据不均,导致这些分片在并行处理的时候,有的分片执行事件过长, 有的执行时间过短,导致总的执行时间过长的一种现象,通常是由:1.map端的key值过多或者有空值; 2.业务本身的特性;3.某些sql就有数据倾斜;4.建表的时候考虑不周等原因造成的。 处理:* a:增加reducetask的数量 * b:在不改变整体统计结果的前提下,可以修改key的设定方式 * c:在做关联时,尽量避免reducetask端的join 可以使用maptask端的join 4.combiner的作用,使用时机? Combiner其实也是一种reduce操作,是map运算的后续操作,在map后续对于相同key值做一个简单合并,减小后续的reduce的计算压力。 数据量小的时候,且输入的结果不会影响到reduce输入的结果,且不做平均值的时候,用基于map端之后shuffle端之前的reduce操作。 1 5.MapReduce–如何设置Reducer的个数 1.在代码中通过:JobConf.setNumReduceTasks(Int numOfReduceTasks)方法设置reducer的个数; 2.在hive中:set mapred.reduce.tasks; 3.reducer的最优个数与集群中可用的reducer的任务槽数相关,一般设置比总槽数微少一些的reducer数量;Hadoop文档中推荐了两个公式: 0.95*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum 1.75*NUMBER_OF_NODES*mapred.tasktracker.reduce.tasks.maximum 备注:NUMBER_OF_NODES是集群中的计算节点个数; mapred.tasktracker.reduce.tasks.maximum:每个节点所分配的reducer任务槽的个数; 6.MR的过程: input —–>spilt—–>map—–>combiner—–>shuffer—> partition—–>reduce—–>output spilt :对数据进行split分片处理,产生K1值和V1值,传给map map: 数据整理,把数据整理成K2和V2, combiner:如果map输出内容比较多,reduce计算比较慢,我们可以加个combiner map端的本地化reduce,减少map输出; shuffer:相同的数据放到一个分区 partiton:如果reduce不是一个,shuffler做一个分区,将相同的K值,分到一个区; 排序方式:hash方式; reduce:shuffer分区结束后交给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上。 7.MR怎么处理小文件: 1.输入过程合并处理:1.在linux 10000个文件上传到HDFS时候,用脚本形成二进制文件流上传,上传的过程中就合并成了一个文件。 2.如果在hdfs中有大量小文件,首先进行清洗,把10000个小文件清洗成一个文件或者几个文件,写个map(1.前提10000小文件格式相同,
2.不会有太多的小文件 一千万个小文件,首先会在操作系统上传时就处理完了,但是要是问可以说,分批做,每一万个存储到一个目录中,对一个目录进行map清洗)),其次,进行reduce计算 清洗会产生数据倾斜: 很多小文件是数据倾斜(解决方法):2.1.基于map端的离散方法;2.2.combiner; //hdfs为什么怕很多小文件:因为很多小文件的话也会占用namenode目录树的空间,一般一个文件的元数据会占到150字节;
而NameNode是要接收集群中所有的DataNode的心跳信息,来确定元数据的信息变化的,当小文件一旦过多,namenode的元数据读取就会变慢。
(在HDFS中,namenode将文件系统中的元数据存储在内存中,因此,HDFS所能存储的文件数量会受到namenode内存的限制) 8.如何从编程的角度讲解MR的过程 对数据进行底层默认分片把数据解析成k1/v1形式传给map; Map对k1/v1进行截取、运算等操作生成k2/v2传给reduce; Reduce对相同key的值进行计算,生成最终结果k3/v3输出 9.MR中有没有只有Map的 有,只对数据进行分片,解析成key/value形式后,直接输出结果不进行reduce端的去重和数组化的。 eg:比如说我把所有的经过split(map)形成的元素都放到context的key做标签就不会用到reduce。 10.Map输出端的组成部份 Combiner、shuffle、partitioner 11.如何用MR实现join 1) reduce side join(在reduce端做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) map side join(在map端做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读取相应的文件。 DistributedCache方法:(DistributedCache 是一个提供给Map/Reduce框架的工具,用来缓存文件(text, archives, jars and so on)文件的默认访问协议为(hdfs://). DistributedCache将拷贝缓存的文件到Slave节点在任何Job在节点上执行之前。 文件在每个Job中只会被拷贝一次,缓存的归档文件会被在Slave节点中解压缩。) 符号链接 每个存储在HDFS中的文件被放到缓存中后都可以通过一个符号链接使用。 URI hdfs://namenode/test/input/file1#myfile 你可以在程序中直接使用myfile来访问 file1这个文件。 myfile是一个符号链接文件。 12.MAP如何排序 在map端一共经历两次的排序: 当map函数产生输出时,会首先写入内存的环形缓冲区,当达到设定的阈值,在刷写磁盘之前, 后台线程会将缓冲区的数据划分成相应的分区。在每个分区中,后台线程按键进行内排序,在Map任务完成之前, 磁盘上存在多个已经分好区,并排好序的、大小和缓冲区一样的溢写文件, 这时溢写文件将被合并成一个已分区且已排序的输出文件。 由于溢写文件已经经过第一次排序,所以合并分区文件时只需要再做一次排序就可使输出文件整体有序。 13.什么是inputsplit InputSplit是MapReduce对文件进行处理和运算的输入单位,只是一个逻辑概念,每个InputSplit并没有对文件实际的切割 ,只是记录了要处理的数据的位置(包括文件的path和hosts)和长度(由start和length决定)。 14.MR中使用了哪些接口?(或者是抽象类) FileinputFormat、Mapper、Reducer、FileoutputFormat、Combiner、Partitioner等 --------------------- 作者:QianShiK 来源:CSDN 原文:https://blog.csdn.net/QianShiK/article/details/81480854 版权声明:本文为博主原创文章,转载请附上博文链接! 这个业务中map输出value包含日志数据中每一行的上行流量 下行流量 * 因为一次要输出3个值 所以我们通常都是编写一个自定义的类型 * * 自定义map reducer的输出值类型? * a:需要编写一个java类封装每一行日志数据中的上行流量和下行流量 * b:还需要在a中封装根据上行流量和下行流量计算总流量 * c:因为a中的java类做的是map的输出值类型 所以它需要符合hadoop io类型 * LongWritable Text IntWritable都实现了WritableComparable接口 * 反推就是想编写hadoop io类型就需要实现WritableComparable接口 * * WritableComparable接口又包括了 * Writable接口(write,readFields两个方法) 这个接口是负责这个对象的序列化和反序列化 * Comparable接口(compareTo一个方法) 这个接口是负责对象比较大小/排序使用的 * 所以两个接口中Writable接口才是标识是否属于hadoop io的类型 * * 又以为map的输出值不需要排序 只需要序列化 所以我们在这需求需要编写的map输出自定义类型只 * 需要实现Writable接口即可 切片怎么切的:切片的数量不是越大或者越小写好,而是要根据每次计算的实际数据凉,自定义优化的切片大小来控制切片的数量 比如有一共300m,前128m以一个切片,如果129到300m的存储空间小可以直接是一个切片 NIO 1:什么是NIO? NIO是基于通道和缓存的非阻塞IO。 2:IO 和 NIO的区别? a:通道在IO中只是一个便于理解的虚拟概念 而在NIO中通道是一个实际的概念 b:在IO中最底层的传输数据是字节 而在NIO中最小的传输都是缓存 c:在IO中 虚拟的通道直接会和数据接触 在NIO中通道直接面对的不是数据 而是缓存 d:在IO中某一个通道通常都是单向的 在NIO中通道是双向的 e:IO和NIO针对数据传输内存使用的方式不同 IO是面向流的 NIO是面向缓存的 3:NIO中的缓存 在NIO中传输数据 都是把数据先放入某个缓存中 再在某个通道中 按照缓存传输 在java中原有针对NIO的开发包 java.nio.* 在java.nio包下直接都是可以使用的缓存类: ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer MappedByteBuffer ShortBuffer 4:直接缓冲区和非直接缓冲区 a:系统内存(系统内核内存) 和 JVM内存(程序内存的区别) b:IO是把数据先传入JVM内存 再从JVM内存复制到系统内存 组后从系统内存写入目的硬盘 NIO是把数据可以先传入硬盘内存区 再从硬盘内存区直接写入目的硬盘 buffer.allocate方法创建的缓冲区是在非直接缓冲区申请的内存 buffer.allocateDirect一旦使用 就是在直接缓冲区申请的内存 5:通道 通道是为了替代cpu完成io操作 从而提升cpu的利用率
作为一个真正的程序员,首先应该尊重编程,热爱你所写下的程序,他是你的伙伴,而不是工具。