大数据-hadoop初探-02

【SSH免密码登录】
1、ssh-keygen -t rsa
id_rsa -》私钥
id_rsa.pub -》公钥
ssh-copy-id bigdata-01
ssh-copy-id bigdata-02
ssh-copy-id bigdata-03
自己也要给自己发送公钥和私钥
authorized_keys  -》将公钥保存到文件中远程拷贝到其他机器上保存
known_hosts      -》记录秘钥信息
看.ssh目录下面是不是不有四个文件
2、报错解决:
如果没有生效,就删除.ssh目录下所有文件,重新生成
或者直接删除.ssh目录,生成方式ssh-keygen,就会生成.ssh目录,不要使用mkdir
3、配置了SSH之后,就不需要输入密码,直接可以启动多个节点的服务进程(sbin/start-dfs.sh)




【HDFS架构的安全模式】
读&写
client -> namenode 
client -> datanode




1、等待过程,处于安全模式
safemode安全模式下HDFS文件系统是只读的,进入"只读不写"的状态
namenode每次启动的时候,在等待的过程中都是处于安全模式
安全模式下HDFS不能响应外部客户端的写操作请求(上传、删除等修改类操作)
安全模式下客户端读取HDFS文件和下载HDFS文件到本地是可以的


2、安全模式在做什么操作
namenode上有元数据表,但是启动的时候要确保这些数据块是否还完整(匹配key)
namenode在启动的过程中在等待所有的datanode向它汇报块的信息
所以要等待所有节点向主节点汇报
namenode和datanode,心跳机制,默认每隔3秒,进行心跳通信
3、相关参数和属性配置
1)表示HDFS启动的时候,如果DataNode上报的block个数达到了元数据记录的block个数的0.999倍才可以离开安全模式
也可以通过hadoop dfsadmin -safemode leave命令强制离开,但是当集群中磁盘空间满了,就算你成功退出了,它还会马上又进入安全模式
1、当反馈给namenode的正常块数和总块数的比例小于0.999f
那就将系统切换成安全模式,对数据块进行复制;
2、当大于该比例时,就离开安全模式,说明系统有足够的数据块副本数,可以对外提供服务。
3、小于等于0意味不进入安全模式,大于1意味一直处于安全模式。
注:当集群启动的时候,会首先进入安全模式。当系统处于安全模式时会检查数据块的完整性。
假设我们设置的副本数(即参数dfs.replication)是5,那么在datanode上就应该有5个副本存在
假设只存在3个副本,那么比例就是3/5=0.6。在配置文件hdfs-default.xml中定义了一个最小的副本的副本率0.999,
我们的副本率0.6明显小于0.99,因此系统会自动的复制副本到其他的dataNode,使得副本率不小于0.999f
如果系统中有7个副本,超过我们设定的5个副本,那么系统也会删除多余的2个副本。
现有块信息/完整的快信息(dfs.replication) > 0.999f
<property>
  <name>dfs.namenode.safemode.threshold-pct</name>
  <value>0.999f</value>
  <description>
    Specifies the percentage of blocks that should satisfy 
    the minimal replication requirement defined by dfs.namenode.replication.min.
    Values less than or equal to 0 mean not to wait for any particular
    percentage of blocks before exiting safemode.
    Values greater than 1 will make safe mode permanent.
  </description>
</property>


2)指定namenode和datanode之间心跳的间隔时间,默认3秒
<property>
  <name>dfs.heartbeat.interval</name>
  <value>3</value>
  <description>Determines datanode heartbeat interval in seconds.</description>
</property>




【本地库无法加载的警告】
ERROR
WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
这个版本的压缩包被其他用户编译了,但是编译者的编译环境和我们自己的环境有不一样
解决方法:
下载官方的源码包
hadoop-2.5.0-src.tar.gz
1、编译Hadoop源码
2、替换hadoop/lib下的native本地库文件
3、将编译好的native拷贝到lib下
4、通过bin/hadoop checknative检验是否成功


【搭建eclipse环境(Linux)】
搭建eclipse环境(Linux)
-》安装配置maven
-》解压
-》修改/etc/profile添加环境变量
#MAVEN_HOME
export MAVEN_HOME=/opt/modules/apache-maven-3.0.5
export PATH=$PATH:$MAVEN_HOME/bin
-》验证maven是否生效
mvn -version


-》解压eclipse
-》在虚拟机图形界面中执行启动eclipse
-》./eclipse


-》创建一个.m2的文件夹用于存放settings.xml和maven仓库文件夹
把你的在linux上解压的maven里的conf目录下settings.xml文件和resportry文件夹拷贝到.m2


【搭建eclipse环境(windows)】
分享博客:http://blog.csdn.net/lsr40/article/details/77868113


【Mapreduce & yarn】
特点:
1、分布式并行计算
2、主要核心功能:排序,默认的排序方式是按照key进行排序
概念定义:
1、MapReduce执行流程涉及到Client、ResourceManager、NodeManager、ApplicationMaster、Container、Task
2、其中Client是提交Mapreduce的机器
3、ApplicationMaster是负责该Job调度的进程,一个job一个applicationMaster
4、Container是资源表示形式
5、Task是运行在NodeManager上的进程,使用到资源就是Container 
6、resourcemanager是管理整个集群的资源
7、nodemanager是单个节点的资源管理
提交流程:
1、Clinet向RM申请资源,RM上有所有NM的节点资源信息,RM将资源信息(NM的hostname、以及分配的内存和CPU大小)发送给Client
2、Client根据请求到资源信息发送到对应的NM,NM中产生Container对象,然后在Container对象中调用相关代码,启动AM 
3、AM开始获取job相关设置信息,获得得到map task数量(由InputFormat的getSplits方法决定)和reduce task数量(由参数mapreduce.job.reduces影响)
4、然后AM向RM申请Map Task运行的资源(一个task就需要申请一个container),RM将分配的资源发送给AM,AM远程调用NM的相关方法启动对应的Container,并在Container中启动对应的Map Task
5、当一个Map Task执行完成后,会通知AM进程,当前Map Task执行完成;当总Map Task中有5%执行完成,AM向RM申请reduce task运行资源(一个task需要一个container)
6、RM将资源信息发送给AM,AM在对应的NM节点启动对应的Container,并在Container中运行对应的reduce task任务
7、当reduce task任务执行完成后,会AM进程,当所有的reduce task执行完成,AM通知client表示程序执行完成


疑问一:map task在哪儿运行,是由谁来决定的?
这个东西是由RM返回给AM资源的时候决定的
RM上会有全部CPU和内存,已使用CPU和内存,RM会根据底层写好的算法,返回NM的信息
所以说如果一个NM上只有一个Map Task任务,一个maptask默认使用1核cpu,使用1G内存,那这个Map Task任务只处理该task本身的数据,也就是说该任务处理的数据可以是当前节点的,也可以是其它节点上的数据
RM在分配资源的时候,会尽可能的将Map Task所运行的资源(Container所在机器的NM的hostname等)的放到数据节点上,这样的话RM在启动AM的时候就会在数据节点上启动处理该数据的map  task任务,该机制叫做mapreduce的数据本地化机制 
但是如果资源不够,就会选择其他机器,所以主要还是使用资源来做选择哪台机器执行Task的判断)


疑问二:怎么设定map和reduce的数量?
MapReduce有两套API,org.apache.hadoop.mapred(旧API)和org.apache.hadoop.mapreduce(新API),开发时基本用新的API
map和reduce的数量受两个操作的影响,split和partition,一个split就是对应一个maptask,一个partition对应一个reduce数据输入
控制map数量:
新版本mapreduce的textInputFormat使用参数:mapreduce.input.fileinputformat.split.maxsize和mapreduce.input.fileinputformat.split.minsize来控制split也就是map的数量
公式:split_size = max(minsize,min(maxsize,blocksize)) 默认spilt_size=blocksize
默认maxsize为Long.MaxValue,minsize为0,所以默认map大小等于blocksize,也就是128M
如果要增多map数量,就将maxsize的值设置比blocksize小
如果要减少map数量,就将minsize的值设置比blocksize大
提交job:
hadoop jar XXXX.jar wordcont -Dmapreduce.input.fileinputformat.split.maxsize=xxx -Dmapreduce.input.fileinputformat.split.minsize=xxx
或者通过api设置
FileInputFormat.setMaxInputSplitSize(job, 20971520l);
FileInputFormat.setMinInputSplitSize(job, 1000);


但是,当我储存一个129MB的文件的时候,存了几块!?
存储了2块!
第一块128M,第二块1M
正确的概念:
HDFS上的文件进行mapreduce计算,默认情况下一个map当中会有128M(和块大小一样)的数据输入
所以这里就涉及到我的一个129M的文件会启动几个Map任务来操作
答案是:1个
mapreduce有这样的机制,最后一个文件的输入如果小于128*1.1(其实就是可以多10%)
那么只会启动一个Map来执行这个job,避免了第一个Map跑了128M的数据,第二个Map只跑了1M的数据的尴尬
这种情况只会在最后一块出现
再举个例子,比如522M的文件,分成几个Map来处理呢?
第一个map-》128M
第二个map-》128M
第三个map-》128M
第四个map-》138M  ——》138小于128*1.1,所以这里就不会再开启一个map来处理最后剩余的那10M的数据
直接在最后一个map当中把所有138M的数据输入!!

mapreduce流程
1、输入(HDFS、hbase、mysql...)
2、map(数据的切分和清洗)
3、shuffle
4、reduce
5、输出(HDFS、hbase、hive、MySQL....)
两套API(新旧):
org.apache.hadoop.mapred    -》 Hadoop 1.x
org.apache.hadoop.mapreduce -》 Hadoop 2.x
数据格式:
input:
hadoop hive 
hadoop hive hadoop hadoop
long  String
<0,”hadoop hive“>
<12,"hadoop hive hadoop hadoop">
map:
String 
line.split()
String  int
<hadoop,1>
<hive,1>
<hadoop,1>
<hadoop,1>
<hive,1>
<hadoop,1>
shuffle:
<key,list(values)>
<hadoop,List(1,1,1,1)>
<hive,List(1,1)>
reduce:
String,int
<hadoop,4>
<hive,2>
output: 
最终的输出
map的输出等于reduce的输入
intpu<k1,v1> --> map<k2,v2> -->shuffle<k2,list<v2,v2>> -->reduce<k3,v3> -->output
k1,v1  <long  string>  map输入
k2,v2  <string  int>  
shuffle<k2,list{v1,v2}>  <string  int>  map输出,reduce输入
k3,v3  <String  int> reduce输出


【MR输入和输出类】
输入:InputFormat
TextInputFormat
SequenceFileInputFormat
DBInputFormat
KeyValueTextInputFormat
输出:OutputFormat
TextOutputFormat(LineRecordWriter)
SequenceFileOutputFormat、DBOutputFormat
因为离线分析,一般来说都是处理日志,以行分割的数据,所以用默认的TextInputFormat就可以,有特殊需求自己写类就行


【MR shuffle】
1、分为map端shuffle和reduce端shuffle
2、发生的阶段是map的输出到达reduce输入之前的中间阶段
3、wordcount 单词统计
4、输入input hadoop ,spark
<0,hadoop spark>
5、map()
<hadoop,1>,<spark,1>
6、map output -》 shuffle
7、数据往内存中写入,环形缓冲区
8、内存默认大小:100MB,用户自定义大小
<property>
  <name>mapreduce.task.io.sort.mb</name>
  <value>100</value>
  <description>The total amount of buffer memory to use while sorting 
  files, in megabytes.  By default, gives each merge stream 1MB, which
  should minimize seeks.</description>
</property>
当map()被调用次数过多的时候,代表内存中的空间会占用越来越大
当内存中的空间达到了80%,默认是80%,用户可以自定义
当达到80%就会触发spill溢写操作

buffer_size*spill.percent=80M
<property>
  <name>mapreduce.map.sort.spill.percent</name>
  <value>0.80</value>
  <description>The soft limit in the serialization buffer. Once reached, a
  thread will begin to spill the contents to disk in the background. Note that
  collection will not block if this threshold is exceeded while a spill is
  already in progress, so spills may be larger than this threshold when it is
  set to less than .5</description>
</property>
9、溢写阶段
溢写会单独开启一个线程(将数据写入磁盘中)
溢写过程中map可以继续往剩余的内存空间中继续写入,互不影响
如果写入的速度快于溢写的速度,那么会造成阻塞,就会等待溢写完成


10、分区partition
默认hashpartiton算法,哈希值取余的方式
分区的时候是根据key的hash值去进去分配
java当中的各种运算符:http://blog.csdn.net/is_zhoufeng/article/details/8112199
1、reduce数目设置
时间是检验真理的唯一标准
reduce的数目设置影响运行总时间
假设:
20个reduce运行时间10分钟
10个reduce运行时间11分钟
选择数目少的,尽量的减少集群资源开销

reducede 的数目就等于map shuffle过程中partition数目

2、分区的同时有排序sort
mapreduce默认排序是根据key进行排序
对于分区进行排序,这个阶段还是处于内存中的
溢写到本地磁盘,在本地会形成一个溢写文件
如果数据量很大的情况下,就会有多个溢写文件
合并merge,将溢写文件做一个合并
算法:归并方式
在map中的shuffle甚至可以有combiner
<property>
  <name>mapreduce.cluster.local.dir</name>
  <value>${hadoop.tmp.dir}/mapred/local</value>
  <description>The local directory where MapReduce stores intermediate
  data files.  May be a comma-separated list of
  directories on different devices in order to spread disk i/o.
  Directories that do not exist are ignored.
  </description>
</property>
=======================map端shuffle==============================


=======================reduce端shuffle===========================
APPmaster通知reduce进行拷贝数据
reduce开启cpoy线程去对应的map上拷贝数据,通过http网络方式进行传输
reduce将数据写入环形缓冲区中
做sort排序,分组group,将相同key的value放在一起
<hadoop,list(1,1,1)>
reduce input


https://www.cnblogs.com/CherishFX/p/4239959.html


【本地程序打jar运行在yarn】
注意:程序必须指定主类
jar需要上传到Linux上,然后通过命令行运行
输入和输出路径在程序中指定,也可以在命令中指定


【MR程序的优化】
combiner,属于map的shuffle阶段
在map端设置combiner可以优化reduce输入的数据量
最主要的作用:
减轻了网络和磁盘IO的开销
<hadoop,1><hadoop,1><hadoop,1><hadoop,1><hadoop,1><hadoop,1><hadoop,1><hadoop,1>
<hadoop,10>
combiner并不是所有的MR程序都适合
combiner虽然是可选项但是默认情况下是不启用的
适合场景:
不能更改最终的计算结果
适合做累加的、最大值、最小值等
combiner和reduce区别:
combiner对象是对于单个map来说的,只是处理单台机器生成的数据
reduce对象是对于多个map来说的,所以如果有聚合,reduce阶段是不可避免的


combiner获取的数据
<hadoop,list(1,1,1)>
combiner输出的数据
<hadoop,3>














 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值