HIVE分桶表的详解和创建实例.docx
《HIVE分桶表的详解和创建实例.docx》由会员分享,可在线阅读,更多相关《HIVE分桶表的详解和创建实例.docx(14页珍藏版)》请在冰豆网上搜索。
HIVE分桶表的详解和创建实例
我们学习一下分桶表,其实分区和分桶这两个概念对于初学者来说是比较难理解的。
但对于理解了的人来说,发现又是如此简单。
我们先建立一个分桶表,并尝试直接上传一个数据
createtablestudent4(snoint,snamestring,sexstring,sageint,sdeptstring)clusteredby(sno)into3bucketsrowformatdelimitedfieldsterminatedby',';
sethive.enforce.bucketing=true;强制分桶。
loaddatalocalinpath'/home/hadoop/hivedata/students.txt'overwriteintotablestudent4;
我们看到虽然设置了强制分桶,但实际student表下面只有一个students一个文件。
分桶也就是分区,分区数量等于文件数,所以上面方法并没有分桶。
现在,我们用插入的方法给另外一个分桶表传入同样数据
createtablestudent4(snoint,snamestring,sexstring,sageint,sdeptstring)clusteredby(sno)into3bucketsrowformatdelimitedfieldsterminatedby',';
sethive.enforce.bucketing=true;强制分桶。
loaddatalocalinpath'/home/hadoop/hivedata/students.txt'overwriteintotablestudent4;
我们看到虽然设置了强制分桶,但实际STUDENT表下面只有一个STUDENTS一个文件。
分桶也就是分区,分区数量等于文件数,所以上面方法并没有分桶。
#创建第2个分桶表
createtablestu_buck(snoint,snamestring,sexstring,sageint,sdeptstring)
clusteredby(sno)
sortedby(snoDESC)
into4buckets
rowformatdelimited
fieldsterminatedby',';
#设置变量,设置分桶为true,设置reduce数量是分桶的数量个数
sethive.enforce.bucketing=true;
setmapreduce.job.reduces=4;
#开会往创建的分通表插入数据(插入数据需要是已分桶,且排序的)
#可以使用distributeby(sno)sortby(snoasc)或是排序和分桶的字段相同的时候使用Clusterby(字段)
#注意使用clusterby就等同于分桶+排序(sort)
insertintotablestu_buck
selectsno,sname,sex,sage,sdeptfromstudentdistributeby(sno)sortby(snoasc);
QueryID=root_20171109145012_7088af00-9356-46e6-a988-f1fc5f6d2e13
Totaljobs=1
LaunchingJob1outof1
Numberofreducetasksdeterminedatcompiletime:
4
Inordertochangetheaverageloadforareducer(inbytes):
sethive.exec.reducers.bytes.per.reducer=
Inordertolimitthemaximumnumberofreducers:
sethive.exec.reducers.max=
Inordertosetaconstantnumberofreducers:
setmapreduce.job.reduces=
StartingJob=job_1510197346181_0014,TrackingURL=http:
//server71:
8088/proxy/application_1510197346181_0014/
KillCommand=/usr/local/hadoop/bin/hadoopjob -killjob_151********81_0014
HadoopjobinformationforStage-1:
numberofmappers:
1;numberofreducers:
4
2017-11-0914:
50:
59,642Stage-1map=0%, reduce=0%
2017-11-0914:
51:
38,682Stage-1map=100%, reduce=0%,CumulativeCPU5.04sec
2017-11-0914:
52:
31,935Stage-1map=100%, reduce=50%,CumulativeCPU7.91sec
2017-11-0914:
52:
33,467Stage-1map=100%, reduce=67%,CumulativeCPU15.51sec
2017-11-0914:
52:
39,420Stage-1map=100%, reduce=83%,CumulativeCPU22.5sec
2017-11-0914:
52:
40,953Stage-1map=100%, reduce=92%,CumulativeCPU25.86sec
2017-11-0914:
52:
42,243Stage-1map=100%, reduce=100%,CumulativeCPU28.01sec
MapReduceTotalcumulativeCPUtime:
28seconds10msec
EndedJob=job_151********81_0014
Loadingdatatotabledefault.stu_buck
Tabledefault.stu_buckstats:
[numFiles=4,numRows=22,totalSize=527,rawDataSize=505]
MapReduceJobsLaunched:
Stage-Stage-1:
Map:
1 Reduce:
4 CumulativeCPU:
28.01sec HDFSRead:
18642HDFSWrite:
819SUCCESS
TotalMapReduceCPUTimeSpent:
28seconds10msec
OK
Timetaken:
153.794seconds
我们设置reduce的数量为4,学过mapreduce的人应该知道reduce数等于分区数,也等于处理的文件数量。
把表或分区划分成bucket有两个理由
1,更快,桶为表加上额外结构,链接相同列划分了桶的表,可以使用map-sidejoin更加高效。
2,取样sampling更高效。
没有分区的话需要扫描整个数据集。
hive>createtablebucketed_user(idint,namestring)
>clusteredby(id)sortedby(idasc)into4buckets;
重点1:
CLUSTEREDBY来指定划分桶所用列和划分桶的个数。
HIVE对key的hash值除bucket个数取余数,保证数据均匀随机分布在所有bucket里。
重点2:
SORTEDBY对桶中的一个或多个列另外排序
总结:
我们发现其实桶的概念就是MapReduce的分区的概念,两者完全相同。
物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。
而分区表的概念,则是新的概念。
分区代表了数据的仓库,也就是文件夹目录。
每个文件夹下面可以放不同的数据文件。
通过文件夹可以查询里面存放的文件。
但文件夹本身和数据的内容毫无关系。
桶则是按照数据内容的某个值进行分桶,把一个大文件散列称为一个个小文件。
这些小文件可以单独排序。
如果另外一个表也按照同样的规则分成了一个个小文件。
两个表join的时候,就不必要扫描整个表,只需要匹配相同分桶的数据即可。
效率当然大大提升。
同样,对数据抽样的时候,也不需要扫描整个文件。
只需要对每个分区按照相同规则抽取一部分数据即可。
Hive分桶通俗点来说就是将表(或者分区,也就是hdfs上的目录而真正的数据是存储在该目录下的文件)中文件分成几个文件去存储。
比如表buck(目录,里面存放了某个文件如sz.data)文件中本来是1000000条数据,由于在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便,所以我们可以分4个文件去存储。
下面记录了从头到尾以及出现问题的操作
进行连接,创建数据库myhive2,使用该数据库
[root@mini1~]#cdapps/hive/bin
[root@mini1bin]#./beeline
Beelineversion1.2.1byApacheHive
beeline>!
connectjdbc:
hive2:
//localhost:
10000
Connectingtojdbc:
hive2:
//localhost:
10000
Enterusernameforjdbc:
hive2:
//localhost:
10000:
root
Enterpasswordforjdbc:
hive2:
//localhost:
10000:
******
Connectedto:
ApacheHive(version1.2.1)
Driver:
HiveJDBC(version1.2.1)
Transactionisolation:
TRANSACTION_REPEATABLE_READ
0:
jdbc:
hive2:
//localhost:
10000>showdatabases;
+----------------+--+
|database_name|
+----------------+--+
|default|
|myhive|
+----------------+--+
2rowsselected(1.795seconds)
0:
jdbc:
hive2:
//localhost:
10000>createdatabasemyhive2;
Norowsaffected(0.525seconds)
0:
jdbc:
hive2:
//localhost:
10000>usemyhive2;
Norowsaffected(0.204seconds)
创建分桶表,导入数据,查看表内容
0:
jdbc:
hive2:
//localhost:
10000>createtablebuck(idstring,namestring)
0:
jdbc:
hive2:
//localhost:
10000>clusteredby(id)sortedby(id)into4buckets
0:
jdbc:
hive2:
//localhost:
10000>rowformatdelimitedfieldsterminatedby',';
Norowsaffected(0.34seconds)
0:
jdbc:
hive2:
//localhost:
10000>descbuck;
+-----------+------------+----------+--+
|col_name|data_type|comment|
+-----------+------------+----------+--+
|id|string||
|name|string||
+-----------+------------+----------+--+
2rowsselected(0.55seconds)
loaddatalocalinpath'/root/sz.data'intotablebuck;
INFO:
Loadingdatatotablemyhive2.buckfromfile:
/root/sz.data
INFO:
Tablemyhive2.buckstats:
[numFiles=1,totalSize=91]
Norowsaffected(1.411seconds)
0:
jdbc:
hive2:
//localhost:
10000>select*frombuck;
+----------+------------+--+
|buck.id|buck.name|
+----------+------------+--+
|1|zhangsan|
|2|lisi|
|3|wangwu|
|4|furong|
|5|fengjie|
|6|aaa|
|7|bbb|
|8|ccc|
|9|ddd|
|10|eee|
|11|fff|
|12|ggg|
+----------+------------+--+
如果分桶了的话,那么buck目录下应该有4个文件,页面查看
image.png
然而并没有,还是自己导入的那个文件。
这是因为分桶不是hive活着hadoop自动给我们划分文件来分桶的,而应该是我们分好之后导入才好。
需要设置开启分桶,设置reducetask数量(跟分桶数量一致)
0:
jdbc:
hive2:
//localhost:
10000>sethive.enforce.bucketing=true;
Norowsaffected(0.063seconds)
0:
jdbc:
hive2:
//localhost:
10000>sethive.enforce.bucketing;
+------------------------------+--+
|set|
+------------------------------+--+
|hive.enforce.bucketing=true|
+------------------------------+--+
1rowselected(0.067seconds)
0:
jdbc:
hive2:
//localhost:
10000>setmapreduce.job.reduces=4;
那么创建另外一个表tp,将该表数据放入到buck中(select出来insert进去),放入的时候指定进行分桶,那么会分四桶,每个里面进行排序。
那么最后buck表就进行了分桶(分桶是导入的时候就分桶的而不是自己实现分桶(文件划分))。
接下来,清空buck表信息,创建表tp,将tp中数据查询出来insertinto到buck中。
0:
jdbc:
hive2:
//localhost:
10000>truncatetablebuck;
Norowsaffected(0.316seconds)
0:
jdbc:
hive2:
//localhost:
10000>createtabletp(idstring,namestring)
0:
jdbc:
hive2:
//localhost:
10000>rowformatdelimitedfieldsterminatedby',';
Norowsaffected(0.112seconds)
0:
jdbc:
hive2:
//localhost:
10000>loaddatalocalinpath'/root/sz.data'intotabletp;
INFO:
Loadingdatatotablemyhive2.tpfromfile:
/root/sz.data
INFO:
Tablemyhive2.tpstats:
[numFiles=1,totalSize=91]
Norowsaffected(0.419seconds)
0:
jdbc:
hive2:
//localhost:
10000>showtables;
+-----------+--+
|tab_name|
+-----------+--+
|buck|
|tp|
+-----------+--+
2rowsselected(0.128seconds)
0:
jdbc:
hive2:
//localhost:
10000>select*fromtp;
+--------+-----------+--+
|tp.id|tp.name|
+--------+-----------+--+
|1|zhangsan|
|2|lisi|
|3|wangwu|
|4|furong|
|5|fengjie|
|6|aaa|
|7|bbb|
|8|ccc|
|9|ddd|
|10|eee|
|11|fff|
|12|ggg|
+--------+-----------+--+
12rowsselected(0.243seconds)
0:
jdbc:
hive2:
//localhost:
10000>insertintobuck
0:
jdbc:
hive2:
//localhost:
10000>selectid,namefromtpdistributeby(id)sortby(id);
INFO:
Numberofreducetasksdeterminedatcompiletime:
4
INFO:
Inordertochangetheaverageloadforareducer(inbytes):
INFO:
sethive.exec.reducers.bytes.per.reducer=
INFO:
Inordertolimitthemaximumnumberofreducers:
INFO:
sethive.exec.reducers.max=
INFO:
Inordertosetaconstantnumberofreducers:
INFO:
setmapreduce.job.reduces=
INFO:
numberofsplits:
1
INFO:
Submittingtokensforjob:
job_150********95_0028
INFO:
Theurltotrackthejob:
http:
//mini1:
8088/proxy/application_1508216103995_0028/
INFO:
StartingJob=job_1508216103995_0028,TrackingURL=http:
//mini1:
8088/proxy/application_1508216103995_0028/
INFO:
KillCommand=/root/apps/hadoop-2.6.4/bin/hadoopjob-killjob_150********95_0028
INFO:
HadoopjobinformationforStage-1:
numberofmappers:
1;numberofreducers:
4
INFO:
2017-10-1903:
57:
23,631Stage-1map=0%,reduce=0%
INFO:
2017-10-1903:
57:
29,349Stage-1map=100%,reduce=0%,CumulativeCPU1.18sec
INFO:
2017-10-1903:
57:
40,096Stage-1map=100%,reduce=25%,CumulativeCPU2.55sec
INFO:
2017-10-1903:
57:
41,152Stage-1map=100%,reduce=75%,CumulativeCPU5.29sec
INFO:
2017-10-1903:
57:
42,375Stage-1map=100%,reduce=100%,CumulativeCPU6.61sec
INFO:
MapReduceTotalcumulativeCPUtime:
6seconds610msec
INFO:
EndedJob=job_150********95_0028
INFO:
Loadingdatatotablemyhive2.buckfromhdfs:
//192.168.25.127:
9000/user/hive/warehouse/myhive2.db/buck/.hive-staging_hive_2017-10-19_03-57-14_624_198********58899177-1/-ext-10000
INFO:
Tablemyhive2.buckstats:
[numFiles=4,numRows=12,totalSize=91,rawDataSize=79]
Norowsaffected(29.238seconds)
0:
jdbc:
hive2:
//localhost:
10000>select*frombuck;
+----------+------------+--+
|buck.id|buck.name|
+----------+------------+--+
|11|fff|
|4|furong|
|8|ccc|
|1|zhangsan|
|12|ggg|
|5|fengjie|
|9|ddd|
|2|lisi|
|6|aaa|
|10|eee|
|3|wangw