Hadoop 在配置单元中生成唯一ID

Hadoop 在配置单元中生成唯一ID,hadoop,hash,hive,identifier,Hadoop,Hash,Hive,Identifier,我一直在尝试为表的每一行(3000多万行)生成唯一的ID 由于Hadoop的并行性,使用序列号显然不起作用 内置的UDF rand()和hash(rand(),unixtime())似乎会产生冲突 必须有一种简单的方法来生成行ID,我想知道是否有人有解决方案 我的下一步就是创建一个Java map reduce作业,以生成一个真正的哈希字符串,其中包含一个安全的随机+主机IP+当前时间作为种子。但我想在做这件事之前我应该先问一下;) 不确定这是否有帮助,但接下来 考虑本机MapReduce

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

  • 由于Hadoop的并行性,使用序列号显然不起作用
  • 内置的UDF rand()和hash(rand(),unixtime())似乎会产生冲突
必须有一种简单的方法来生成行ID,我想知道是否有人有解决方案

  • 我的下一步就是创建一个Java map reduce作业,以生成一个真正的哈希字符串,其中包含一个安全的随机+主机IP+当前时间作为种子。但我想在做这件事之前我应该先问一下;)
      不确定这是否有帮助,但接下来

      考虑本机MapReduce模拟:假设您的输入数据集是基于文本的,那么对于每一行,输入映射器的键(以及唯一ID)将是文件名加上其字节偏移量


      当您将数据加载到配置单元中时,如果您可以创建包含此信息的额外“列”,则可以免费获得您的rowID。这在语义上毫无意义,但你上面提到的方法也是如此。

      根据你的工作性质和你计划运行它们的频率,使用序列号实际上可能是一个合理的选择。您可以实现中所述的
      rank()
      UDF。

      使用反射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
      );
      
      要让配置单元为您生成ID,请在insert语句中使用列列表,不要提及代理键列:

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

      详细阐述了jtravaglini的回答, 自0.8.0以来,有2个内置配置单元虚拟列可用于生成唯一标识符:

      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  
      ...
      
      反射(“java.util.UUID”、“randomUUID”)

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


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

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

      如果要使用多个映射器和大型数据集,请尝试使用以下自定义项:


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

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

      从t1中选择()上方的行作为id;
      

      请参见

      您考虑过吗?有谁能给我提供一个示例,我是一名.nET开发人员,希望实现我的自定义映射器功能此功能在hiveserver2中被列入黑名单。是否有解决此问题的方法,或者是否有替代方法?@VinayKumar-根据reflect UDF的文档-您可以为randomUUID编写自己的自定义UDF包装器,该包装器返回值。reflect只是一个帮助工具,可以避免您在任何时候调用某些常用Java方法时需要这样做。注意:虚拟列使用双下划线:
      INPUT\uu FILE\uu NAME
      BLOCK\uu OFFSET\uu in\uu FILE
      小心!对于拼花文件格式,上述解决方案返回多个具有相同行id的行,尽管数据不同。
      select
      Md5(concat(INPUT__FILE__NAME, ':', BLOCK__OFFSET__INSIDE__FILE)) as rowkey,
      ...