异常说明
- 测试环境:
1.Redhat7.4
2.采用root用户操作
3.CM和CDH为6.3.0
4.集群启用了Sentry未开启Kerberos
5.HDFS服务开启了ACL
1.随便为一个HDFS目录设置ACL条目,当超过32个时会报一下错误。
代码语言:javascript复制[root@ip-172-31-13-38 ~]# sh a.sh
setfacl: Invalid ACL: ACL has 33 access entries, which exceeds maximum of 32.
setfacl: Invalid ACL: ACL has 33 access entries, which exceeds maximum of 32.
setfacl: Invalid ACL: ACL has 33 access entries, which exceeds maximum of 32.
setfacl: Invalid ACL: ACL has 33 access entries, which exceeds maximum of 32.
setfacl: Invalid ACL: ACL has 33 access entries, which exceeds maximum of 32.
[root@ip-172-31-13-38 ~]# hadoop fs -getfacl /acl_test
# file: /acl_test
# owner: root
# group: supergroup
user::rwx
user:fayson:r--
user:fayson1:r--
user:fayson10:r--
user:fayson11:r--
user:fayson12:r--
user:fayson13:r--
user:fayson14:r--
user:fayson15:r--
user:fayson16:r--
user:fayson17:r--
user:fayson18:r--
user:fayson19:r--
user:fayson2:r--
user:fayson20:r--
user:fayson21:r--
user:fayson22:r--
user:fayson23:r--
user:fayson24:r--
user:fayson25:r--
user:fayson26:r--
user:fayson27:r--
user:fayson3:r--
user:fayson4:r--
user:fayson5:r--
user:fayson6:r--
user:fayson7:r--
user:fayson8:r--
user:fayson9:r--
group::r-x
mask::r-x
other::r-x
解决办法
2.1 方法1
1.在设置ACL的时候带上default前缀。
代码语言:javascript复制[root@ip-172-31-13-38 ~]# hadoop fs -setfacl -m default:user:fayson2:r-- /acl_test
可以看到命令没有报错,而且执行正常。
2.创建一个子目录,发现子目录会继承父目录的default的ACL
代码语言:javascript复制[root@ip-172-31-13-38 ~]# hadoop fs -mkdir /acl_test/acl_test1
[root@ip-172-31-13-38 ~]# hadoop fs -getfacl /acl_test/acl_test1
3.此时再对父目录增加一个default的ACL,看看子目录的ACL情况。
代码语言:javascript复制[root@ip-172-31-13-38 ~]# hadoop fs -setfacl -m default:user:fayson28:rwx /acl_test
[root@ip-172-31-13-38 ~]# hadoop fs -getfacl /acl_test
[root@ip-172-31-13-38 ~]# hadoop fs -getfacl /acl_test/acl_test1
可以看到子目录没有继承父目录新的default的ACL条目,说明只是在第一次创建的时候会继承。
2.2 方法2
1.使用Sentry为一张表赋予超过32个group的权限。
代码语言:javascript复制0: jdbc:hive2://localhost:10000> create role acl_test;
0: jdbc:hive2://localhost:10000> grant all on default.test to role acl_test;
0: jdbc:hive2://localhost:10000> grant role acl_test to group fayson01;
0: jdbc:hive2://localhost:10000> grant role acl_test to group fayson02;
...
0: jdbc:hive2://localhost:10000> grant role acl_test to group fayson32;
0: jdbc:hive2://localhost:10000> grant role acl_test to group fayson33;
2.检查HDFS对应目录的ACL条目。
发现并没有报错,在超过32个ACL条目的情况下,所有Sentry中对group赋权都同步到了底层的HDFS。
总结
1.HDFS ACL条目32个限制的讨论你可以参考Apache Hadoop的jira:HDFS-7447:
代码语言:javascript复制https://issues.apache.org/jira/browse/HDFS-7447
该jira里主要讨论了为什么会有这个限制:这样做主要有2个原因:简化管理和限制资源消耗。一个HDFS的目录如果有大量ACL条目往往看上去不是太好理解,这种需求往往可以通过更好的划分用户和用户组的关系来更好的去实现。同时具有大量ACL条目后会消耗集群更多的存储和内存,对于NameNode来说也需要消耗更多的时间来做权限检查,从而影响整个集群的性能。为什么HDFS的ACL条目是32是与Linux的ext文件系统的最大ACL条目一致的。关于HDFS的这个设计你可以参考:
代码语言:javascript复制https://issues.apache.org/jira/secure/attachment/12627729/HDFS-ACLs-Design-3.pdf
2.对于这个问题,HDFS社区有一个jira进行一个简单的提升,即一个目录的default和特定的(specific) ACL是两种不同的类型,每个都可以最大设置32,所以整个ACL条目可以超过32到达64,具体可以参考:
代码语言:javascript复制https://issues.apache.org/jira/browse/HDFS-7582
这个jira在CDH5.12.2, CDH5.13.1和CDH5.14.0及更高版本已经修复。注:default ACL一般是子目录继承的父目录的ACL,主要是在创建子目录的时候会直接继承父目录的default的ACL。
3.在CDH之上,对于Hive/Impala表,在使用Sentry后,并同时开启HDFS ACL与HDFS ACL同步后,对于Hive表的目录是可以超过32个条目限制的。
在实际使用中我们给出如下建议:
1.如果是Hive表,使用Sentry后超过32个ACL条目没问题,你可以进行相关设置。
2.如果是HDFS目录,你最好调整用户和组的关系,或者整理好用户和组的对应关系,在设置ACL条目的时候尽量以group来设置,然后控制到32个以内。
3.对于HDFS目录,对于替代方案,你如果非要超过32个ACL,你可以在这些目录上建立Hive表(虽然这个表你可能不使用),然后通过Sentry来赋权后来实现超过32个的目的。
我们建议你使用1 2的组合方式,其实更多的是整理好user和group的对应关系,来更好的管理HDFS ACL,毕竟ACL多了确实管理困难以及影响集群性能。