当前位置: 首页 > 知识库问答 >
问题:

为什么Spark可以用bucketBy创建数千个文件?

翟冷勋
2023-03-14

语境

Spark2.0.1,spark-submit在集群模式下。我正在从HDFS中读取一个拼花地板文件:

val spark = SparkSession.builder
      .appName("myApp")
      .config("hive.metastore.uris", "thrift://XXX.XXX.net:9083")
      .config("spark.sql.sources.bucketing.enabled", true)
      .enableHiveSupport()
      .getOrCreate()

val df = spark.read
              .format("parquet")
              .load("hdfs://XXX.XX.X.XX/myParquetFile")

我正在将DF保存到一个配置单元表中,该表包含按userid分组的50个桶:

df0.write
   .bucketBy(50, "userid")
   .saveAsTable("myHiveTable")

现在,当我查看hdfs的hive仓库/user/hive/warehouse时,有一个名为myhivetable的文件夹。它的内部是一堆part-*.parquet文件。我希望有50个文件。但是没有,有3201个文件!!!!每个分区有64个文件,为什么?对于我保存为配置单元表的不同文件,每个分区有不同数量的文件。所有的文件都很小,每个只有几十Kb!

让我补充一下,在MyParquetFile中,不同的Userid的数量大约为1,000

为什么文件夹里有3201个文件而不是50个!它们是什么?

当我将此表读回DataFrame并打印分区数时:

val df2 = spark.sql("SELECT * FROM myHiveTable") 
println(df2.rdd.getNumPartitions)

分区的数量是正确的50,并且我确认数据是通过userid正确分区的。

问题

创建的文件数量取决于什么?

问题

有办法限制创建的文件数量吗?

问题

我应该担心这些文件吗?拥有所有这些文件是否会影响DF2的性能?人们总是说我们不应该创建太多的分区,因为这是有问题的。

问题

我发现这个信息配置单元动态分区提示,文件的数量可能与映射器的数量有关。建议在插入配置单元表时使用distribution by。我怎么能在Spark里做到呢?

问题

如果问题确实如上面的链接所示,在MapR-FS上插入数据后如何控制配置单元表的文件号,建议使用hive.merge.mapfileshive.merge.mapredfiles等选项合并map reduce作业后的所有小文件。在Spark中有这样的选择吗?

共有1个答案

鲁靖
2023-03-14

请使用spark sql,它将使用HiveContext将数据写入配置单元表,因此它将使用您在表模式中配置的桶数。

 SparkSession.builder().
  config("hive.exec.dynamic.partition", "true").
  config("hive.exec.dynamic.partition.mode", "nonstrict").
  config("hive.execution.engine","tez").
  config("hive.exec.max.dynamic.partitions","400").
  config("hive.exec.max.dynamic.partitions.pernode","400").
  config("hive.enforce.bucketing","true").
  config("optimize.sort.dynamic.partitionining","true").
  config("hive.vectorized.execution.enabled","true").
  config("hive.enforce.sorting","true").
  enableHiveSupport().getOrCreate()

spark.sql(s"insert into hiveTableName partition (partition_column) select * from  myParquetFile")

spark的bucketing实现没有满足指定的bucket大小数。每个分区都写入一个单独的文件,因此每个bucket都有很多文件。

拉维

 类似资料:
  • 我使用Netty 4创建了一个相当直接的服务器。我已经能够将它扩展到处理数千个连接,而且它从未超过40个线程。 为了测试它,我还创建了一个创建数千个连接的测试客户端。不幸的是,这会创建和连接一样多的线程。我希望尽量减少客户端的线程。我已经看了很多帖子。许多示例显示了单个连接设置。这个和这个说在客户端之间共享NioEventLoopGroup,我这样做了。我得到的nioEventLoopGroup数

  • 问题内容: 我们正在构建一个eLearningMultipleChoice工具,成千上万的用户将完成我们的测试。我们已经有成千上万的其他研讨会的订阅者,因此很可能成千上万的人也将完成MC测试。 现在,我们需要跟踪每个用户回答的每个问题,花了他多长时间,是否正确(经过多次尝试之后),如果不是,他给出了哪个错误答案等等。确实有很多数据。 现在,我们将有成千上万的问题和成千上万的用户。由于每个问题至少要

  • 我已经创建了一个android项目,我想在市场上上传我的项目,但在此之前,我需要为我的项目创建一个文档,对吗? 谁能告诉我有什么工具可以为android项目创建一个文档吗? 这里我使用的是Ubunto12。 据我所知,到目前为止,我在谷歌找不到任何工具。 谢谢你宝贵的时间!..

  • 我试图使一个属性文件在Java。可悲的是,当我启动Minecraft(因为这是Forge中的一个mod)时,文件不会创建。我会非常感谢任何帮助我的人。下面是代码:

  • 本文向大家介绍目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?相关面试题,主要包含被问及目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?时的应答技巧和注意事项,需要的朋友参考一下 答案: 创建目录: mkdir 创建文件:典型的如 touch,vi 也可以创建文件,其实只要向一个不存在的文件输出,都会创建文件 复制文件: cp 7. 文件权限修改用什么命令?格式是怎么样的?

  • 在以下Java代码中 我在控制台中得到以下输出 在使用next()或nextFoo()后,从扫描仪查看答案时跳过nextLine()?,我们必须添加Cmd8的原因是,nextInt()一直读取输入,直到将输入发送到程序,并将输入放回输入流的前面。现在,当“Cmd8”中的nextLine()开始读取它时,它会在输入流的开始处发现前面没有任何字符串,它假定用户没有输入任何内容,因此将空字符串作为输入并