我一直在研究一种在其他使用者/应用程序访问数据时刷新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)
}
答案 0 :(得分:1)
更简单的方法
每个源或目标使用2个HDFS位置分别循环加载表defs t1_x和t2_x,并使用view_x同样在t1_x和t2_x之间切换。
查询应始终使用view_x。
您可以在下一个周期之前及时清理不再使用的HDFS位置。
提示是将新数据和旧数据保留一段时间。
评论 唯一的缺点是,如果一组查询需要针对旧版本的数据运行。如果更改后的数据具有“添加到”的性质,则没有问题,但是如果可以覆盖,则有问题。
更复杂的方法
在后一种情况下,不确定是否存在问题,您需要按照下面概述的方法应用烦人的解决方案。
哪个版本的数据(通过分区)具有一些值。
并具有一个带有current_version的控制表,并选择此值并将其用于所有相关查询中,直到可以使用新的current_version。
然后进行维护。