我正在开展一个项目,我仍然坚持以下方案。
我有一张桌子:superMerge(id,name,salary)
我还有另外两个表:table1和table2
所有表(table1,table2和superMerge)具有相同的结构。
现在,我的挑战是从table1和table2插入/更新superMerge表。 table1每10分钟更新一次,table2每20分钟更新一次,因此在时间t = 20分钟我有2个工作试图更新同一个表(在这种情况下是superMerge。)
我想了解如何使用Spark或任何其他hadoop应用程序将此并行插入/更新/合并到superMerge表中。
答案 0 :(得分:5)
这里的问题是这两个工作无法相互沟通,不知道对方在做什么。一个相对简单的解决方案是实现基于文件的基本“锁定”系统:
每个作业在HDFS上的特定文件夹中创建一个(空)文件,指示更新/插入正在进行中并在作业完成时删除该文件
现在,每个作业必须在开始更新/插入之前检查是否存在此类文件。如果存在,作业必须等到文件消失。
答案 1 :(得分:1)
你能控制job1&的代码吗?作业2?你如何安排这些?
通常,您可以将这两个作业转换为每10分钟运行一次的作业。一旦在20分钟内,这个统一的作业以不同的模式运行(从2个表合并),而默认模式将仅从1个表合并。 因此,当您拥有相同的驱动程序时 - 您不需要在两个作业之间进行任何同步(例如锁定)。该解决方案假设工作在10分钟内完成。
答案 2 :(得分:1)
您的数据集有多大?您打算在批处理(Spark)中执行此操作,还是可以流式插入/更新(Spark Streaming)?
让我们假设您想要批量执行此操作:
答案 3 :(得分:0)
我遇到了这种情况,将tb1 DF1写入location1,将tb2 DF2写入位置2,最后只需将路径切换到超级合并表,也可以将表格插入表格插入,但这会占用很多特别是在蜂巢中运行时间。
覆盖到登台位置location1和位置2:
df1.write.mode("overwrite").partitionBy("partition").parquet(location1)
df2.write.mode("overwrite").partitionBy("partition").parquet(location2)
切换到超级合并表的路径:
hiveContext.sql(alter table super_merge_table add if not exists partition(partition=x); LOAD DATA INPATH 'location1/partition=x/' INTO TABLE super_merge_table partition(partition=x))"
hiveContext.sql(alter table super_merge_table add if not exists partition(partition=x); LOAD DATA INPATH 'location2/partition=x/' INTO TABLE super_merge_table partition(partition=x))"
您可以执行并行合并而不会覆盖其他合并。