其他应用程序正在访问数据时替换HDFS文件

时间:2018-12-09 14:10:43

标签: hdfs

我一直在研究一种在其他使用者/应用程序访问数据时刷新HDFS文件的方法。我有一个HDFS目录,该目录具有供用户访问的文件,我每天都需要用最新的传入数据替换该文件,我的刷新过程仅数秒/毫秒。但是仍然面临的挑战是,由于此刷新过程,已经读取了该数据以进行分析的作业会生效。我刷新文件的方法不是将spark作业产生的数据写到用户可以访问的实际数据位置,而是先将数据写到一个临时位置,然后用hdfs文件替换API替换。但是我的问题仍然没有解决。请提出解决HDFS文件替换的任何解决方案或解决方法,而不影响下游。

      val conf: Configuration = new Configuration()
      val fs: FileSystem = FileSystem.get(conf)
      val currentDate = java.time.LocalDate.now
      val destPath = outputPath + "/data"
      val archivePath = outputPath + "/archive/" + currentDate

      val dataTempPath = new Path(destPath + "_temp")
      val dataPath = new Path(destPath)
      if(fs.exists(dataPath)){
        fs.delete(dataPath, true)
      }
      if(fs.exists(dataTempPath)){
        fs.rename(dataTempPath, dataPath)
      }

      val archiveTempData = new Path(archivePath+"_temp")
      val archive = new Path(archivePath)
      if(fs.exists(archive)){
        fs.delete(archive,true)
      }
      if(fs.exists(archiveTempData)){
        fs.rename(archiveTempData, archive)
      }

1 个答案:

答案 0 :(得分:1)

更简单的方法

每个源或目标使用2个HDFS位置分别循环加载表defs t1_x和t2_x,并使用view_x同样在t1_x和t2_x之间切换。

查询应始终使用view_x。

您可以在下一个周期之前及时清理不再使用的HDFS位置。

提示是将新数据和旧数据保留一段时间。

评论 唯一的缺点是,如果一组查询需要针对旧版本的数据运行。如果更改后的数据具有“添加到”的性质,则没有问题,但是如果可以覆盖,则有问题。

更复杂的方法

在后一种情况下,不确定是否存在问题,您需要按照下面概述的方法应用烦人的解决方案。

哪个版本的数据(通过分区)具有一些值。

并具有一个带有current_version的控制表,并选择此值并将其用于所有相关查询中,直到可以使用新的current_version。

然后进行维护。