云服务器内容精选

  • ZooKeeper常见参数 参数入口: 请参考修改集群服务配置参数,进入ZooKeeper“全部配置”页面。在搜索框中输入参数名称。 表1 参数说明 配置参数 说明 默认值 skipACL 是否跳过ZooKeeper节点的权限检查。 no maxClientCnxns ZooKeeper的最大连接数,在连接数多的情况下,建议增加。 2000 LOG_LEVEL 日志级别,在调试的时候,可以改为DEBUG。 INFO acl.compare.shortName 当Znode的ACL权限认证类型为SASL时,是否仅使用principal的用户名部分进行ACL权限认证。 true synclimit Follower与leader进行同步的时间间隔(单位为tick)。如果在指定的时间内leader没响应,连接将不能被建立。 15 tickTime 一次tick的时间(毫秒),它是ZooKeeper使用的基本时间单位,心跳、超时的时间都由它来规定。 4000 ZooKeeper内部时间由参数ticktime和参数synclimit控制,如需调大ZooKeeper内部超时时间,需要调大客户端连接ZooKeeper的超时时间。 父主题: 使用ZooKeeper
  • 操作场景 该操作指导用户对ZooKeeper的znode设置权限。 ZooKeeper通过访问控制列表(ACL)来对znode进行访问控制。ZooKeeper客户端为znode指定ACL,ZooKeeper服务器根据ACL列表判定某个请求znode的客户端是否有对应操作的权限。ACL设置涉及如下四个方面。 查看ZooKeeper中znode的ACL。 增加ZooKeeper中znode的ACL。 修改ZooKeeper中znode的ACL。 删除ZooKeeper中znode的ACL。 ZooKeeper的ACL权限说明: ZooKeeper目前支持create,delete,read,write,admin五种权限,且ZooKeeper对权限的控制是znode级别的,而且不继承,即对父znode设置权限,其子znode不继承父znode的权限。ZooKeeper中znode的默认权限为world:anyone:cdrwa,即任何用户都有所有权限。 ACL有三部分: 第一部分是认证类型,如world指所有认证类型,sasl是kerberos认证类型; 第二部分是账号,如anyone指的是任何人; 第三部分是权限,如cdrwa指的是拥有所有权限。 特别的,由于普通模式启动客户端不需要认证,sasl认证类型的ACL在普通模式下将不能使用。本文所有涉及sasl方式的鉴权操作均是在安全集群中进行。 表1 Zookeeper的五种ACL 权限说明 权限简称 权限详情 创建权限 create(c) 可以在当前znode下创建子znode 删除权限 delete(d) 删除当前的znode 读权限 read(r) 获取当前znode的数据,可以列出当前znode所有的子znodes 写权限 write(w) 向当前znode写数据,写入子znode 管理权限 admin(a) 设置当前znode的权限
  • 操作场景 该操作指导用户对ZooKeeper的znode设置权限。 ZooKeeper通过访问控制列表(ACL)来对znode进行访问控制。ZooKeeper客户端为znode指定ACL,ZooKeeper服务器根据ACL列表判定某个请求znode的客户端是否有对应操作的权限。ACL设置涉及如下四个方面。 查看ZooKeeper中znode的ACL。 增加ZooKeeper中znode的ACL。 修改ZooKeeper中znode的ACL。 删除ZooKeeper中znode的ACL。 ZooKeeper的ACL权限说明: ZooKeeper目前支持create,delete,read,write,admin五种权限,且ZooKeeper对权限的控制是znode级别的,而且不继承,即对父znode设置权限,其子znode不继承父znode的权限。ZooKeeper中znode的默认权限为world:anyone:cdrwa,即任何用户都有所有权限。 ACL有三部分: 第一部分是认证类型,如world指所有认证类型,sasl是kerberos认证类型; 第二部分是账号,如anyone指的是任何人; 第三部分是权限,如cdrwa指的是拥有所有权限。 特别的,由于普通模式启动客户端不需要认证,sasl认证类型的ACL在普通模式下将不能使用。本文所有涉及sasl方式的鉴权操作均是在安全集群中进行。 表1 Zookeeper的五种ACL 权限说明 权限简称 权限详情 创建权限 create(c) 可以在当前znode下创建子znode 删除权限 delete(d) 删除当前的znode 读权限 read(r) 获取当前znode的数据,可以列出当前znode所有的子znodes 写权限 write(w) 向当前znode写数据,写入子znode 管理权限 admin(a) 设置当前znode的权限
  • ZooKeeper结构 ZooKeeper集群中的节点分为三种角色:Leader、Follower和Observer,其结构和相互关系如图1所示。通常来说,需要在集群中配置奇数个(2N+1)ZooKeeper服务,至少(N+1)个投票才能成功的执行写操作。 图1 ZooKeeper结构 图1中各部分的功能说明如表1所示。 表1 结构图说明 名称 描述 Leader 在ZooKeeper集群中只有一个节点作为集群的Leader,由各Follower通过ZooKeeper Atomic Broadcast(ZAB)协议选举产生,主要负责接收和协调所有写请求,并把写入的信息同步到Follower和Observer。 Follower Follower的功能有两个: 每个Follower都作为Leader的储备,当Leader故障时重新选举Leader,避免单点故障。 处理读请求,并配合Leader一起进行写请求处理。 Observer Observer不参与选举和写请求的投票,只负责处理读请求、并向Leader转发写请求,避免系统处理能力浪费。 Client ZooKeeper集群的客户端,对ZooKeeper集群进行读写操作。例如HBase可以作为ZooKeeper集群的客户端,利用ZooKeeper集群的仲裁功能,控制其HMaster的“Active”和“Standby”状态。 如果集群启用了安全服务,在连接ZooKeeper时需要进行身份认证,认证方式有以下两种: keytab方式:需要从MRS集群管理员处获取一个“人机”用户,用于登录MRS平台并通过认证,并且获取到该用户的keytab文件。 票据方式:从MRS集群管理员处获取一个“人机”用户,用于后续的安全登录,开启Kerberos服务的renewable和forwardable开关并且设置票据刷新周期,开启成功后重启kerberos及相关组件。 默认情况下,用户的密码有效期是90天,所以获取的keytab文件的有效期是90天。 Kerberos服务的renewable、forwardable开关和票据刷新周期的设置在Kerberos服务的配置页面的“系统”标签下,票据刷新周期的修改可以根据实际情况修改“kdc_renew_lifetime”和“kdc_max_renewable_life”的值。
  • ZooKeeper原理 写请求 Follower或Observer接收到写请求后,转发给Leader。 Leader协调各Follower,通过投票机制决定是否接受该写请求。 如果超过半数以上的Leader、Follower节点返回写入成功,那么Leader提交该请求并返回成功,否则返回失败。 Follower或Observer返回写请求处理结果。 只读请求 客户端直接向Leader、Follower或Observer读取数据。
  • ZooKeeper常见规格 ZooKeeper服务的常见系统规格如ZooKeeper常见规格所示。 表2 ZooKeeper常见规格 指标名称 规格 说明 单集群ZooKeeper最大实例数 9 ZooKeeper最大实例数 每个ZooKeeper实例,单个IP最大连接数 2000 - 每个ZooKeeper实例,最大连接总数 20000 - 默认参数情况下,最大ZNode数 2000000 ZNode数量过大会对服务稳定性造成影响,降低组件读写性能。 一般业务场景下建议ZNode数量在200w以内,如果集群仅部署了ClickHouse,ZNode数量可以扩大到600w以内。 单个ZNode大小 4MB -
  • 代码样例 以下代码片段在“hbase-zk-example\src\main\java\com\huawei\hadoop\hbase\example”包的“TestZKSample”类中,用户主要需要关注“login”和“connectApacheZK”这两个方法。 private static void login(String keytabFile, String principal) throws IOException { conf = HBaseConfiguration.create(); //In Windows environment String confDirPath = TestZKSample.class.getClassLoader().getResource("").getPath() + File.separator;[1] //In Linux environment //String confDirPath = System.getProperty("user.dir") + File.separator + "conf" + File.separator; // Set zoo.cfg for hbase to connect to fi zookeeper. conf.set("hbase.client.zookeeper.config.path", confDirPath + "zoo.cfg"); if (User.isHBaseSecurityEnabled(conf)) { // jaas.conf file, it is included in the client pakcage file System.setProperty("java.security.auth.login.config", confDirPath + "jaas.conf"); // set the kerberos server info,point to the kerberosclient System.setProperty("java.security.krb5.conf", confDirPath + "krb5.conf"); // set the keytab file name conf.set("username.client.keytab.file", confDirPath + keytabFile); // set the user's principal try { conf.set("username.client.kerberos.principal", principal); User.login(conf, "username.client.keytab.file", "username.client.kerberos.principal", InetAddress.getLocalHost().getCanonicalHostName()); } catch (IOException e) { throw new IOException("Login failed.", e); } } } private void connectApacheZK() throws IOException, org.apache.zookeeper.KeeperException { try { // Create apache zookeeper connection. ZooKeeper digestZk = new ZooKeeper("127.0.0.1:2181", 60000, null); LOG.info("digest directory:{}", digestZk.getChildren("/", null)); LOG.info("Successfully connect to apache zookeeper."); } catch (InterruptedException e) { LOG.error("Found error when connect apache zookeeper ", e); } }
  • ZooKeeper开源增强特性:ZooKeeper SSL通信(Netty连接) ZooKeeper设计最初含有Nio包,且不能较好的支持3.5版本后的SSL。为了解决这个问题,Netty被加入到ZooKeeper中。所以如果用户需要使用SSL,启用Netty并设置Server端和Client端的以下参数。 开源的服务端只支持简单的文本密码,这可能导致相关安全问题。为此在服务端将不再使用此类文本密码。 Client端 将“zkCli.sh/zkEnv.sh”文件中的参数“-Dzookeeper.client.secure”设置为“true”以在Client端使用安全通信。之后客户端可以连接服务端的secureClientPort。 通过设置“zkCli.sh/zkEnv.sh”文件中的以下参数配置客户端环境。 参数 描述 -Dzookeeper.clientCnxnSocket 用于客户端的Netty通信。 默认值:"org.apache.zookeeper.ClientCnxnSocketNetty" -Dzookeeper.ssl.keyStore.location keystore文件路径。 -Dzookeeper.ssl.keyStore.password 加密密码。 -Dzookeeper.ssl.trustStore.location truststore文件路径。 -Dzookeeper.ssl.trustStore.password 加密密码。 -Dzookeeper.config.crypt.class 用于加密密码的解密。 -Dzookeeper.ssl.password.encrypted 默认值:false 当keystore和truststore的密码为加密密码时设置为true。 -Dzookeeper.ssl.enabled.protocols 通过配置此参数定义SSL协议以适用于SSL上下文。 -Dzookeeper.ssl.exclude.cipher.ext 通过配置此参数定义SSL上下文中应排除的密码列表,之间以逗号间隔。 以上参数须在“zkCli.sh/zk.Env.sh”文件内设置。 Server端 在文件“zoo.cfg”中将SSL端口参数“secureClientPort”设置为“3381”。 在server端将文件“zoo.cfg”中的参数“zookeeper.serverCnxnFactory”设置为“org.apache.zookeeper.server.NettyServerCnxnFactory”。 设置文件zoo.cfg(路径:“zookeeper/conf/zoo.cfg”)中的以下参数来配置服务端环境。 参数 描述 ssl.keyStore.location keystore.jks文件路径。 ssl.keyStore.password 加密密码。 ssl.trustStore.location truststore文件路径。 ssl.trustStore.password 加密密码。 config.crypt.class 用于加密密码的解密。 ssl.keyStore.password.encrypted 默认值:false 设置为true时可使用加密密码。 ssl.trustStore.password.encrypted 默认值:false 设置为true时可使用加密密码。 ssl.enabled.protocols 通过配置此参数定义SSL协议以适用于SSL上下文。 ssl.exclude.cipher.ext 通过配置此参数定义SSL上下文中应排除的密码列表,之间以逗号间隔。 启动ZKserver,然后将安全客户端连接到安全端口。 凭证 ZooKeeper上Client和Server之间的凭证由X509AuthenticationProvider执行。根据以下参数指定服务端证书及信任客户端证书,并通过这些证书初始化X509AuthenticationProvider。 zookeeper.ssl.keyStore.location zookeeper.ssl.keyStore.password zookeeper.ssl.trustStore.location zookeeper.ssl.trustStore.password 若用户不想使用ZooKeeper的默认机制,可根据所需配置不同的ZooKeeper信任机制。
  • 回答 在单个父目录中创建大量的znode后,当客户端尝试在单个请求中获取所有子节点时,服务端将无法返回,因为结果将超出可存储在znode上的数据的最大长度。 为了避免这个问题,应该根据客户端应用的实际情况将“jute.maxbuffer”参数配置为一个更高的值。 “jute.maxbuffer”只能设置为Java系统属性,且没有zookeeper前缀。如果要将“jute.maxbuffer”的值设为X,在ZooKeeper客户端或服务端启动时传入以下系统属性:-Djute.maxbuffer=X。 例如,将参数值设置为4MB:-Djute.maxbuffer=0x400000。 表1 配置参数 参数 描述 默认值 jute.maxbuffer 指定可以存储在znode中的数据的最大长度。单位是Byte。默认值为0xfffff,即低于1MB。 说明: 如果更改此选项,则必须在所有服务器和客户端上设置该系统属性,否则将出现问题。 0xfffff
  • 处理步骤 获取ZooKeeper的IP地址及端口信息,具体请参考如何获取ZooKeeper地址?。 以root用户登录Master节点。 初始化环境变量。 source /opt/client/bigdata_env 执行以下命令连接ZooKeeper。 zkCli.sh -server ZooKeeper所在节点的IP:端口 ZooKeeper所在节点的IP即为1中查到的结果,多个IP之间以逗号间隔。 使用ls /等常用的命令查看ZooKeeper上的信息。
  • 回答 创建大量节点后,follower与leader同步时数据量大,在集群数据同步限定时间内不能完成同步过程,导致超时,各个ZooKeeper server启动失败。 参考修改集群服务配置参数章节,进入ZooKeeper服务“全部配置”页面。不断尝试调大ZooKeeper配置文件“zoo.cfg”中的“syncLimit”和“initLimit”两参数值,直到ZooKeeperServer正常。 表1 参数说明 参数 描述 默认值 syncLimit follower与leader进行同步的时间间隔(时长为ticket时长的倍数)。如果在该时间范围内leader没响应,连接将不能被建立。 15 initLimit follower连接到leader并与leader同步的时间(时长为ticket时长的倍数)。 15 如果将参数“initLimit”和“syncLimit”的参数值均配置为“300”之后,ZooKeeper server仍然无法恢复,则需确认没有其他应用程序正在kill ZooKeeper。例如,参数值为“300”,ticket时长为2000毫秒,即同步限定时间为300*2000ms=600s。 可能存在以下场景,在ZooKeeper中创建的数据过大,需要大量时间与leader同步,并保存到硬盘。在这个过程中,如果ZooKeeper需要运行很长时间,则需确保没有其他监控应用程序kill ZooKeeper而判断其服务停止。
  • 代码样例 以下代码片段在“hbase-zk-example\src\main\java\com\huawei\hadoop\hbase\example”包的“TestZKSample”类中,用户主要需要关注“login”和“connectApacheZK”这两个方法。 private static void login(String keytabFile, String principal) throws IOException { conf = HBaseConfiguration.create(); //In Windows environment String confDirPath = TestZKSample.class.getClassLoader().getResource("").getPath() + File.separator;[1] //In Linux environment //String confDirPath = System.getProperty("user.dir") + File.separator + "conf" + File.separator; // Set zoo.cfg for hbase to connect to fi zookeeper. conf.set("hbase.client.zookeeper.config.path", confDirPath + "zoo.cfg"); if (User.isHBaseSecurityEnabled(conf)) { // jaas.conf file, it is included in the client pakcage file System.setProperty("java.security.auth.login.config", confDirPath + "jaas.conf"); // set the kerberos server info,point to the kerberosclient System.setProperty("java.security.krb5.conf", confDirPath + "krb5.conf"); // set the keytab file name conf.set("username.client.keytab.file", confDirPath + keytabFile); // set the user's principal try { conf.set("username.client.kerberos.principal", principal); User.login(conf, "username.client.keytab.file", "username.client.kerberos.principal", InetAddress.getLocalHost().getCanonicalHostName()); } catch (IOException e) { throw new IOException("Login failed.", e); } } } private void connectApacheZK() throws IOException, org.apache.zookeeper.KeeperException { try { // Create apache zookeeper connection. ZooKeeper digestZk = new ZooKeeper("127.0.0.1:2181", 60000, null); LOG.info("digest directory:{}", digestZk.getChildren("/", null)); LOG.info("Successfully connect to apache zookeeper."); } catch (InterruptedException e) { LOG.error("Found error when connect apache zookeeper ", e); } }