美文网首页
Zookeeper在华为云设备接入服务的使用

Zookeeper在华为云设备接入服务的使用

作者: ShootHzj | 来源:发表于2021-04-10 19:25 被阅读0次

    前言

    和我断断续续合作过快一年半的同事要离职啦,跟他一起处理过很多Zookeeper的问题,作文以记之。转载请注明出处。

    华为云设备接入服务是面向多租户的服务。架构为微服务化结构。

    使用Zookeeper的使用场景

    image-20210410093126548

    分布式缓存清理

    为了更快地响应,我们将一些不常变更的元数据信息做了内存缓存,在我们还没有做业务配置中心之前,缺乏通知能力,这部分是通过Zookeeper来实时通知缓存的清理和刷新的

    实现一致性哈希算法

    用户数量大的情况下,部分业务很难由一个微服务实例承接(如海量用户的证书加载等),通过一致性哈希算法或类似的算法来将业务均分到不同的微服务实例上。

    严格分布式锁

    用户开户,注册设备的时候,需要保证严格不重复,通过Zookeeper的强一致性,来实现分布式锁。

    自建Pulsar依赖Zookeeper

    很多开源软件都依赖Zookeeper,如FlinkHadoopPulsar等,我们自建Zookeeper集群来满足开源组件对Zookeeper的依赖

    微服务注册中心

    相比其他微服务引擎,如华为云的ServiceStage,阿里云的MSE,已有的Zookeeper集群作为微服务的注册中心,既能满足微服务数量较少时的功能需求,并且更加节约成本

    数据库连接均衡

    image-20210410100426706

    之前,我们微服务连接数据库的地址的策略是随机选择,上面是我随便画了一个随机可能造成的场景,我们假设有微服务B和微服务C,微服务C实例虽多,但对数据库的操作并不多。微服务B在运行期间,操作数据库更加频繁。上图的连接方式就会造成数据库Data2节点的连接数和CPU居高不下,成为集群的瓶颈。我们的灵感来自于Kafkapartition的分配算法,微服务B1连接了Data1和Data2,那么B2就去连Data3和Data4,如果还有B3,就再去连Data1和Data2节点。微服务C1的连接,再从Data1和Data2节点开始。但是因为微服务的数量和数据库实例的数量乘以2(因为每个微服务建立2个连接)并不一定整除,可能会造成Data1节点和Data2节点负载不均衡。所以我们在这个的基础上,加上第一个微服务实例选择数据库节点,从随机起点出发,这样子也保证了Data1节点和Data2节点的均衡。如下图

    image-20210410102225646

    部署

    服务端部署方式

    我们所有微服务和中间件均采用容器化部署,个数选择3节点(没有learner)规格。使用statefulset搭配pvc即公有云上的云硬盘进行部署。为什么使用statefulset进行部署?statefulset非常适合用于像Zookeeper这样有持久化存储需求的服务,每个Pod可以和对应的存储资源绑定,保证数据的持久化,同时也简化了部署,如果想使用deploy的部署模式,需要规划、固定每个pod的虚拟机部署。Zookeeper本身对云硬盘的要求并不高,普通IO,几十G存储就已经能够支撑Zookeeper平稳运行了。Zookeeper本身运行的资源,使用量不是很大,在我们的场景,规格主要取决于Pulsar的topic数量,如果Pulsar的topic不多,那么0.5核、2G内存已经能保证Zookeeper平稳运行了。

    客户端连接方式

    客户端使用域名的方式进行连接,如zookeeper-0.zookeeper:2181,zookeeper-1.zookeeper:2181,zookeeper-2.zookeeper:2181

    重要监控指标

    • readlantency、updatelantency

      zk的读写延迟

    • approximate_data_size

      zk中数据的平均大小估计

    • outstanding_requests

      等待Zookeeper处理的请求数

    • znode_count

      Zookeeper当前的znode总数

    • num_alive_connections

      Zookeeper当前活跃的连接数

    碰到的问题

    readiness合理设置

    这是碰到的最有趣的问题,readiness接口是k8s判断pod是否正常的依据,那么对于Zookeeper集群来说,最合理的就是,当这个Zookeeper节点加入集群,获得了属于自己的LeaderFollower状态,就算pod正常。可是,当初次部署的时候,只有一个节点可用,该节点一个实例无法完成选举流程,导致无法部署。

    综上,我们把readiness的策略修改为:

    image-20210410111218429

    PS:为了让readiness检查不通过时,Zookeeper集群也能选主成功,需要配置publishNotReadyAddresses为true,示例如下

    apiVersion: v1
    kind: Service
    metadata:
      name: zookeeper
    spec:
      selector:
        app: zookeeper
      clusterIP: None
      sessionAffinity: None
      publishNotReadyAddresses: true
      ports:
        - protocol: TCP
          port: 2181
          name: client
        - protocol: TCP
          port: 2888
          name: peer
        - protocol: TCP
          port: 3888
          name: leader
    

    jute.maxbuffer超过上限

    jute.maxbuffer,这个是znode中存储数据大小的上限,在客户端和服务端都需要配置,根据自己在znode上存储的数据合理配置

    zookeeper的Prometheus全0监听

    不满足华为的安全要求,不满足网络监听最小可见原则。修改策略,添加一个可配置参数来配置监听的IP metricsProvider.httpHost,提交PR,待合入 https://github.com/apache/zookeeper/pull/1574/files

    客户端版本号过低,域名无法及时刷新

    客户端使用域名进行连接,但在客户端版本号过低的情况下,客户端并不会刷新新的ip,还是会用旧的ip尝试连接。升级客户端版本号到curator-4.3.0、zookeeper-3.6.2版本后解决。

    总结

    Zookeeper对我们来说,目前还是一个不可替代的组件。Zookeeper本身在网上运行也很稳定,我们对现网的Zookeeper升级频率大约是半年一次。更多的工作是在上面做一些加固,满足安全规范、适配我们的部署等工作。

    相关文章

      网友评论

          本文标题:Zookeeper在华为云设备接入服务的使用

          本文链接:https://www.haomeiwen.com/subject/pwvnkltx.html