精华内容
下载资源
问答
  • Hive分桶表

    2021-04-05 09:09:51
    Hive分桶表

    Hive分桶表

    分区的使用场景
    • 分区提供了一个隔离数据和优化查询的便利方式,不过并非所有的数据都可形成合理的分区,尤其是需要确定合适大小的分区划分方式,不合理的数据分区划分方式可能导致有的分区数据过多,而某些分区没有什么数据的尴尬情况。

    • 分桶是将数据集分解为更容易管理的若干部分的另一种技术。

    数据分桶的原理
    • 和MR中的HashPartitioner的原理一样。
    • MR中:按照key的hash值去模除以reduceTask的个数。
    • Hive中:按照分桶字段的hash值去模除以分桶的个数。
      Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录放在哪个桶中。
    • 每个桶就是表目录里的一个文件,一个作业产生的桶和reduce任务个数相同。
    数据分桶的作用
    • 方便抽样
      使取样更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

    • 提高join查询效率
      桶为表加上了额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连接两个在相同列上划分了桶的表,可以使Map端连接更高效的实现。比如join操作,对于join操作两个表有一个相同的列,如果对这两个表都进行了桶操作,那么将保存相同列值的桶进行join操作就可以,可以大大减少join的数据量。

    创建数据分桶表
    • cluster by(col,col) into 100buckets
    • 分桶中的字段是原始数据中存在的。分区表,分区字段在原始文件中并不存在。
      原文参考此处
    展开全文
  • Hive 分桶表

    千次阅读 2017-02-05 14:29:42
    hive 分桶表

    简介

    本文主要介绍了Hive中分桶表的使用及作用

    分桶和分区

    分区提供了一个隔离数据和优化查询的便利的方式.但是当分区的数量过多时,会产生过多的小分区,这样会给namenode带来较大的压力.分桶试讲数据集分解成更容易管理的若干部分的另一个技术.

    使用

    我们先准备我们将使用的分桶表的数据.

    1,jack,2016/11/11
    2,michael,2016/11/12
    3,summer,2016/11/13
    4,spring,2016/11/14
    5,nero,2016/11/15
    6,book,2016/12/21
    7,node,2016/12/22
    8,tony,2016/12/23
    9,green,2016/12/24
    10,andy,2016/12/25
    11,kaith,2016/12/26
    12,spring,2016/12/27
    13,andy,2016/12/28
    14,tony,2016/12/29
    15,green,2016/12/30
    16,andy,2016/12/31
    17,kaith,2017/1/1
    18,xiaoming,2017/1/2

    如上所示,这是一张顾客信息表,3个字段分别代表顾客的id,name,birthday

    创建桶表

    桶表的建表语法和普通表类似,但是需要制定分桶的规则和桶的个数.

    create table t_bucket(id int,name string,birthday string)
    clustered by (id) 
    into 4 buckets
    row format delimited fields terminated by ',';

    我们设定桶表按照id进行分桶,桶内数据按照id进行排序.注意这里的建表语句只是告诉hive,t_bucket这张表是应该按照这种方式去存储,但是并不会在插入数据时帮我们去分桶存储.我们来做个试验:
    我们将上面准备好的数据插入t_bucket表

    load data local inpath '/home/spark/jar/testdata/Customer.txt' into table t_bucket;

    然后我们到hdfs的目录去查看,发现并没有安装我们预先设计的方式去存储数据,数据文件个数为一个;

    hive (test_neil)> dfs -ls /user/hive/warehouse/test_neil.db/t_bucket;
    Found 1 items
    -rwxr-xr-x   1 root staff        364 2017-02-05 12:44 /user/hive/warehouse/test_neil.db/t_bucket/Customer.txt
    

    事实上hive采用的为读时模式,他并不会去判断插入表的数据是否符合元数据的信息.因为我们使用load插入数据并不会产生reduce,数据量较小,只生成了一个数据文件,因此这并不是一个分桶表.一般我们并不采用load的方式去加载数据到bucket表,我们采用insert的方式,使用select将数据变成我们分桶指定的模式.

    正确的load方式

    首先我们把数据导入另外一张表中

    create table t_temp(id int,name string,birthday string)
    row format delimited fields terminated by ',';
    
    load data local inpath 'home/spark/jar/testdata/Customer.txt' into table t_temp;

    在我们导入数据前,需要将hive.enforce.bucketing的值设置为true,

    set hive.enforce.bucketing = true

    这个参数将强制控制ruduce的个数去和我们指定的分桶个数相适配.

    将t_bucket表truncate掉,再次导入数据

    truncate table t_bucket;
    
    insert into table t_bucket
    select id,name,birthday
    from t_temp
    cluster by id;

    在job执行的log中,我们可以看到最终分桶的情况:

    Loading data to table test_neil.t_bucket
    Table test_neil.t_bucket stats: [numFiles=4, numRows=18, totalSize=346, rawDataSize=328]

    我们再次去查看t_bucket表的目录发现,这张表的数据已经被分成了四份,这样我们便成功的将文件进行了分桶的操作;

    hive (test_neil)> dfs -ls /user/hive/warehouse/test_neil.db/t_bucket;
    Found 4 items
    -rwxr-xr-x   1 root staff         78 2017-02-05 13:14 /user/hive/warehouse/test_neil.db/t_bucket/000000_0
    -rwxr-xr-x   1 root staff         92 2017-02-05 13:14 /user/hive/warehouse/test_neil.db/t_bucket/000001_0
    -rwxr-xr-x   1 root staff         98 2017-02-05 13:14 /user/hive/warehouse/test_neil.db/t_bucket/000002_0
    -rwxr-xr-x   1 root staff         78 2017-02-05 13:14 /user/hive/warehouse/test_neil.db/t_bucket/000003_0

    我们去查看文件的内容:

    dfs -cat /user/hive/warehouse/test_neil.db/t_bucket/000000_0;
    dfs -cat /user/hive/warehouse/test_neil.db/t_bucket/000001_0;
    dfs -cat /user/hive/warehouse/test_neil.db/t_bucket/000002_0;
    dfs -cat /user/hive/warehouse/test_neil.db/t_bucket/000003_0;

    结果:

    4/spring/2016/11/14
    8/tony/2016/12/23
    12/spring/2016/12/27
    16/andy/2016/12/31
    1/jack/2016/11/11
    5/nero/2016/11/15
    9/green/2016/12/24
    13/andy/2016/12/28
    17/kaith/2017/1/1
    2/michael/2016/11/12
    6/book/2016/12/21
    10/andy/2016/12/25
    14/tony/2016/12/29
    18/xiaoming/2017/1/2
    3/summer/2016/11/13
    7/node/2016/12/22
    11/kaith/2016/12/26
    15/green/2016/12/30

    我们可以看到,我们的客户数据被分成了四份.那么这四份是如何进行划分的呢?其实我们已经制定了按照id进行划分,因此hive使用hash散列的方式,将id个数对桶个数求余数,我们id为18个,对桶个数(4个)求余数,结果为4.这样每个桶最少有4条数据,同时这样的方式得到的桶内数据其实相当于是随机的.

    cluster by和distribute by

    在上面的select语句中,我们使用了cluster by语句执行分桶的方式.我们发现其实桶内的数据是按照id字段进行升序排列的.其实cluster by相当于distribute by+sort by.sort by默认按照升序进行排列.

    sort by排序的为reducer内的数据,在这里就是bucket内的数据.这样数据是局部有序的,而order by是全局有序的.执行了order by,最后只能有个reduce,因为要做全局的排序.

    但是呢,distribute by+sort by的组合会更加的灵活,因为我们可以去按照id分桶,按照birthday去进行排序.我们可以做如下的试验.

    insert into table t_bucket
    select id,name,birthday
    from t_temp
    distribute by id
    sort by birthday desc;

    我们再去执行select,发现数据是按照id进行分桶的,但是数据的排列顺序其实是按照birthday进行降序排列的.

    16  andy    2016/12/31
    12  spring  2016/12/27
    8   tony    2016/12/23
    4   spring  2016/11/14
    17  kaith   2017/1/1
    13  andy    2016/12/28
    9   green   2016/12/24
    5   nero    2016/11/15
    1   jack    2016/11/11
    18  xiaoming    2017/1/2
    14  tony    2016/12/29
    10  andy    2016/12/25
    6   book    2016/12/21
    2   michael 2016/11/12
    15  green   2016/12/30
    11  kaith   2016/12/26
    7   node    2016/12/22
    3   summer  2016/11/13

    分桶的好处

    1.分桶加快了join查询的速度.
    对于map端连接的情况,两个表以相同方式划分桶。处理左边表内某个桶的 mapper知道右边表内相匹配的行在对应的桶内。因此,mapper只需要获取那个桶 (这只是右边表内存储数据的一小部分)即可进行连接。这一优化方法并不一定要求 两个表必须桶的个数相同,两个表的桶个数是倍数关系也可以.这样便采用了Map-side join的方式,避免全表进行笛卡尔积的操作.

    **关于桶内排序的意义:
    桶中的数据可以根据一个或多个列另外进行排序。由于这样对每个桶的连接变成了高效的归并排序(merge-sort), 因此可以进一步提升map端连接的效率。**

    **分桶个数:
    如果两个表的分桶个数之间没有什么倍数的关系,这样分桶表在做join时并不会提升效率,因为数据随机分发,桶和桶之间并没有对应关系.**

    2.使取样(sampling)更加的高效
    在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便.
    使用上面的t-bucket我们进行演示.
    假如我们使用的为一个大规模的数据集,我们只想去抽取部分数据进行查看.使用bucket表可以变得更加的高效

    select * from t_bucket tablesample(bucket 1 out of 4);
    select * from t_bucket tablesample(bucket 1 out of 4 on id);

    这样表示我们从bucket1开始取样1个bucket的数据.

    select * from t_bucket tablesample(bucket x out of y on xx);

    x表示从哪个bucket进行抽样,桶计数从1开始.y用来计算抽取数据的量,计算方式为分桶数/y.假设我们一共分了128个桶,y设置为32,则表示要抽取4个bucket,如果x为12,则抽取的数据来自于12/13/14/15.y的值可以不为桶个数的公约数,可以为任意值.

    参考文章

    Hive 基础之:分区、桶、Sort Merge Bucket Join

    展开全文
  • hive 分桶表

    2019-06-21 15:18:34
    昨天转载了朋友的博客 里面有分桶表的描述,今天自己好好的练习了,再整理记录一下: 首先是修改了一个文件 在我这的路径是: /opt/software/hive-1.2.1/conf/hive-site.xml 在这其中添加一些配置: <...

    昨天转载了朋友的博客 里面有分桶表的描述,今天自己好好的练习了,再整理记录一下:
    首先是修改了一个文件 在我这的路径是:

    /opt/software/hive-1.2.1/conf/hive-site.xml
    
    

    在这其中添加一些配置:

    		<property>
                    <name>hive.exec.dynamic.partition</name>
                    <value>true</value>
            </property>
            
            <property>
                    <name>hive.exec.dynamic.partition.mode</name>
                    <value>nostrict</value>
            </property>
            
            <property>
                    <name>hive.enforce.bucketing</name>
                    <value>true</value>
            </property>
    
    

    在我的数据库中本就有一个表,且表中有数据,字段及数据如下
    字段: id int ,name string

    hive> select * from a;
    OK
    1	"张三"	10
    2	"李四"	10
    3	"张闫"	10
    4	"彬彬"	10
    5	"肉肉"	10
    
    

    建立分桶表

    hive> create table b1(id int,name string)
        > cluster
        > clustered by (id) into 3 bucket
        > clustered by (id) into 3 buckets
        > row format delimited
        > fields terminated by ' ';
    OK
    Time taken: 0.075 seconds
    
    

    然后向分桶表中添加数据

    insert into table b1 select id,name from a;
    
    

    查看分桶表中数据

    hive> select * from b1;
    OK
    1	"张三"
    2	"李四"
    3	"张闫"
    4	"彬彬"
    5	"肉肉"
    
    

    按照分区分别分别看数据

    hive> select * from b1 tablesample  (bucket 1 out of 3 on id);
    OK
    3	"张闫"
    Time taken: 0.699 seconds, Fetched: 1 row(s)
    hive> select * from b1 tablesample  (bucket 2 out of 3 on id);
    OK
    1	"张三"
    4	"彬彬"
    Time taken: 0.064 seconds, Fetched: 2 row(s)
    hive> select * from b1 tablesample  (bucket 3 out of 3 on id);
    OK
    2	"李四"
    5	"肉肉"
    Time taken: 0.06 seconds, Fetched: 2 row(s)
    
    

    第一个桶中放的是id模3得0得数据
    id %3 =0
    第二个桶中放的是id模3得1得数据
    id %3 =1
    第三个桶中放的是id模3得2得数据
    id %3 =2

    									整理如上;
    									如有不足请多多指出;
    
    展开全文
  • hive分桶表

    2020-06-26 11:27:01
    分桶表 与分区的目录不同,分桶是将数据按照指定的字段进行划分到多个文件当中去,分桶就是MapReduce中的分区. 分桶规则:对分桶字段值进行哈希,哈希值除以的个数求余,余数决定了该条记录在哪个中,也就是...

    分桶表

    • 与分区的分目录不同,分桶是将数据按照指定的字段进行划分到多个文件当中去,分桶就是MapReduce中的分区.
    • 分桶规则:对分桶字段值进行哈希,哈希值除以桶的个数求余,余数决定了该条记录在哪个桶中,也就是余数相同的在一个桶中。
    • 优点:1、提高join查询效率 2、提高抽样效率

    标题分桶表操作

    • 开启 Hive 的分桶功能

    set hive.enforce.bucketing=true;

    • 创建临时表
    create table temp (
    name string,
    type string
    ) row format delimited fields terminated by ' ';
    
    • 创建分桶表 type为分桶字段,into 3 buckets表示将表数据分成三个桶,底层其实就是根据type进行分区将type的哈希值对3取模。
    create table myuser 
    (
    name string,
    type string
    ) clustered by(type) into 3 buckets row format delimited fields terminated by ' ';
    
    • 本地有一个用户信息文件包含用户名和所在部门 user.txt
    jack 测试
    tom 开发
    shy 销售
    duke 开发
    zoom 销售
    penut 销售
    leyan 销售
    jkl 开发
    ning 测试
    faker 销售
    wwk 销售
    
    • 将user.txt 加载到temp表
    load data local inpath '/root/user.txt' into table temp;
    
    • 通过insert overwrite给桶表中加载数据
    insert overwrite table myuser select * from temp cluster by(type);
    
    • 然后查看分桶表 可以发现将相同部门的员工分到了同一个桶中,这样就完成了分桶操作。
    shy     销售
    zoom    销售
    penut   销售
    leyan   销售
    faker   销售
    wwk     销售
    jack    测试
    ning    测试
    tom     开发
    duke    开发
    jkl     开发
    

    分桶提高抽样效率

    • 抽样语法 tablesample (bucket x out of y on z); 表示根据z字段将数据分成y份,取第x份。
    • 如下表示将myuser表数据根据type字段分成三份取第二份 可以看到把测试部门数据取出来了。
    hive> select * from myuser tablesample (bucket 2 out of 3 on type);
    OK
    jack    测试
    ning    测试
    
    • 因为myuser就是按照type分桶的,所以抽样时直接将第二个桶数据取出,非常高效,无需全表遍历。
    • 如果按照其他字段进行抽样,就无法进行达到提高效率的目的了,仍然需要全表查询。
    hive> select * from myuser tablesample (bucket 2 out of 3 on name);
    OK
    shy     销售
    penut   销售
    jack    测试
    

    分桶提高join效率

    • 假设我们除了员工表还有一张经理表,表示每个部门的经理是谁
      user
    shy     销售
    zoom    销售
    penut   销售
    leyan   销售
    faker   销售
    wwk     销售
    jack    测试
    ning    测试
    tom     开发
    duke    开发
    jkl     开发
    
       manager
    
    销售 马云
    测试 马化腾
    开发 李彦宏
    
    • 假设两张表都是大表,而且两个表都根据type字段进行分桶。
    • 那么在进行join操作时就可以表A的每个桶就可以和表B对应的桶直接join,而不用全表join,提高查询效率。
    • 比如user表的销售桶数据与manager销售桶数据进行join,测试桶与测试桶数据进行join。将各自join的结果再通过union all进行合并即可。
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,461
精华内容 4,984
关键字:

hive分桶表