我正在研究一项计划每天运行一次的hadoop计划。它需要一堆json文档,每个文档都有一个时间戳,显示文档何时添加。我的程序应该只处理自上次运行以来添加的文档。所以,我需要保持一个状态,这是一个时间戳,显示我的hadoop作业最后一次运行。我在考虑将这种状态存储在SQL Server中并在我的工作的驱动程序中查询。这是一个很好的解决方案,还是一个更好的解决方案?
P.S。我的hadoop工作正在HDInsight上运行。说过仍然可以从我的驱动程序查询SQL服务器吗?
答案 0 :(得分:1)
我们为在AWS(亚马逊网络服务)中运行的工作流程解决了存储在S3中的数据的问题。
我们的设置:
<强>问题:强>
我们使用Flume将数据提取到Amazon S3中。所有摄取的数据都在同一个文件夹中(S3是一个键/值存储,没有文件夹的概念。这里的文件夹意味着,所有的数据都有相同的前缀。例如/tmp/1.txt,/tmp/2.txt等这里/ tmp /是键前缀)。
我们有一个ETL工作流程,计划在一小时内运行一次。但是,由于所有数据都被摄取到同一个文件夹中,因此我们必须区分已处理和未处理文件。
例如第一小时的数据是:
/tmp/1.txt
/tmp/2.txt
当工作流首次启动时,它应该处理来自&#34; 1.txt&#34;的数据。和&#34; 2.txt&#34;并将其标记为已处理。
如果是第二个小时,摄取的数据是:
/tmp/3.txt
/tmp/4.txt
/tmp/5.txt
然后,2小时后文件夹中的总数据将是:
/tmp/1.txt
/tmp/2.txt
/tmp/3.txt
/tmp/4.txt
/tmp/5.txt
因为,&#34; 1.txt&#34;和&#34; 2.txt&#34;已经处理并标记为已处理,在第二次运行期间,作业应该只处理&#34; 3.txt&#34;,&#34; 4.txt&#34;和&#34; 5.txt&#34;。
解决方案:
我们开发了一个库(让我们将其称为FileManager
),用于管理已处理文件的列表。我们将此库作为Java操作插入到Oozie工作流程中。这是工作流程的第一步。
该库还负责忽略Flume目前正在编写的文件。当Flume将数据写入文件时,这些文件有&#34; _current&#34;后缀。因此,这些文件被忽略进行处理,直到完全写入。
生成的文件是以时间戳作为后缀生成的。对于例如&#34; hourly_feed.1234567&#34 ;.因此,文件名按其创建的升序排列。
为了获取未处理文件的列表,我们使用了S3使用标记查询的功能(例如,如果文件夹中有10,000个文件,如果指定标记作为第5,000个文件的名称,则S3将文件从5001返回到10,000)。
我们对每个文件都有以下3种状态:
对于每个文件,我们在MySQL DB中存储了以下详细信息:
FileManager
公开的以下接口:
GetLatestFiles
:返回最新未处理文件列表UpdateFileStatus
:处理完文件后,更新文件状态以下是确定尚未处理的文件的步骤:
order by created desc
)。 我们使用Oozie进行工作流程管理。 Oozie工作流程有以下步骤:
<强>去重强>: 当您实现这样的库时,可能会重复记录(在某些极端情况下,可能会拾取两次相同的文件进行处理)。我们实施了重复数据删除逻辑来删除重复记录。
答案 1 :(得分:0)
您可以使用日期时间重命名结果文档,然后您的程序可以根据文档名称处理文档。
答案 2 :(得分:0)
检查上一次运行时间戳的驱动程序是一种很好的方法,但是对于存储上次运行时间戳,可以使用来自HDFS的临时文件。