如何使用 FileSystem API 计算分区?
Posted
技术标签:
【中文标题】如何使用 FileSystem API 计算分区?【英文标题】:How to count partitions with FileSystem API? 【发布时间】:2019-10-22 22:25:12 【问题描述】:我正在使用 Hadoop 2.7 版及其文件系统 API。问题是关于“如何使用 API 计算分区?” 但是,把它放到软件问题中,我在这里处理一个 Spark-Shell 脚本......关于脚本的具体问题是
下面的变量parts
是在统计表分区的数量,还是别的什么?
import org.apache.hadoop.fs.FileSystem, Path
import scala.collection.mutable.ArrayBuffer
import spark.implicits._
val warehouse = "/apps/hive/warehouse" // the Hive default location for all databases
val db_regex = """\.db$""".r // filter for names like "*.db"
val tab_regex = """\.hive\-staging_""".r // signature of Hive files
val trStrange = "[\\s/]+|[^\\x00-\\x7F]+|[\\pCntrl&&[^\r\n\t]]+|\\pC+".r //mark
def cutPath (thePath: String, toCut: Boolean = true) : String =
if (toCut) trStrange.replaceAllIn( thePath.replaceAll("^.+/", ""), "@") else thePath
val fs_get = FileSystem.get( sc.hadoopConfiguration )
fs_get.listStatus( new Path(warehouse) ).foreach( lsb =>
val b = lsb.getPath.toString
if (db_regex.findFirstIn(b).isDefined)
fs_get.listStatus( new Path(b) ).foreach( lst =>
val lstPath = lst.getPath
val t = lstPath.toString
var parts = -1
var size = -1L
if (!tab_regex.findFirstIn(t).isDefined)
try
val pp = fs_get.listStatus( lstPath )
parts = pp.length // !HERE! partitions?
pp.foreach( p =>
try // SUPPOSING that size is the number of bytes of table t
size = size + fs.getContentSummary(p.getPath).getLength
catch case _: Throwable =>
)
catch case _: Throwable =>
println(s"$cutPath(b),$cutPath(t),$parts,$size")
)
) // x warehouse loop
System.exit(0) // get out from spark-shell
这只是一个展示重点的例子:Hive 默认数据库 FileSystem 结构的正确扫描和语义解释,使用 Hive FileSystem API。该脚本有时需要一些内存,但工作正常。使用 sshell --driver-memory 12G --executor-memory 18G -i teste_v2.scala > output.csv
注意:这里的目的不是通过任何其他方法(例如 HQL DESCRIBE
或 Spark Schema)对分区进行计数,而是使用 API 来实现...用于控制和数据质量 检查,API 作为一种“低级测量”很重要。
【问题讨论】:
【参考方案1】:Hive 将其元数据构建为 数据库 > 表 > 分区 > 文件。这通常转化为文件系统目录结构<hive.warehouse.dir>/database.db/table/partition/.../files
。其中/partition/.../
表示表可以由多个列分区,从而创建嵌套级别的子目录。 (partition 是一个 directory,按照惯例名称为 .../partition_column=value
)。
因此,如果我没记错的话,您的脚本似乎将打印每个数据库中每个单列分区表的文件数 (parts
) 及其总长度 (size
)。
作为替代方案,我建议您查看hdfs dfs -count
命令,看看它是否适合您的需求,并可能将其包装在一个简单的 shell 脚本中以循环访问数据库和表。
【讨论】:
以上是关于如何使用 FileSystem API 计算分区?的主要内容,如果未能解决你的问题,请参考以下文章
电脑开机出现error:unknown filesystem的解决方法
linux7 扩展根分区报错,xfs_growfs 提示is not a mounted XFS filesystem
大数据问题排查系列 - HDFS FileSystem API 的正确打开方式,你 GET 了吗?
/dev/sda2 is mounted; will not make a filesystem here!