赞
踩
排序问题在数据量少的时候是没有问题的,但是数据量一多,问题就出来了:
select * from emp order by empno desc;
0: jdbc:hive2://hadoop001:10000/ruozedata_hiv> set hive.mapred.mode=strict;
No rows affected (0.004 seconds)
0: jdbc:hive2://hadoop001:10000/ruozedata_hiv> select * from emp order by empno desc;
Error: Error while compiling statement: FAILED: SemanticException 1:27 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error encountered near token ‘empno’ (state=42000,code=40000)
打开hive.configure.properties,注意参数:hive.mapred.mode;在严格模式中,一些负载重的查询是不被允许跑的,举例:全表扫描是被禁止的单单使用order by的话,必须加上limit字段:
我们找一张分区表进行操作:
/ruozedata_hiv> select * from order_partition where event_month=‘2020-01’ order by order_no desc;
Error: Error while compiling statement: FAILED: SemanticException 1:67 In strict mode, if ORDER BY is specified, LIMIT must also be specified. Error encountered near token ‘order_no’ (state=42000,code=40000)
0: jdbc:hive2://hadoop001:10000/ruozedata_hiv> set hive.mapred.mode=nonstrict;
No rows affected (0.002 seconds)
0: jdbc:hive2://hadoop001:10000/ruozedata_hiv> select * from order_partition where event_month=‘2020-01’ order by order_no desc;
严格模式下:
如果是普通表:order by + limit
分区表:order by + limit where partition column
name | value | description |
---|---|---|
mapred.reduce.tasks | -1 |
1、设置reduce数:
set mapred.redcue.tasks=3; 设置3个reduce
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 3
2、select * from emp sort by empno; 结果在控制台上输出是没那么明显的直观的: 3、MR中有多少个reduce作业就对应输出多少个文件、spark中多少个task就对应输出多少个输出文件: 4、把输出文件放到本地liunux目录上再做决断: insert overwrite local directory '/home/hadoop/tmp/hivetmp/sort/' select * from emp sort by empno; 5、自行去到输出目录中查看确实是有3个输出文件 --> 这就是所谓的分区有序: [hadoop@hadoop001 sort]$ pwd /home/hadoop/tmp/hivetmp/sort [hadoop@hadoop001 sort]$ ll total 12 -rw-r--r-- 1 hadoop hadoop 335 Apr 3 13:59 000000_0 -rw-r--r-- 1 hadoop hadoop 282 Apr 3 13:59 000001_0 -rw-r--r-- 1 hadoop hadoop 91 Apr 3 13:59 000002_0
为什么严格模式下一定要加limit?默认的排序机制asc升序,lexicographical(字典序),
使用方法:distribute by + col:根据指定的字段把数据分发到不同的reduce上去;相当于是MapReduce中的Partitioner,通常与Sort by连用;
1、按照名字的长度进行分发,又在分区内根据员工编号的升序排序:
insert overwrite local directory ‘/home/hadoop/tmp/hivetmp/distribute’ select * from emp distribute by length(ename) sort by empno;
//在大数据中数据倾斜的场景需要依赖于distribute的,
cluster by is a short-cut for both Distribute by and sort by:只做数据分发:
insert overwrite local directory ‘/home/hadoop/tmp/hivetmp/distribute’ select * from emp cluster by empno;
order by:全局有序,一个reduce 大数据量下效率低
sort by: 每个reduce内有序,不能保证全局有序
distribute by:是按照指定字段进行数据分发
常与sort by连用,确保每个reduce内有序
cluster by = distribute by + cluster by
场景:
1)、数据存储在MySQL中,你想使用Hive进行处理
2)、使用Hive统计分析好了,数据还在Hive中,如何导出到MySQL中:
–> 最终是通过报表可视化展示的,结果如何对接到报表中:(1)、HiveServer2 (2)、Hive的统计结果导出到RDBMS中,报表数据直接对接RDBMS中,必备的两大场景
解决方案:MapReduce(太过繁杂)
–> 抽象成常用的工具
Sqoop是一个数据导入导出工具:
类似Hive访问MySQL在$HIVE_HOME/cong下的hive-site.xml中的信息一样:
RDBMS需要如下链接信息:url driver db table user password(必要信息)
链接到hdfs需要:path
链接到Hive需要:database table partition
–> 引出了Sqoop这个框架:sqoop.apache,org
sqoop:sql to hadoop
hue:一个可视化的框架,在上面写SQL,结果可以采用报表的方式出来:在CDH一配置结果就都出来了。
生产集群中看公司,先通过跳板机在再链接到服务器上去,Dbeaver能否链接到生产服务器,可以
RDBMS <==>Hadoop,同比的也可以把数据导到Hbase、Hive中去。
两大版本:
sqoop1.x:sqoop1 ***(70%左右公司都是使用这个的)
sqoop1.99.x:sqoop2(用起来很麻烦)
把数据从RDBMS和Hadoop之间记性导入导出操作,底层就是使用MapReduce来实现的。
Sqoop只有Map,它不需要Reduce;
Sqoop的导入:基于Hadoop作为参考点、基准点:
RDBMS <==>Hadoop
Sqoop的导出:从Hadoop作为出发点往外导:
Hadoop <==> RDBMS
1、下载:
wget http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.6-cdh5.16.2.tar.gz
2、解压并且做一个软连接:
tar -zxvf sqoop-1.4.6-cdh5.16.2.tar.gz -C ~/app/
ln -s sqoop-1.4.6-cdh5.16.2 sqoop
3、配置系统环境变量:vi ~/.bashrc
export SQOOP_HOME=/home/hadoop/app/sqoop
export PATH=
S
Q
O
O
P
H
O
M
E
/
b
i
n
:
SQOOP_HOME/bin:
SQOOPHOME/bin:PATH
4、生效环境变量:
source ~/.bashrc
5、在$SQOOP_HOME/conf下拷贝一份文件,再进行参数配置:
cp sqoop-env-template.sh sqoop-env.sh
export HADOOP_COMMON_HOME=/home/hadoop/app/hadoop
export HADOOP_MAPRED_HOME=/home/hadoop/app/hadoop
export HIVE_HOME=/home/hadoop/app/hive
6、拷贝一个驱动包到$SQOOP_HOME/lib目录下:
cp mysql-connector-java-5.1.27-bin.jar $SQOOP_HOME/lib/
sqoop help查看命令帮助,学习sqoop就是查字典:
1、sqoop version:
查看版本号
2、列出mysql下的数据库,查看命令帮助:sqoop help list_databases
sqoop list-databases \
--connect jdbc:mysql://hadoop001:3306 \
--username root \
--password 960210
输出结果如下:
20/04/03 15:08:06 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset.
information_schema
mysql
performance_schema
ruozedata_hive
sqoop
sys
wordpress
3、列出数据库下的表:
sqoop list-tables \
--connect jdbc:mysql://hadoop001:3306/sqoop \
--username root \
--password 960210
//运行结果如下:
20/04/03 15:39:54 INFO manager.MySQLManager: Preparing to use a MySQL streaming resultset.
dept
emp
salgrade
sqoop help import:查看命令帮助:
参数先捋一遍:
--append
--columns <col,col,col...>
--delete-target-dir
-m,--num-mappers <n>
--mapreduce-job-name <name>
--target-dir <dir>
sqoop import \ --connect jdbc:mysql://hadoop001:3306/sqoop \ --username root \ --password 960210 \ --table emp \ -m 1 //出现如下报错: Exception in thread "main" java.lang.NoClassDefFoundError: org/json/JSONObject at org.apache.sqoop.util.SqoopJsonUtil.getJsonStringforMap(SqoopJsonUtil.java:43) at org.apache.sqoop.SqoopOptions.writeProperties(SqoopOptions.java:784) at org.apache.sqoop.Sqoop.main(Sqoop.java:252) Caused by: java.lang.ClassNotFoundException: org.json.JSONObject at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) //原因是缺少java-json.jar包,上传一个即可解决问题:
1、如下所示,顺利的把MySQL中的数据导入到了hdfs目录上: [hadoop@hadoop001 bin]$ hdfs dfs -ls /user/hadoop/emp 20/04/03 16:10:18 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Found 2 items -rw-r--r-- 1 hadoop supergroup 0 2020-04-03 16:08 /user/hadoop/emp/_SUCCESS -rw-r--r-- 1 hadoop supergroup 282 2020-04-03 16:08 /user/hadoop/emp/part-m-00000 2、使用了一个map所以结果是一个文件 [hadoop@hadoop001 bin]$ hdfs dfs -text /user/hadoop/emp/part-m-00000 20/04/03 16:10:31 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 7369,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40 7499,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40 7499,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40 7499,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40 7499,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40 7499,SMITH,CLERK,7902,1980-12-17,800.0,20.0,40
ERROR tool:FileAlreadyExist,文件目录已存在;意思就是在导入命令中需要删除目标表:
1、在$SQOOP_HOME/bin目录下执行命令的时候打印在控制台上的log信息,为什么会有一个limit1,主要是查看这张表是否存在:
20/04/03 16:21:09 INFO manager.SqlManager: Executing SQL statement: SELECT t.* FROM emp
AS t LIMIT 1
2、为什么number of splits:1
设置的map就是1
3、在$SQOOP_HOME/bin目录下每执行一个sqoop导入就会生成一个.java文件:
sqoop import \
--connect jdbc:mysql://hadoop001:3306/sqoop \
--username root \
--password 960210 \
--table emp \
--mapreduce-job-name frommysql2hdfs \
--delete-target-dir
sqoop import \
--connect jdbc:mysql://hadoop001:3306/sqoop \
--username root \
--password 960210 \
--table emp \
--mapreduce-job-name frommysql2hdfs2 \
--delete-target-dir \
--target-dir emp_column \
--columns "empno,ename,job,sal,comm" \
-m 1
sqoop import \ --connect jdbc:mysql://hadoop001:3306/sqoop \ --username root \ --password 960210 \ --table emp \ --mapreduce-job-name frommysql2hdfs2 \ --delete-target-dir \ --target-dir emp_column \ --columns "empno,ename,job,sal,comm" \ --fields-terminated-by '\t' \ -- null-string '' \ --null-non-string '0' \ -m 1 //--fields-terminated-by '\t'把导出数据的分割符换成\t,-- null-string '' \ --null-non-string '0' \ -->意思是把空的字符串值替换为0
1、Sort by和order by的区别?
2、hadoop fs -ls和hadoop fs -ls /的区别?
不加斜杠意味着的是:/user/hadoop -->/用户/当前用户名
加斜杠意味着的是hdfs的根目录
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。