如何在Hadoop中共享全局序列号生成器?

时间:2011-10-28 12:49:43

标签: java hadoop mapreduce rpc

现在我正在使用Hadoop处理最终将加载到同一个表中的数据。我需要一个共享的序列号生成器来为每一行生成id。现在我使用以下方法生成唯一编号:

1)在HDFS中创建一个文本文件,例如test.seq,以保存当前的序列号。

2)我使用锁定文件“.lock”来控制并发。假设我们有两个并行处理数据的任务。如果task1想要获取该号码,它将检查锁定文件是否存在。如果是,则表示task2正在从test.seq访问该号码,然后task1必须等待。当task2获取了该号码时,它会在返回时通过增加1来覆盖旧号码,并删除锁定文件“.lock”。当task1看到.lock消失时,task1将首先创建一个“.lock”文件,然后以相同的方式获取序列号。

但是,我不确定这种方法是否切实可行。因为我将.lock和test.seq文件保存在HDFS中,即使任务1更改了test.seq的内容,它也可能无法立即被task2识别。当其他任务通过namenode获取有关HDFS中数据的信息时。因此,datanode将首先通知对namenode的更改,然后通知其他任务更改。这是对的吗?

另一个想法是创建在Master上运行的torjan程序。所以,任务获取顺序号是通过RPC Torjan程序。但是如何在主程序上运行Torjan程序?

有人可以给我一些建议吗?谢谢!

3 个答案:

答案 0 :(得分:6)

你是对的,HDFS不能为你提供快速变化数据的一致视图。这种方法也会给您的名称节点带来大量流量负担。

我强烈建议您投入精力部署ZooKeeper。它是作为一项独立服务构建的,但是专为使用Hadoop进行全局状态跟踪而设计。好东西。

要解决您的问题,您将在ZooKeeper为升序值分配的目录中创建节点。它可以扩展,容错,以及所有好东西。

答案 1 :(得分:4)

主要问题是由于水平可伸缩性属性,您选择hadoop 当您包含需要从中心点协调的内容时,所有形式的水平可伸缩性都会受到很大影响。

所以你有两个选择:

  1. 您接受缩放限制并寻求其他人提出的解决方案。 (比如zookeeper选项)
  2. 您选择的解决方案不需要中央协调。以钥匙的某些属性为代价。
  3. 我会试着看看后者是否适合你的目的。 一个这样的解决方案可能是您获取当前跟踪器实例的id并附加本地计数器值。 通过这种方式,每个跟踪器和同一作业的多次运行中的值是唯一的,并且不是在作业内。

答案 2 :(得分:0)

如果您只需要按时间顺序排列条目,请存储时间戳而不是ID。