我刚才问了一个类似的问题,并且认为我解决了这个问题,但事实证明它只是因为我正在处理一个较小的数据集而消失了。
很多人问过这个……
我最终联系了cloudera论坛,他们在几分钟内回答了我的问题: http://community.cloudera.com/t5/Storage-Random-Access-HDFS/Why-can-t-I-partition-a-1-gigabyte-dataset-into-300/m-p/86554#M3981 我尝试了Harsh J的建议,它完美无缺!
这是他说的话:
如果您正在处理来自数据源的无序分区,那么您 最终可以在分区时并行创建大量文件 尝试。 在HDFS中,当一个文件(或更具体地说,它的块)打开时, DataNode执行其目标块大小的逻辑预留。所以 如果您配置的块大小为128 MiB,则每个并发打开 block将从可用的剩余部分中扣除该值(逻辑上) DataNode发布到NameNode的空间。 这项预订是为了帮助管理空间和保证完整 阻止写入客户端,以便客户端开始编写它 文件永远不会在中途遇到空间异常。 注意:文件关闭时,只保留实际长度, 并调整预订计算以反映现实 使用和可用空间。但是,当文件块保持打开状态时, 它总是被认为是一个完整的块大小。 如果可以,NameNode还将仅为写入选择DataNode 保证完整的目标块大小。它会忽略它的任何DataNodes 认为(基于其报告的价值观和指标)不适合 请求写入的参数。您的错误显示NameNode具有 在尝试分配时,停止考虑您唯一的实时DataNode 新的阻止请求。 例如,70 GiB的可用空间将证明是不够的 将有超过560个并发,打开的文件(70 GiB划分 分为128 MiB块大小)。因此,DataNode将“显示为” 点~560打开文件,不再作为有效目标 进一步的文件请求。 根据您对插入的描述,可能会出现这种情况 数据集的300个块中的每个块仍然可以携带不同的ID, 导致每个并行任务请求大量打开文件 插入几个不同的分区。 你可以通过减少请求块来“破解”你的方式 查询中的大小(例如,将dfs.blocksize设置为8 MiB), 影响预订计算。但是,这可能不是一个 在扩展时,对于较大的数据集是个好主意,因为它会驱动数据集 file:块计数并增加NameNode的内存开销。 解决这个问题的更好方法是执行预分区 insert(首先按分区排序,然后插入分区 方式)。例如,Hive提供了这个选项: hive.optimize.sort.dynamic.partition ,如果你使用普通的Spark 或MapReduce然后他们的默认分区策略确实 这个。
如果您正在处理来自数据源的无序分区,那么您 最终可以在分区时并行创建大量文件 尝试。
在HDFS中,当一个文件(或更具体地说,它的块)打开时, DataNode执行其目标块大小的逻辑预留。所以 如果您配置的块大小为128 MiB,则每个并发打开 block将从可用的剩余部分中扣除该值(逻辑上) DataNode发布到NameNode的空间。
这项预订是为了帮助管理空间和保证完整 阻止写入客户端,以便客户端开始编写它 文件永远不会在中途遇到空间异常。
注意:文件关闭时,只保留实际长度, 并调整预订计算以反映现实 使用和可用空间。但是,当文件块保持打开状态时, 它总是被认为是一个完整的块大小。
如果可以,NameNode还将仅为写入选择DataNode 保证完整的目标块大小。它会忽略它的任何DataNodes 认为(基于其报告的价值观和指标)不适合 请求写入的参数。您的错误显示NameNode具有 在尝试分配时,停止考虑您唯一的实时DataNode 新的阻止请求。
例如,70 GiB的可用空间将证明是不够的 将有超过560个并发,打开的文件(70 GiB划分 分为128 MiB块大小)。因此,DataNode将“显示为” 点~560打开文件,不再作为有效目标 进一步的文件请求。
根据您对插入的描述,可能会出现这种情况 数据集的300个块中的每个块仍然可以携带不同的ID, 导致每个并行任务请求大量打开文件 插入几个不同的分区。
你可以通过减少请求块来“破解”你的方式 查询中的大小(例如,将dfs.blocksize设置为8 MiB), 影响预订计算。但是,这可能不是一个 在扩展时,对于较大的数据集是个好主意,因为它会驱动数据集 file:块计数并增加NameNode的内存开销。
解决这个问题的更好方法是执行预分区 insert(首先按分区排序,然后插入分区 方式)。例如,Hive提供了这个选项: hive.optimize.sort.dynamic.partition ,如果你使用普通的Spark 或MapReduce然后他们的默认分区策略确实 这个。
所以,在那天结束时我做了 set hive.optimize.sort.dynamic.partition=true; 一切都开始奏效了。但我也做了另一件事。
set hive.optimize.sort.dynamic.partition=true;
这是我之前在调查此问题时的一篇帖子: 为什么在写入分区表时会将“文件只能复制到0个节点”? 我遇到了一个问题,hive无法对我的数据集进行分区,因为 hive.exec.max.dynamic.partitions 被设定为 100 所以,我搜索了这个问题,在hortonworks论坛的某个地方,我看到了一个答案,说我应该这样做:
hive.exec.max.dynamic.partitions
100
SET hive.exec.max.dynamic.partitions=100000; SET hive.exec.max.dynamic.partitions.pernode=100000;
这是另一个问题,也许hive尝试打开你设置的那些并发连接 hive.exec.max.dynamic.partitions , 所以我的 insert 查询没有开始工作,直到我将这些值减少到 500 。
insert
500