cassandra hbase_弥补MySQL和Redis短板:看HBase怎么确保高可用

知乎技术团队分享了他们基于Kubernetes构建HBase在线服务的实践经验,包括为何选择HBase、面临的问题、解决方案以及Kubernetes在其中的作用。他们通过Kubernetes实现了HBase集群的隔离性、资源利用率优化和成本控制,提供了高可用和故障恢复机制,打造了一套完整的HBase自动化运维服务体系。
摘要由CSDN通过智能技术生成

HBase 是一个基于 Hadoop 面向列的非关系型分布式数据库(NoSQL),设计概念来源于谷歌的 BigTable 模型。

bbf26e8bf6b20d253750a3edbfdc38f3.png

它面向实时读写、随机访问大规模数据集的场景,是一个高可靠性、高性能、高伸缩的分布式存储系统,在大数据相关领域应用广泛。

HBase 系统支持对所存储的数据进行透明切分,从而使得系统的存储以及计算具有良好的水平扩展性。

知乎从 2017 年起开始逐渐采用 HBase 系统存储各类在线业务数据,并在 HBase 服务之上构建各类应用模型以及数据计算任务。

伴随着知乎这两年的发展,知乎核心架构团队基于开源容器调度平台 Kubernetes 打造了一整套 HBase 服务平台管理系统。

经过近两年的研发迭代,目前已经形成了一套较为完整的 HBase 自动化运维服务体系,能够完成 HBase 集群的快捷部署、平滑扩缩容、HBase 组件细粒度监控、故障跟踪等功能。

知乎对 HBase 的使用经验不算太长,在 2017 年初的时候,HBase 服务主要用于离线算法、推荐、反作弊,还有基础数据仓库数据的存储计算,通过 MapReduce 和 Spark 来进行访问。

而在当时知乎的在线存储主要采用 MySQL 和 Redis 系统,其中:

  • MySQL:支持大部分的业务数据存储,当数据规模增大后有一些需要进行扩容的表,分表会带来一定的复杂性。

有些业务希望能屏蔽这个事情,还有一些是因为历史原因在表设计的时候用 rmsdb 的形式存了一些本该由列存储的数据,希望做一下迁移。此外 MySQL 基于 SSD,虽然性能很好,花销也比较大。

  • Redis:可以提供大规模的缓存,也可以提供一定的存储支持。Redis 性能极好,主要的局限是做数据 Resharding 较为繁琐,其次是内存成本较高。

针对以上两种在线存储所存在的一些问题,我们希望建立一套在线存储 NoSQL 服务,对以上两种存储作为一个补充。

选型期间我们也考虑过 Cassandra,早期一些业务曾尝试使用 Cassandra 作为存储。

隔壁团队在运维了一段时间的 Cassandra 系统之后,遇到不少的问题,Cassandra 系统可操作性没有达到预期,目前除了 Tracing 相关的系统,其他业务已经放弃使用 Cassandra。

我们从已有的离线存储系统出发,在衡量了稳定性、性能、代码成熟度、上下游系统承接、业界使用场景以及社区活跃度等方面之后,选择了 HBase,作为知乎在线存储的支撑组件之一。

HBase On Kubernetes

初期知乎只有一套进行离线计算的集群,所有业务都跑在一个集群上,并且 HBase 集群和其他离线计算 Yarn 以及 Impala 混合部署,HBase 的日常离线计算和数据读写都严重受到其他系统影响。

并且 HBase 的监控都只停留在主机层面的监控,出现运行问题时,进行排查很困难,系统恢复服务时间较长,这种状态下,我们需要重新构建一套适用于在线服务的系统。

在这样的场景下,我们对在线 HBase 服务的需求是明确的:

①隔离性:从业务方的视角来说,希望相关的服务做到环境隔离,权限收归业务,避免误操作和业务相互影响。

对于响应时间,服务的可用性,都可以根据业务的需要指定 SLA;对于资源的分配和 blockcache 等参数的配置也能够更加有适应性,提供业务级别的监控和报警,快速定位和响应问题。

②资源利用率:从运维的角度,资源的分配要合理,尽可能的提升主机 CPU,内存包括磁盘的有效利用率。

③成本控制:团队用最小的成本去得到最大的运维收益,所以需要提供便捷的调用接口,能够灵活的进行 HBase 集群的申请、扩容、管理、监控。

同时成本包括机器资源,还有工程师。当时我们线上的这套系统是由一位工程师独立去进行维护。

综合以上需求,参考我们团队之前对基础设施平台化的经验,最终的目标是把 HBase 服务做成基础组件服务平台提供给上游业务。

这个也是知乎技术平台部门工作思路之一,尽可能的把所有的组件对业务都黑盒化,接口化,服务化。

同时在使用和监控的粒度上尽可能的准确,细致,全面。这是我们构建在线 HBase 管理运维系统的一个初衷。

Why Kubernetes?

前文说到我们希望将整个 HBase 系统平台服务化,那就涉及到如何管理和运维 HBase 系统,知乎在微服务和容器方面的工作积累和经验是相当丰富的:

  • 在当时我们所有的在线业务都已经完成了容器化的迁移工作,超万级别的业务容器平稳运行在基于 Mesos 的容器管理平台 Bay 上(参见[1])。
  • 与此同时,团队也在积极的做着 Infrastructure 容器化的尝试,已经成功将基础消息队列组件 Kafka 容器化运行于 Kubernetes 系统之上(参见[2]),因此我们决定也将 HBase 通过 Kubernetes 来进行资源的管理调度。

Kubernetes 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术 Borg 的开源版本。

Kubernetes 提供各种维度组件的资源管理和调度方案,隔离容器的资源使用,各个组件的 HA 工作,同时还有较为完善的网络方案。

Kubernetes 被设计作为构建组件和工具的生态系统平台,可以轻松地部署、扩展和管理应用程序。有着 Kubernetes 大法的加持,我们很快有了最初的落地版本([4])。

初代架构

最初的落地版本架构见下图,平台在共享的物理集群上通过 Kubernetes(以下简称 K8S)API 建立了多套逻辑上隔离的 HBase 集群。

每套集群由一组 Master 和若干个 Regionserver(以下简称 RS)构成,集群共享一套 HDFS 存储集群,各自依赖的 Zookeeper 集群独立;集群通过一套管理系统 Kubas 服务来进行管理([4])。

00c0942a7b0338ce5ec4163712324eb8.png

第一代架构

模块定义:在 K8S 中如何去构建 HBase 集群,首先需要用 K8S 本身的基础组件去描述 HBase 的构成。

K8S 的资源组件有以下几种:

  • Node:定义主机节点,可以是物理机,也可以是虚拟机;
  • Pod:一组紧密关联的容器集合,是 K8S 调度的基本单位;
  • ReplicationController:一组 Pod 的控制器,通过其能够确保 Pod 的运行数量和健康,并能够弹性伸缩。

结合之前 Kafka on K8S 的经验,出于高可用和扩展性的考虑,我们没有采用一个 Pod 里带多个容器的部署方式。

而是统一用一个 ReplicationController 定义一类HBase组件,就是上图中的 Master,Regionserver 还有按需创建的 Thriftserver。

通过以上概念,我们在 K8S 上就可以这样定义一套最小 HBase 集群:

  • 2*MasterReplicationController
  • 3*RegionserverReplicationController
  • 2*ThriftserverReplicationController(可选)

高可用以及故障恢复

作为面向在线业务服务的系统,高可用和故障转移是必需在设计就要考虑的事情,在整体设计中,我们分别考虑组件级别、集群级别和数据存储级别的可用性和故障恢复问题。

①组件级别

HBase 本身已经考虑了很多故障切换和恢复的方案:

  • Zookeeper 集群:自身设计保证了可用性。
  • Master:通过多个 Master 注册在 Zookeeper 集群上来进行主节点的 HA 和更新。
  • RegionServer:本身就是无状态的,节点失效下线以后会把上面的 Region 自动迁走,对服务可用性不会有太大影响。
  • Thriftserver:当时业务大多数是 Python 和 Golang,通过用 Thrift 对 HBase 的进行,Thriftserver 本身是单点的,这里我们通过 HAProxy 来代理一组 Thriftserver 服务。
  • HDFS:本身又由 Namenode 和 DataNode 节点组成,Namenode 我们开启 HA 功能,保证了 HDFS 的集群可用性。

②集群级别

关于集群级别:

  • Pod 容器失效:Pod 是通过 Replication Controller 维护的,K8S 的 Controller Manager 会在它的存储 etcd 去监听组件的失效情况,如果副本少于预设值会自动新的 Pod 容器来进行服务。
  • Kubernetes 集群崩溃:该场景曾经在生产环境中出现过,针对这种情况,我们对 SLA 要求较高的业务采用了少量物理机搭配容器的方式进行混合部署,极端场景出现时,可以保证重要业务受到的影响可控。

③数据级别

所有在 K8S 上构建的 HBase 集群都共享了一套 HDFS 集群,数据的可用性由 HDFS 集群的多副本来提供。

实现细节

资源分配

初期物理节点统一采用 2*12 核心的 CPU,128G 内存和 4T 的磁盘,其中磁盘用于搭建服务的 HDFS,CPU 和内存则在 K8S 环境中用于建立 HBase 相关服务的节点。

Master 组件的功能主要是管理 HBase 集群,Thriftserver 组件主要承担代理的角色,所以这两个组件资源都按照固定额度分配。

在对 Regionserver 组件进行资源分配设计的时候,考虑两种方式去定义资源:

8481e81342f8f7cc4670cdd97452f6e4.png

资源分配方式

按照业务需求分配:

  • 根据业务方对自身服务的描述,对相关的 QPS 以及 SLA 进行评估,为业务专门配置参数,包含 Blockcache,Region 大小以及数量等。
  • 优点是针对业务优化,能够充分的利用资源,降低业务的资源占用成本。
  • 管理成本增加,需要对每一个业务进行评估,对平台维护人员非常不友好,同时需要业务同学本身对 HBase 有理解。

统一规格的资源分配:

  • CPU 以及 MEM 都按照预先设定好的配额来分配,提供多档的配置,将 CPU 和 MEM 的配置套餐化。
  • 方便之处在于业务扩容时直接增加 Regionserver 的个数,配置稳定,运维成本较低,遇到问题时排障方便。
  • 针对某些有特有访问方式的业务有局限性,如 CPU 计算型,大 KV 存储,或者有 MOB 需求的业务,需要特殊的定制。
  • 介于当时考虑接入的在线业务并不多,所以采用了按业务定制的方式去配置 Regionserver,正式环境同一业务采用统一配置的一组 Regionserver,不存在混合配置的 Regionserver 组。

参数配置

# Example for hbase dockerfile # install cdh5.5.0-hbase1.0.0 ADD hdfs-site.xml /usr/lib/hbase/conf/ ADD core-site.xml /usr/lib/hbase/conf/ ADD env-init.py /usr/lib/hbase/bin/ ENV JAVA_HOME /usr/lib/jvm/java-8-oracle ENV HBASE_HOME /usr/lib/hbase ENV HADOOP_PREFIX /usr/lib/hadoop ADD env-init.py /usr/lib/hbase/bin/ ADD hadoop_xml_conf.sh /usr/lib/hbase/bin/ 

基础镜像基于 cdh5.5.0-hbase1.0.0 构建:

  • 固定的环境变量,如 JDK_HOME,HBASE_HOME,都通过 ENV 注入到容器镜像中。
  • 与 HDFS 相关的环境变量,如 hdfs-site.xml 和 core-site.xml 预先加入 Docker 镜像中,构建的过程中就放入了 HBase 的相关目录中,用以确保 HBase 服务能够通过对应配置访问到 HDFS。
  • 与 HBase 相关的配置信息,如组件启动依赖的 Zookeeper 集群地址, HDFS 数据目录路径,堆内存以及 GC 参数等,这些配置都需要根据传入 KubasService 的信息进行对应变量的修改。

一个典型的传入参数示例:

REQUEST_DATA = {  "name": 'test-cluster',  "rootdir": "hdfs://namenode01:8020/tmp/hbase/test-cluster
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值