hadoop要点(一):
YARN支持多种计算模型(hadoop离线,storm实时,spark内存计算),支持数据共享;
hadoop部署方式:本地,伪分布,集群模式
hadoop1.0块文件默认64M,hadoop2.0块文件大小默认128M;
配置ssh免密码登录:处于同一网段的ip才能通信,cd .ssh/ , ls , ssh-keygen -t rsa
生成id_rsa私钥和id_rsa.pub公钥(非对称加密算法), more id_rsa.pub ,
cp id_rsa.pub authorized_keys , ssh winbox , ssh-copy-id 192.168.8.66 把本台机器的公钥拷贝到目标机器上(单向)
HDFS shell: 加了fs前缀的linux命令,可操作HDFS文件;
元数据存储细节(NameNode Metadata):NameNode(FIleName,replicas,block-ids,id2host..) eg: /test/a.log,3,{blk_1,blk_2},[{blk_1:[h0,h1,h3]},{blk_2:[h0,h2,h4]}]
NameNode职责:管理文件系统,接收用户请求;
元数据加载:,当满足checkpoint后,SecondaryNameNode配合NameNode将edits的操作与fsimage合并成新的fsimage.ckpt替换到NameNode内存,此间NameNode中edits会生成新的edits.new替换旧的来记录文件操作;
java操作HDFS:
首先创建fileSystem的实现类(工具类)
FileSystem fs = FileSystem.get(new URI(“hdfs://hdfshost:9000”),new Configuration(),”root”); //这个fs是DistributedFileSystem类型
再利用输入输出流
InputStream in = fs.open(new Path(“/source”);
OutputStream out = new FileOutputStream(“/destination”);
IOUtils.copyBytes(in,out,4096,true);
Hadoop整个体系结构是建立在RPC之上的;
RPC通过实现共同接口的代理对象在服务器端调用方法并返回处理结果给客户端,底层通信仍通过socket套接字完成,代理对象versionID要一致;
2.0的ResourceManager相当于1.0的JobTracker,同理NodeManager相当于TaskTracker
Client向RM提交job原理:RM返回一个jobID和存放路径,Client用前缀+jobID唯一标识一个job,并把该jar存入HDFS,而RM保存了作业的描述信息;
MapReduce自定义输入输出数据类型:实现Writable接口,重写write序列化和readFields反序列化方法,注意属性写入与读出顺序保持一致;
可以根据不同规则对mapper处理后的数据进行partition,reducer数目不能少于分区数;
自定义可排序的数据类型需实现WritableComparable<T>接口
Combiner是map端的reducer,也可用于过滤数据,可插拔;
shuffle过程:map数据先存入内存环形缓冲区,当达到一定阈值,数据溢出到磁盘,每个key-value存入一个小文件的对应分区中,默认partition规则是key的hash,每个分区内进行快排,然后多个小文件合并,相同分区内的数据进行归并排序,最终reducer通过一个线程询问map数据输出位置并获得这些数据;
map数量与split一致,而split数目默认为block个数;
zookeeper提供高可靠,集群个数为奇数,NameService可管理多个namenode,负责主节点切换,zookeeper进程和namenode进程运行在同一台机器上,slaves文件中配置多个备用节点,每个namenode既要配置HTTP端口,也要配置RPC端口;
sqoop导出数据命令示例:./sqoop export - -connect jdbc:mysql://192.168.1.100:3306/winbox - -username root - -password 123
- -export-dir ‘/sqoop/desdir’ - -table td_0106 -m 1 - -fields-terminated-by ‘\t’
HMaster是HBase的老大,HRegionServer是小弟;
修改HBase,先停用表,eg: disable ‘user’ ,添加列族,alter ‘user’,name => ‘f1’ ,启用表: enable ‘user’ ;
Table在行的方向上根据RowKey分割为多个HRegion,一个region由[startkey,endkey)表示,每个HRegion分散在不同的RegionServer中;
通过java操作HBase:java连接zookeeper,首先获得HTable table = new HTable(conf,”表名”);根据rowKey构造出put,get,scan,delete对象,对于查询,通过result.get(列名)获取值;
HBase的namespace相当于HDFS的nameservice;
HBase中有两张特殊的Table,-ROOT-和.META.和用户Region相当于三级索引关系
-ROOT-:记录了.META.表的Region信息,-ROOT-只有一个region
.META.:记录了用户创建的表的Region信息,.META.可以有多个region
Zookeeper中记录了-ROOT-表的location
Client访问用户数据之前需要首先访问zookeeper,然后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置;
Hive的表其实就是HDFS的目录/文件夹,按表名把文件夹分开,如果是分区表,则分区值是子文件夹;
Hive的元数据(metastore)一般保存在mysql(默认derby)中,这些元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等;更改到mysql方法:hadoop fs -rmr /user/hive , 再修改配置文件,添加驱动,并授予相应权限;
select * from table进行全表扫描,不会生成MapReduce任务;
HQL创建外部表(先存数据后建表): eg: create external table ext_student (id int , name string) row format delimited fields terminated by ‘\t’ location ‘/data’;
Hive shell下能运行HDFS shell,灵活处理HDFS文件的ETL;
分区把原来的表额外添加了字段,方便海量数据查询,eg: select * from beauties where nation =‘China’,这里边表按nation进行了分区;
Hive UDF: extends UDF,实现evaluate方法,add jar,create temporary function;
Flume:配置source(读取数据源),channel(临时缓存),sink(输出,例如存HDFS);
案例: 日志分析项目: 将日志文件存入HDFS,对文件建立外部表,用mapreduce清洗日志文件,bash脚本代码示例daily.sh:CURRENT=`date +%y%m%d` , /winbox/hadoop-2.2.0/bin/hadoop jar /root/cleaner.jar /flume/$CURRENT /cleaned/$CURRENT , /winbox/apache-hive-0.13.0-bin/bin/hive -e “alter table winbbs add partition (logdate=$CURRENT) location on ‘/cleaned/$CURRENT’ “ , Hive分析(统计PV):hive -e “create table pv_$CURRENT row format delimited fields terminated by ‘\t’ as select count(*) from winbbs where logdate=$CURRENT “ ; 运行脚本 ./daily.sh , 将分析后的数据导入mysql: /winbox/sqoop-1.4.4/bin/sqoop export - -connect jdbc:mysql://192.168.1.110:3306/winbox - -username root - -password 123 - -export
-dir "/user/hive/warehouse/vip_$CURRENT" - -table vip - -fields-terminated-by ‘\t'
关于block和split几个简单的结论:
1)一个 split 包含大于等于1 的 整数个 Block
2) 一个 split 不会包含两个 File 的 Block, 不会跨越 File 边界
3) split 和 Block 的关系是一对多的关系 ,默认一对一
4) maptasks 的个数最终决定于 splits 的长度
1)一个 split 包含大于等于1 的 整数个 Block
2) 一个 split 不会包含两个 File 的 Block, 不会跨越 File 边界
3) split 和 Block 的关系是一对多的关系 ,默认一对一
4) maptasks 的个数最终决定于 splits 的长度
FileSplit的hosts存储的是block块本身及其冗余所在的机器列表,当taskTracker来索取数据,会判断task所在机器是不是包含在hosts中,有利于数据本地化;
Shuffle过程优化:减少拉取数据的量及尽量使用内存而不是磁盘;
Flume剖析:
Spooling Directory Source: SpoolSource是监测配置的目录下新增的文件,并将文件中的数据读取出来,需要注意两点:1)拷贝到spool目录下的文件不可再打开编辑,2)spool目录下不可包含相应的子目录;
HDFS Sink:这Sink将事件写入到Hadoop分布式文件系统(HDFS),目前支持创建文本和序列文件,支持两种文件类型的压缩;
配置内容:
#Name the components on this agent
a1.sources=r1
a2.sinks=k1
a1.channels=c1
#Describe/configure the source
a1.sources.r1.type=org.apache.flume.source.http.HTTPSource
a1.sources.r1.bind=0.0.0.0
a1.sources.r1.port=5140
a1.sources.r1.channels=c1
#Describe the sink
a1.sinks.k1.typpe=hdfs
a1.sinks.k1.channel=c1
a1.sinks.k1.hdfs.path=hdfs://master:9000/user/hadoop/flume/collected/%y-%m-%d/%H%M/%S
a1.sinks.k1.hdfs.filePrefix=Syslog.%(host)
a1.sinks.k1.hdfs.round=true
a1.sinks.k1.hdfs.roundValue=10
a1.sinks.k1.hdfs.roundUnit=minute
#Use a channel which buffers events in memory
a1.channel.c1.type=memory
a1.channel.c1.cappaty=1000
a1.channels.c1.transactionCapacity=100
启动flume agent a1
flume agent-c.f case9_hdfs.conf -n a1-Dflume.root.logger=INFO.console
Memory Channel:事件存储在一个可配置的最大尺寸内存队列,使用场景:需要更高的吞吐量,代理出现故障后数据丢失的情况;
Flume Event Serializers:
file_roll sink和hdfs sink都支持EventSerializer接口,Body Text Serializer和Avro Event Serializer;