使用zookeeper管理多个hbase集群

 zookeeper是hbase集群的"协调器"。由于zookeeper的轻量级特性,因此我们可以将多个hbase集群共用一个zookeeper集群,以节约大量的服务器。多个hbase集群共用zookeeper集群的方法是使用同一组ip,修改不同hbase集群的"zookeeper.znode.parent"属性,让它们使用不同的根目录。比如cluster1使用/hbase-c1,cluster2使用/hbase-c2,等等。 
  
    使用以上方法有一个现实的问题:如何避免各集群的相互干扰?因为client的配置权是在用户手上,并不能保证用户永远是配置正确的,那么会产生某个用户访问了不该他访问的hbase集群。此时数据安全性成了很大的问题,甚至可能出现误删除数据。我们需要在zookeeper层屏弊掉该问题。 
  
    zookeeper3.x版本起自带了简单的ACL功能(注意3.3.x版本起不再支持按hostname来分配权限)。见: http://zookeeper.apache.org/doc/r3.3.2/zookeeperProgrammers.html#sc_ZooKeeperAccessControl 。进行权限配置主要使用digest和ip两种方法。其中digest是用户密码方式,对用户来说使用上并不透明。ip配置最简单,对用户也是透明的,用户并不知道的情况下就能限制它的访问权限。 
  
    zookeeper将访问权限分为了五类:READ/WRITE/DELETE/CREATE/ADMIN,其中admin为最高权限。zookeeper的权限是到znode级别的,限制了某一个node的权限并不能限制它的子节点权限。 

    不过使用IP做权限配置方案有一个缺陷:必须指定具体的ip,而不能使用通配符或者范围一类的。这样对于大规模的权限设置是非常不方便的一件事,因此作者略调整了一下zookeeper的代码: 
  IPAuthenticationProvider.java 
 
Java代码   收藏代码
  1. /** 
  2.  * Licensed to the Apache Software Foundation (ASF) under one 
  3.  * or more contributor license agreements.  See the NOTICE file 
  4.  * distributed with this work for additional information 
  5.  * regarding copyright ownership.  The ASF licenses this file 
  6.  * to you under the Apache License, Version 2.0 (the 
  7.  * "License"); you may not use this file except in compliance 
  8.  * with the License.  You may obtain a copy of the License at 
  9.  * 
  10.  *     http://www.apache.org/licenses/LICENSE-2.0 
  11.  * 
  12.  * Unless required by applicable law or agreed to in writing, software 
  13.  * distributed under the License is distributed on an "AS IS" BASIS, 
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  15.  * See the License for the specific language governing permissions and 
  16.  * limitations under the License. 
  17.  */  
  18.   
  19. package org.apache.zookeeper.server.auth;  
  20.   
  21. import org.apache.zookeeper.data.Id;  
  22. import org.apache.zookeeper.server.ServerCnxn;  
  23. import org.apache.zookeeper.KeeperException;  
  24.   
  25. public class IPAuthenticationProvider implements AuthenticationProvider {  
  26.   
  27.     public String getScheme() {  
  28.         return "ip";  
  29.     }  
  30.   
  31.     public KeeperException.Code  
  32.         handleAuthentication(ServerCnxn cnxn, byte[] authData)  
  33.     {  
  34.         String id = cnxn.getRemoteAddress().getAddress().getHostAddress();  
  35.         cnxn.getAuthInfo().add(new Id(getScheme(), id));  
  36.         return KeeperException.Code.OK;  
  37.     }  
  38.   
  39.     // This is a bit weird but we need to return the address and the number of  
  40.     // bytes (to distinguish between IPv4 and IPv6  
  41.     private byte[] addr2Bytes(String addr) {  
  42.         byte b[] = v4addr2Bytes1(addr);  
  43.         // TODO Write the v6addr2Bytes  
  44.         return b;  
  45.     }  
  46.   
  47.     private byte v4addr2Bytes(String part) throws NumberFormatException{  
  48.         try {  
  49.            int v = Integer.parseInt(part);  
  50.            if (v >= 0 && v <= 255) {  
  51.                   byte  b = (byte) v;  
  52.                   return b;  
  53.                 } else {  
  54.                     throw new NumberFormatException("v < 0 or v > 255!");  
  55.                 }  
  56.             } catch (NumberFormatException e) {  
  57.                 throw e;  
  58.             }  
  59.     }  
  60.       
  61.     private byte[] v4addr2Bytes1(String addr) {  
  62.       String parts[] = addr.split("\\.", -1);  
  63.       if (parts.length != 4) {  
  64.           return null;  
  65.       }  
  66.       byte b[] = new byte[4];  
  67.       for (int i = 0; i < 4; i++) {  
  68.         try {  
  69.             if(parts[i].split("/").length == 2){  
  70.                 v4addr2Bytes(parts[i].split("/")[0]);  
  71.                 v4addr2Bytes(parts[i].split("/")[1]);  
  72.                 continue;  
  73.             }else{  
  74.             b[i] = v4addr2Bytes(parts[i]);  
  75.             }  
  76.         } catch (NumberFormatException e) {  
  77.           return null;  
  78.             }  
  79.       }  
  80.       return b;  
  81.   }  
  82.       
  83.     public boolean matches(String id, String aclExpr) {  
  84.       String parts[] = aclExpr.split("/"2);  
  85.       byte aclAddr[] = addr2Bytes(parts[0]);  
  86.       if (aclAddr == null) {  
  87.           return false;  
  88.       }  
  89.       byte endAclAddr[] = new byte[aclAddr.length];  
  90.       for(int i = 0; i < aclAddr.length; i ++){  
  91.         endAclAddr[i] = aclAddr[i];  
  92.       }  
  93.       if (parts.length == 2) {  
  94.           try {  
  95.                 int end = Integer.parseInt(parts[1]);  
  96.                 int e = endAclAddr[endAclAddr.length-1]<=0?endAclAddr[endAclAddr.length-1]+256:endAclAddr[endAclAddr.length-1];  
  97.                 if(end <  e|| end < 0 || end > 255)  
  98.                     return false;  
  99.               endAclAddr[endAclAddr.length-1] = (byte)end;  
  100.           } catch (NumberFormatException e) {  
  101.               return false;  
  102.           }  
  103.       }  
  104.       byte remoteAddr[] = addr2Bytes(id);  
  105.       if (remoteAddr == null) {  
  106.           return false;  
  107.       }  
  108.       for (int i = 0; i < remoteAddr.length; i++) {  
  109.         int r = remoteAddr[i]<=0?(int)remoteAddr[i]+256:remoteAddr[i];  
  110.         int a = aclAddr[i]<=0?(int)aclAddr[i]+256:aclAddr[i];  
  111.         int e = endAclAddr[i]<=0?(int)endAclAddr[i]+256:endAclAddr[i];  
  112.         if (r < a || r > e) {  
  113.           return false;  
  114.         }  
  115.       }  
  116.       return true;  
  117.   }  
  118.   
  119.     public boolean isAuthenticated() {  
  120.         return false;  
  121.     }  
  122.   
  123.     public boolean isValid(String id) {  
  124.         return addr2Bytes(id) != null;  
  125.     }  
  126. }  

    支持了使用/做为范围标识,比如进入hbase zkcli,执行:setAcl /test ip:192.168.0.3/10:cd,则将读写权限赋给了192.168.0.3-192.168.0.10这8台机器,其它机器将没有任何权限。 
    这样用同一个zookeeper管理多个集群、海量机器将不再有困扰。 
    最后写了一个帮助运维同学自动化管理zookeeper集群下多个hbase集群的ACL权限的工具,像以下这样: 
Html代码   收藏代码
  1. java -Djava.ext.dirs=libs/ -cp hbase-tools.jar dwbasis.hbase.tools.client.ZookeeperAcl aclFile.json  
  2. Usage: ZookeeperAcl acljsonfile [-plan]  
  3. /test/t ==> 'ip,'192.168.0.1  
  4. :cdrwa  
  5. /test ==> 'ip,'192.168.0.1/3  
  6. :cdrwa  
  7. /test ==> 'ip,'192.168.0.5  
  8. :cdrwa  
  9. do you really setAcl as above?(y/n)  


    补充:多集群共用zk后,每个集群的启动和停止不应该影响zk的稳定。因此请配置hbase-env.sh中export HBASE_MANAGES_ZK=false
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值