12

我一直在尝试为表的每一行(超过 3000 万行)生成唯一的 ID。

  • 由于 Hadoop 的并行性,使用序列号显然不起作用。
  • 内置的 UDF rand() 和 hash(rand(),unixtime()) 似乎会产生冲突。

必须有一种简单的方法来生成行 ID,我想知道有人有解决方案。

  • 我的下一步只是创建一个 Java map reduce 作业来生成一个真正的哈希字符串,其中包含一个安全的随机 + 主机 IP + 当前时间作为种子。但我想在做之前我会在这里问;)
4

8 回答 8

21

使用反射 UDF 生成 UUID。

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

更新 (2019)

长期以来,UUID 是您在 Hive 中获得独特价值的最佳选择。从 Hive 4.0 开始,Hive 提供了一个代理键 UDF,您可以使用它来生成比 UUID 字符串性能更高的唯一值。文档仍然有点稀疏,但这里有一个示例:

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

要让 Hive 为您生成 ID,请在插入语句中使用列列表,并且不要提及代理键列:

-- staging_table would have two string columns.
insert into customer (name, city) select * from staging_table;
于 2013-08-18T04:54:15.473 回答
7

不确定这是否有帮助,但这里有......

考虑本机 MapReduce 类比:假设您的输入数据集是基于文本的,输入 Mapper 的键(以及因此唯一的 ID)将是,对于每一行,文件的名称加上其字节偏移量。

当您将数据加载到 Hive 中时,如果您可以创建一个包含此信息的额外“列”,您将免费获得您的 rowID。它在语义上没有意义,但你上面提到的方法也是如此。

于 2013-08-15T18:04:47.053 回答
5

详细说明 jtravaglini 的答案,自 0.8.0 以来有 2 个内置的 Hive 虚拟列可用于生成唯一标识符:

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,
...
于 2014-02-08T16:06:22.883 回答
3

使用 ROW_NUMBER 函数生成单调递增的整数 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

于 2019-03-29T02:19:38.203 回答
2

反射(“java.util.UUID”,“随机UUID”)

我无法投票赞成另一个。我需要一个纯二进制版本,所以我使用了这个:

unhex(regexp_replace(reflect('java.util.UUID','randomUUID'), '-', ''))

于 2014-03-15T22:02:51.760 回答
1

根据您的工作性质以及您计划运行它们的频率,使用序列号实际上可能是一个合理的选择。您可以按照其他 SO questionrank()中的描述实现UDF 。

于 2013-08-15T18:32:00.767 回答
1

编写一个自定义 Mapper,为每个 Map 任务保留一个计数器,并将 JobID()(从 MR API 获得)+计数器的当前值的串联创建为行的行 ID。在检查下一行之前,递增计数器。

于 2014-11-24T09:11:52.173 回答
1

如果您想使用多个映射器和大型数据集,请尝试使用此 UDF:https ://github.com/manojkumarvohra/hive-hilo

它利用 zookeeper 作为中央存储库来维护序列状态并生成唯一的递增数值

于 2017-02-15T09:43:23.327 回答