Hadoop、hive、sqoop入门及完整小例子
来源:互联网 发布:虎牙刷弹幕软件 编辑:程序博客网 时间:2024/06/16 07:35
Hadoop
MapReduce 和 HDFS
有自己的RPC和序列化机制
hadoop1.x
HDFS:在1.x中的NameNode只可能有一个,虽然可以通过SecondaryNameNode与NameNode进行数据同步备份,但是总会存在一定的时延,如果NameNode挂掉,但是如果有部份数据还没有同步到SecondaryNameNode上,是可能会存在着数据丢失的问题(冷备份、定期checkpoint、单点问题)。
MapReduce:
(1)JobTracker 是 Map-reduce 的集中处理点,存在单点故障;
(2)JobTracker 完成了太多的任务,造成了过多的资源消耗,当 map-reduce job 非常多的时候,会造成很大的内存开销,潜在来说,也增加了 JobTracker 失效的风险,这也是业界普遍总结出老 Hadoop 的 Map-Reduce 只能支持 4000 节点主机的上限;
流程:
(1)首先用户程序 (JobClient) 提交了一个 job,job 的信息会发送到 Job Tracker 中,Job Tracker 是 Map-reduce 框架的中心,他需要与集群中的机器定时通信 (heartbeat), 需要管理哪些程序应该跑在哪些机器上,需要管理所有 job 失败、重启等操作。
(2)TaskTracker 是 Map-reduce 集群中每台机器都有的一个部分,他做的事情主要是监视自己所在机器的资源情况。
(3)TaskTracker 同时监视当前机器的 tasks 运行状况。TaskTracker 需要把这些信息通过 heartbeat发送给JobTracker,JobTracker 会搜集这些信息以给新提交的 job 分配运行在哪些机器上。
hadoop2.x YARN+MapReduce
HDFS:HA
YARN 并不是下一代MapReduce(MRv2),下一代MapReduce与第一代MapReduce(MRv1)在编程接口、数据处理引擎(MapTask和ReduceTask)是完全一样的, 可认为MRv2重用了MRv1的这些模块,不同的是资源管理和作业管理系统,MRv1中资源管理和作业管理均是由JobTracker实现的,集两个功能于一身,而在MRv2中,将这两部分分开了。 其中,作业管理由ApplicationMaster实现,而资源管理由新增系统YARN完成,由于YARN具有通用性,因此YARN也可以作为其他计算框架的资源管理系统,不仅限于MapReduce,也是其他计算框架(例如Spark)的管理平台。
ResourceManager:全局资源管理器,基于应用程序对资源的需求进行调度的 ; 每一个应用程序需要不同类型的资源因此就需要不同的容器。资源按需调度,包括:内存,CPU,磁盘,网络等等。
NodeManager:节点代理,监控资源使用情况并且向调度器汇报。
ApplicationMaster:类似JobTracker,向调度器索要适当的资源容器,结合从 ResourceManager 获得的资源和 NodeManager 协同工作来运行和监控任务。
Container:类似TaskTracker,运行Map和Reduce任务。
编程
Mapper:
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException { String line = value.toString(); String[] splited = line.split("\t"); for (String word : splited) { context.write(new Text(word), new LongWritable(1)); } }
Reducer:
protected void reduce(Text k2, Iterable<LongWritable> v2s, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException { long count = 0L; for (LongWritable v2 : v2s) { count += v2.get(); } LongWritable v3 = new LongWritable(count); context.write(k2, v3); }
执行过程:
输入分片(Input split):跟HDFS块大小有关,输入分片调整,合并小文件
Map阶段
Combiner阶段:提高网络传输效率,原则是combiner的输入不会影响到reduce计算的最终输入,例如:如果计算只是求总数,最大值,最小值可以使用combiner,但是做平均值计算使用combiner的话,最终的reduce计算结果就会出错
Shuffle阶段:map输出一般比较大,先放到内存缓冲区,再spill到磁盘(对应溢出文件),多个溢出文件最后合并、partition(对应reducer)
Reduce阶段
进阶小例子:
public static class AverageMaper extends Mapper<Object,Text,Text,Text> { //private final static IntWritable one=new IntWritable(1); private static Text word=new Text(); public void map(Object key,Text value,Context context) throws IOException,InterruptedException { StringTokenizer itr=new StringTokenizer(value.toString()); while(itr.hasMoreTokens()) { word.set(itr.nextToken()); if(itr.hasMoreTokens()) context.write(word, new Text(itr.nextToken()+",1")); } } } public static class AveragerCombine extends Reducer<Text,Text,Text,Text> { public void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException { int sum=0; int cnt=0; for(Text val:values) { String []str=val.toString().split(","); sum+=Integer.parseInt(str[0]); cnt+=Integer.parseInt(str[1]); } context.write(key,new Text(sum+","+cnt)); } } public static class AveragerReduce extends Reducer<Text,Text,Text,DoubleWritable> { public void reduce(Text key,Iterable<Text> values,Context context) throws IOException,InterruptedException { int sum=0; int cnt=0; for(Text val:values) { String []str=val.toString().split(","); sum+=Integer.parseInt(str[0]); cnt+=Integer.parseInt(str[1]); } double res=(sum*1.0)/cnt; context.write(key, new DoubleWritable(res)); } }
试验
hdfs dfs -mkdir -p /user/whohdfs dfs -mkdir inputhdfs dfs -put ./etc/hadoop/*.xml inputhdfs dfs -ls /user/who/input 或者 hdfs dfs -ls input // output 目录不能存在hdfs dfs -rm -r output// hadoop grep 例子hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.1.jar grep input output 'dfs[a-z.]'hdfs dfs -cat output/* 或者先取回本地再查看 hdfs dfs -get output ./output // 直接文本查看hdfs dfs -text /user/who/input/core-site.xml// 本地验证find ./etc/ -type f -name *.xml|xargs grep 'dfs[a-z.]' - --color// hadoop wordcount 例子hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.1.jar wordcount input output
HDFS信息:http://192.168.56.102:50070/dfshealth.html
MapReduce查看:http://192.168.56.102:8088/cluster/apps
Hive
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
关键配置
创建目录并赋予权限:
hdfs dfs -mkdir -p /user/hive/warehousehdfs dfs -mkdir -p /user/hive/tmphdfs dfs -mkdir -p /user/hive/loghdfs dfs -chmod g+w /user/hive/warehousehdfs dfs -chmod g+w /usr/hive/tmphdfs dfs -chmod g+w /usr/hive/log
配置目录:
<property> <name>hive.exec.scratchdir</name> <value>/user/hive/tmp</value> <description>HDFS root scratch dir for Hive jobs which gets created with write all (733) permission. For each connecting user, an HDFS scratch dir: ${hive.exec.scratchdir}/<username> is created, with ${hive.scratch.dir.permission}.</description> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> <description>location of default database for the warehouse</description> </property><property> <name>hive.querylog.location</name> <value>/user/hive/log</value> <description>Location of Hive run time structured log file</description> </property>
Hive MetaStore配置,默认使用derby
<property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true&characterEncoding=UTF-8&useSSL=false</value> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hive</value> </property>
注意:mysql-connector-java-*.jar 放入Hive的lib目录
语法
许多关系型数据库都提供了命名空间的概念,用于划分不同的数据库或者Schema。例如MySQL支持的Database概念,PostgreSQL支持的namespace概念。Hive也有自己的schema的概念:
CREATE DATABASE dbname;USE dbname;DROP DATABASE dbname;SHOW DATABASES; // 默认 default
(1)如何执行:
// 进入hive命令行后可以直接执行dfs命令,如 dfs -ls /user/hivehivehive -e "show tables"hive -f create_table.hql
(2)表操作:
内部表和外部表的区别:
内部表:将数据移动到对应的warehouse目录下,速度非常快,不会对数据是否符合定义的Schema做校验,这个工作通常在读取的时候进行,称为Schema On Read。使用DROP语句删除后,其数据和表的元数据都被删除。
外部表:不会把数据移动到warehouse目录中。事实上,Hive甚至不会校验外部表的目录是否存在。这使得我们可以在创建表格之后再创建数据。当删除外部表时,Hive只删除元数据,而外部数据不动。
适用场景:大多数情况下,这两者的区别不是很明显。如果数据的所有处理都在Hive中进行,那么更倾向于选择内部表。但是如果Hive和其他工具针对相同的数据集做处理,外部表更合适。一种常见的模式是使用外部表访问存储的HDFS(通常由其他工具创建)中的初始数据,然后使用Hive转换数据并将其结果放在内部表中。相反,外部表可以用于将Hive的处理结果导出供其他应用使用。使用外部表的另一种场景是针对一个数据集,关联多个Schema。
外部表创建:
CREATE EXTERNAL TABLE external_table (dummy STRING)LOCATION '/user/root/external_table';
表操作:
SHOW TABLES;ALTER TABLE source RENAME TO target;ALTER TABLE source ADD COLUMNS (col3 STRING);DROP TABLE source;TRUNCATE TABLE my_table;
直接创建:
CREATE TABLE IF NOT EXISTS useracc ( dt string, time string, x_forwarded_for string, client_ip string, server_ip string, http_status string, content_length string, time_taken string, http_method string, url string, query_string string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE;
复制表结构:
create table if not exists table002 like table001;
CTAS语句:
CREATE TABLE table002AS select ip, time from table001;
(3)插入数据:
直接插入:
insert into users values (0,'Nat'),(2,'Joe'),(3,'Kay'),(4,'Ann');
本地文件系统导入:
LOAD DATA LOCAL INPATH "/home/hadoopUser/data/test1.txt" INTO TABLE test1;
HDFS导入:
LOAD DATA INPATH "/input/test1.txt" OVERWRITE INTO TABLE test1;
从查询结果导入:
INSERT INTO TABLE test4 SELECT * FROM test1;
CTAS语句:
CREATE TABLE table002AS select ip, time from table001;
多表插入:
FROM recordsINSERT INTO TABLE stations_by_year SELECT year ,COUNT(DISTINCT station) GROUP BY yearINSERT INTO TABLE record_by_year SELECT year,count(1) GROUP BY yearINSERT INTO TABLE good_records_by_year SELECT year , count(1) WHERE temperature != 9999 AND quality in (0,1,4,5,9) GROUP BY year;
(4)分区:
Hive将表划分为分区,Partition根据分区字段进行。分区可以让数据的部分查询变得更快。我们将用于分区的字段成为分区字段,但是在数据文件中,不存在这些字段的值,这些值是从目录中推断出来的。但是在SELECT语句中,我们依然可使用分区字段。
静态分区:
create table if not exists partition_table002 like partition_table001; insert overwrite table partition_table002 partition (dt='20150617', ht='00') select name, ip from partition_table001 where dt='20150607';
动态分区:
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; insert overwrite table partition_table002 partition (dt, ht) select * from partition_table001 where dt='20150617'; INSERT OVERWRITE TABLE T PARTITION (dt, ht) SELECT key, value, dt, ht FROM srcpart WHERE dt is not null and ht>10;
hive先获取select的最后两个位置的dt和ht参数值,然后将这两个值填写到insert语句partition中的两个dt和ht变量中,即动态分区是通过位置来对应分区值的。原始表select出来的值和输出partition的值的关系仅仅是通过位置来确定的,和名字并没有关系,比如这里dt和st的名称完全没有关系。
混合使用:
INSERT OVERWRITE TABLE T PARTITION (ds='2010-03-03', hr) SELECT key, value, /*ds,*/ hr FROM srcpart WHERE ds is not null and hr>10; // rightINSERT OVERWRITE TABLE T PARTITION (ds, hr = 11) SELECT key, value, ds/*, hr*/ FROM srcpart WHERE ds is not null and hr=11; // wrong
(5)分桶:
对于每一个表(table)或者分区,Hive可以进一步组织成桶。Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。采用桶能够带来一些好处,比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
bucket主要作用:数据sampling;提升某些查询操作效率,例如mapside join。
set hive.enforce.bucketing = true; create table student(id INT, age INT, name STRING)partitioned by(stat_date STRING) clustered by(id) sorted by(age) into 2 bucketrow format delimited fields terminated by ','; from student_tmp insert overwrite table student partition(stat_date="20120802") select id,age,name where stat_date="20120802" sort by age;
'set hive.enforce.bucketing = true' 可以自动控制上一轮reduce的数量从而适配bucket的个数,当然,用户也可以自主设置mapred.reduce.tasks去适配bucket 个数,推荐使用'set hive.enforce.bucketing = true' 。
抽样语法:TABLESAMPLE(BUCKET x OUT OF y)
select * from student tablesample(bucket 1 out of 2 on id);
y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32时,抽取 (64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。x表示从哪个bucket开始抽取。例 如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。
试验
具体步骤参考另一篇文章:大数据串讲-从日志文件分析访问量最高的10个接口及响应访问量
Sqoop
数据收集
手动SCP
Rsync命令同步文件
Sqoop从关系型数据库导入
Flume收集
具体参考另一篇文章:Apache Flume 日志收集案例
Logstash收集
ELK(ElasticSearch、Logstash、Kibana)三搭档之一
- Hadoop、hive、sqoop入门及完整小例子
- Hadoop 入门小例子
- Hadoop入门(三):Sqoop和Hive的使用
- Hadoop+hive+sqoop环境部署
- 初探hadoop+hbase+sqoop+hive
- 【hadoop Sqoop】数据迁移工具 sqoop 入门
- 【Hadoop】Sqoop部署入门指南
- hadoop之MapReduce基本原理及入门WordCount小例子(三)
- 【hadoop Sqoop】Sqoop从mysql导数据到hive
- 初学HADOOP(MAPREDUCE-WORLD COUNT/HIVE/SQOOP)
- CDH版 Hadoop Hive Sqoop 安装
- hadoop生态系统搭建(hadoop hive hbase zookeeper oozie sqoop)
- Sqoop安装配置及hive导入
- 定时自动执行Sqoop及Hive命令
- hadoop+hive+hbase入门
- hive.Hadoop入门
- Hadoop-Hive快速入门
- hadoop日志【1】--hive服务和sqoop服务运行
- UVC设备驱动之描述符分析
- Zokeeper java入门
- sort(1,2,3)快速排序+贪心(nlongn):今年暑假不AC
- 行高等于容器高度可以垂直居中
- Http协议
- Hadoop、hive、sqoop入门及完整小例子
- js 零碎笔记
- 一个菜鸟对MVP的认识
- Java中Runnable和Thread的区别
- 用R语言用生存资料做基于radiomic(影像组学)的生存分析
- 显示一定时长弹框的解决方案
- JDBC动态执行存储过程
- Linux下载安装Nginx并配置,以及启动/停止/重启命令
- 无序的图片预加载