在hive中生成唯一的id

xzlaal3s  于 2021-06-03  发布在  Hadoop
关注(0)|答案(8)|浏览(2587)

我一直在尝试为表的每一行(3000多万行)生成唯一的id。
由于hadoop的并行性,使用序列号显然是行不通的。
内置的udfs rand()和hash(rand(),unixtime())似乎会产生冲突。
必须有一个简单的方法来生成行ID,我想知道是否有人有一个解决方案。
我的下一步只是创建一个javamap reduce作业,以生成一个真正的哈希字符串,其中包含一个安全的random+主机ip+当前时间作为种子。但我想在做之前我会先问这里;)

uemypmqf

uemypmqf1#

使用行数函数生成单调递增的整数ID。

select ROW_NUMBER() OVER () AS id from t1;

看到了吗https://community.hortonworks.com/questions/58405/how-to-get-the-row-number-for-particular-values-fr.html

c86crjj0

c86crjj02#

使用reflect udf生成uuid。

reflect("java.util.UUID", "randomUUID")

更新(2019)
很长一段时间以来,uuid是您在hive中获得唯一值的最佳选择。从hive4.0开始,hive提供了一个代理键udf,您可以使用它生成比uuid字符串性能更好的唯一值。文档仍然有点稀疏,但这里有一个示例:

create table customer (
  id bigint default surrogate_key(),
  name string, 
  city string, 
  primary key (id) disable novalidate
);

要让配置单元为您生成ID,请在insert语句中使用列列表,不要提及代理键列:

-- staging_table would have two string columns.
insert into customer (name, city) select * from staging_table;
z4iuyo4d

z4iuyo4d3#

编写一个自定义Map程序,为每个Map任务保留一个计数器,并将jobid()(从mr api获得)+counter的当前值的串联创建为行的行id。在检查下一行之前,递增计数器。

ctrmrzij

ctrmrzij4#

如果要使用多个Map器和大型数据集,请尝试使用以下自定义项:https://github.com/manojkumarvohra/hive-hilo
它利用zookeeper作为中央存储库来维护序列状态,并生成唯一的递增数值

vhmi4jdf

vhmi4jdf5#

根据jtravaglini的回答,自0.8.0以来,有两个内置的配置单元虚拟列可用于生成唯一标识符:

INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE

像这样使用:

select
concat(INPUT__FILE__NAME, ':', BLOCK__OFFSET__INSIDE__FILE) as rowkey,  
...  
;  
...  
OK  
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:0
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:57
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:114
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:171
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:228
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:285
hdfs://<nodename>:8020/user/dhdpadmn/training/training_data/nyse/daily/NYSE_daily2.txt:342  
...

或者您可以使用md5或类似工具匿名,这里有一个指向md5 udf的链接:https://gist.github.com/dataminelab/1050002
(注意函数类名是initcap'md5')

select
Md5(concat(INPUT__FILE__NAME, ':', BLOCK__OFFSET__INSIDE__FILE)) as rowkey,
...
fykwrbwg

fykwrbwg6#

根据工作的性质和计划运行它们的频率,使用序列号实际上可能是一个合理的选择。您可以实现 rank() 另一个问题中描述的自定义项。

pnwntuvh

pnwntuvh7#

我不确定这是否有帮助,但这里是。。。
考虑本机mapreduce模拟:假设您的输入数据集是基于文本的,那么对于每一行,输入Map器的键(因此也是惟一的id)将是文件名及其字节偏移量。
当您将数据加载到配置单元中时,如果您可以创建一个包含此信息的额外“列”,则可以免费获得您的rowid。它在语义上毫无意义,但你上面提到的方法也是如此。

i2byvkas

i2byvkas8#

reflect(“java.util.uuid”,“randomuuid”)
我不能投票支持另一个。我需要一个纯二进制版本,所以我用了这个:
unhex(regexp\u replace(reflect('java.util.uuid','randomuuid'),'-','')

相关问题