Hive中的排序表(ORC文件格式)

时间:2018-08-07 08:30:43

标签: hive orc

我在确保利用Hive表中的排序数据方面遇到一些困难。 (使用ORC文件格式)

我了解我们可以通过在创建DDL中声明一个DISTRIBUTE BY子句来影响如何从Hive表中读取数据。

CREATE TABLE trades
(
    trade_id INT,
    name STRING,
    contract_type STRING,
    ts INT
)
PARTITIONED BY (dt STRING)
CLUSTERED BY (trade_id) SORTED BY (trade_id, time) INTO 8 BUCKETS
STORED AS ORC;

这意味着每次我对此表进行查询时,数据将由trade_id在各个映射器中进行分配,然后对其进行排序。

我的问题是:

我不希望将数据拆分为N个文件(存储桶),因为容量不大,我会保留小文件。

但是,我确实想利用排序插入。

INSERT OVERWRITE TABLE trades
PARTITION (dt)
SELECT trade_id, name, contract_type, ts, dt
FROM raw_trades
DISTRIBUTE BY trade_id
SORT BY trade_id;

我真的需要在创建DLL语句中使用CLUSTERED/SORT吗?还是Hive / ORC知道如何利用插入过程已经确保对数据进行排序这一事实?

做类似的事情是否有意义:

CLUSTERED BY (trade_id) SORTED BY (trade_id, time) INTO 1 BUCKETS

1 个答案:

答案 0 :(得分:2)

带桶装桌子是一个过时的概念。

您不需要在表DDL中编写CLUSTERED BY。

在加载表时,请使用distribute by partition key来减少对reducer的压力,尤其是在编写ORC时,这需要中间缓冲区来构建ORC,并且如果每个reducer加载许多分区,可能会导致OOM异常。

当表很大时,可以使用bytes.per.reducer限制最大文件大小,如下所示:

set hive.exec.reducers.bytes.per.reducer=67108864;--or even less

如果您有更多数据,将启动更多reducer,创建更多文件。这比加载固定数量的桶更灵活。

这也将更好,因为对于小型表,您不需要创建较小的存储桶。

ORC具有内部索引和Bloom筛选器。 Applying SORT you can improve index and bloom filters efficiency because all similar data will be stored together. Also this can improve compression depending on your data enthropy.

如果由于分区数据偏斜并且数据量大而无法通过分区键进行分发,则可以另外随机分发。如果您具有均匀分布的数据,则最好按列进行分布。如果不是,请随机分配以避免单个长期运行的减速器问题。

最后,您的插入语句可能看起来像这样:

set hive.exec.reducers.bytes.per.reducer=33554432; --32Mb per reducer

INSERT OVERWRITE TABLE trades PARTITION (dt)
SELECT trade_id, name, contract_type, ts, dt
FROM raw_trades
DISTRIBUTE BY dt,                    --partition key is a must for big data
              trade_id,              --some other key if the data is too big and key is
                                     --evenly distributed (no skew)   
              FLOOR(RAND()*100.0)%20 --random to distribute additionally on 20 equal parts 

SORT BY contract_type; --sort data if you want filtering by this key 
                       --to work better using internal index

不要在表DDL中使用CLUSTERED BY,因为在插入期间使用DISTRIBUTE BY,ORC w索引和Bloom Bloom + SORT可以更灵活地实现相同目的。

另请阅读:https://stackoverflow.com/a/55375261/2700344 这是有关排序的相关答案:https://stackoverflow.com/a/47416027/2700344