I asked a similar question a while ago,以为我解决了这个问题,但事实证明,它之所以消失是因为我正在处理一个较小的数据集。
很多人问了这个问题,我浏览了我能找到但仍然没有取得任何进展的每一篇互联网帖子。
我要这样做的是:
我在蜂巢中有一个外部表browserdata
,它引用大约1 GB的数据。
我尝试将数据粘贴到分区表partbrowserdata
中,该表的定义如下:
CREATE EXTERNAL TABLE IF NOT EXISTS partbrowserdata (
BidID string,
Timestamp_ string,
iPinYouID string,
UserAgent string,
IP string,
RegionID int,
AdExchange int,
Domain string,
URL string,
AnonymousURL string,
AdSlotID string,
AdSlotWidth int,
AdSlotHeight int,
AdSlotVisibility string,
AdSlotFormat string,
AdSlotFloorPrice decimal,
CreativeID string,
BiddingPrice decimal,
AdvertiserID string,
UserProfileIDs array<string>
)
PARTITIONED BY (CityID int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE
LOCATION '/user/maria_dev/data2';
使用此查询:
insert into table partbrowserdata partition(cityid)
select BidID,Timestamp_ ,iPinYouID ,UserAgent ,IP ,RegionID ,AdExchange ,Domain ,URL ,AnonymousURL ,AdSlotID ,AdSlotWidth ,AdSlotHeight ,AdSlotVisibility ,AdSlotFormat ,AdSlotFloorPrice ,CreativeID ,BiddingPrice ,AdvertiserID ,UserProfileIDs ,CityID
from browserdata;
每次在hortonworks或cloudera的每个平台上,我都会收到此消息:
Caused by:
org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /user/maria_dev/data2/.hive-staging_hive_2019-02-06_18-58-39_333_7627883726303986643-1/_task_tmp.-ext-10000/cityid=219/_tmp.000000_3 could only be replicated to 0 nodes instead of minReplication (=1). There are 4 datanode(s) running and no node(s) are excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:1720)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:3389)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:683)
at org.apache.hadoop.hdfs.server.namenode.AuthorizationProviderProxyClientProtocol.addBlock(AuthorizationProviderProxyClientProtocol.java:214)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:495)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol$2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:617)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1073)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2217)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2213)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:422)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1917)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2211)
at org.apache.hadoop.ipc.Client.call(Client.java:1504)
at org.apache.hadoop.ipc.Client.call(Client.java:1441)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:230)
at com.sun.proxy.$Proxy14.addBlock(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.addBlock(ClientNamenodeProtocolTranslatorPB.java:413)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:258)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:104)
at com.sun.proxy.$Proxy15.addBlock(Unknown Source)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.locateFollowingBlock(DFSOutputStream.java:1814)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.nextBlockOutputStream(DFSOutputStream.java:1610)
at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:773)
我该怎么办?我不明白为什么会这样。但是,这似乎确实是一个内存问题,因为我可以插入几行,但是由于某种原因,并非所有行都可以插入。请注意,我在HDFS上有足够的内存,因此1千兆字节的额外数据等于1美元,因此,这可能是RAM问题吗?
这是我的dfs报告输出:
我已经在所有执行引擎上进行过尝试:spark
,tez
,mr
。
请不要建议需要我格式化namenode的解决方案,因为它们不起作用,而且无论如何都不是解决方案。
更新:
查看名称节点的日志后,我注意到了,如果有帮助的话
Failed to place enough replicas, still in need of 1 to reach 1 (unavailableStorages=[DISK ], storagePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}, newBlock=true) All required storage types are unavailable: unavailableStorages=[DISK], stor agePolicy=BlockStoragePolicy{HOT:7, storageTypes=[DISK], creationFallbacks=[], replicationFallbacks=[ARCHIVE]}
这些日志建议这样做:
有关更多信息,请启用DEBUG日志级别 org.apache.hadoop.hdfs.ser ver.blockmanagement.BlockPlacementPolicy 和org.apache.hadoop.net.NetworkTopology
我该怎么做?
我还注意到以下类似的未解决帖子:
HDP 2.2@Linux/CentOS@OracleVM (Hortonworks) fails on remote submission from Eclipse@Windows
更新2:
我刚刚尝试用spark对它进行分区,并且它起作用了!因此,这肯定是一个蜂巢错误...
更新3:
仅在MapR上进行了测试,即可正常工作,但MapR不使用HDFS。这绝对是某种HDFS + Hive组合错误。
证明:
答案 0 :(得分:2)
我最终接触了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,则每个并发打开 区块将从可用的剩余金额(逻辑上)减去该值 DataNode发布到NameNode的空间。
完成此预订是为了帮助管理空间并保证完整的 阻止写入客户端,以便开始写入客户端的客户端 文件不会在中途遇到空间不足异常。
注意:关闭文件时,仅保留实际长度, 并调整了预订计算以反映实际情况 已用和可用空间。但是,尽管文件块保持打开状态, 它始终被认为拥有完整的块大小。
NameNode还将仅选择一个DataNode进行写入 确保完整的目标块大小。它将忽略它的任何DataNodes 认为(基于其报告的值和指标)不适合 请求的写参数。您的错误表明NameNode具有 尝试分配一个时,不再考虑您唯一的活动DataNode 新的阻止请求。
例如,如果满足以下条件,将证明70 GiB的可用空间不足 将会有超过560个并发打开的文件(划分为70 GiB 分成128个MiB块大小)。因此,DataNode将在“ 约560个打开文件的位置,将不再用作有效目标 进一步的文件请求。
根据您对插入内容的描述,很可能出现这种情况,因为 数据集的300个数据块中的每个数据块仍可能带有不同的ID, 导致每个并行任务请求大量打开文件, 插入几个不同的分区。
您可以通过减少请求阻止来“破解”您的方法 查询中的大小(例如,将dfs.blocksize设置为8 MiB), 影响预定计算。但是,这可能不是 随着规模的扩大,最好使用较大的数据集,因为这将推动 file:阻止计数并增加NameNode的内存成本。
解决此问题的更好方法是执行预分区 插入(首先按分区排序,然后插入分区中 方式)。例如,Hive提供了此选项: hive.optimize.sort.dynamic.partition,如果您使用普通Spark 或MapReduce,那么他们的默认分区策略完全可以 这个。
因此,最终,我做了set hive.optimize.sort.dynamic.partition=true;
,一切都开始了。但是我还做了另一件事。
这是我早些时候在调查此问题时发表的文章之一:Why do I get "File could only be replicated to 0 nodes" when writing to a partitioned table?我遇到了一个问题,因为蜂巢无法分区我的数据集,因为hive.exec.max.dynamic.partitions
设置为{{1} },因此,我在这个问题上进行了搜索,并在hortonworks论坛的某个地方看到了答案,说我应该这样做:
100
这是另一个问题,也许蜂巢会尝试打开您设置的SET hive.exec.max.dynamic.partitions=100000;
SET hive.exec.max.dynamic.partitions.pernode=100000;
并发连接,因此我的hive.exec.max.dynamic.partitions
查询直到将这些值减小到{{1 }}。