亚马逊AWS官方博客

利用 Amazon Elastic Kubernetes Service(Amazon EKS)打造弹性 StarRocks 集群

前言

作为一款面向分析型工作负载的全新一体化 MPP 分析数据库,StarRocks 凭借其简洁的架构、CBO 优化器、向量化执行引擎等特色功能开始变得愈发流行。无论从易用性、性能还是成本角度来看,其都是一款出色的数仓产品。

StarRocks 在 3.0 版本中推出了存算分离架构的特性。在这种模式下,StarRocks 将数据存储在兼容 Amazon Simple Storage Service(S3)协议的对象存储或 HDFS 中,而本地磁盘则作为热数据缓存,用于加速查询。这种存储计算分离架构不仅能有效降低存储成本,优化资源隔离,更能增强集群的弹性扩展能力。

从 StarRocks 官网中的架构示例我们可以看出,在存算分离架构中,负责存储和计算数据的 BE 节点被 CN 节点取代。后者仅负责数据计算任务和缓存热数据。数据存储在低成本且可靠的远端存储系统中,如 Amazon S3。当缓存命中时,查询性能可与存算一体架构相媲美。CN 节点可以根据需要在几秒钟内添加或删除。这种架构降低了存储成本,确保更好的资源隔离,并具有高度的弹性和可扩展性。

根据 StarRocks 官网的描述,相对存算一体架构,StarRocks 的存储计算分离架构提供以下优势:

  • 廉价且可无缝扩展的存储。
  • 弹性可扩展的计算能力。由于数据不存储在 CN 节点中,因此集群无需进行跨节点数据迁移或 Shuffle 即可完成扩缩容。
  • 热数据的本地磁盘缓存,用以提高查询性能。
  • 可选异步导入数据至对象存储,提高导入效率。

本文主要针对 StarRocks 的存算分离模式进行展开探讨,主要包括其在亚马逊云进行容器化部署的一些优势,以及在部署过程中的建议。

利用 S3 高吞吐量搭建数据持久层

在存算分离模式下,StarRocks 将数据存储在对象存储中,而本地盘作为热数据缓存,用以加速查询。通过存储计算分离架构,您可以降低存储成本并且优化资源隔离。除此之外,集群的弹性扩展能力也得以加强。在查询命中缓存的情况下,存算分离集群的查询性能与存算一体集群性能一致。

S3 是您作为云上存储 StarRocks 数据的非常理想的选择。S3 支持近乎无限量的存储空间,S3 与 EC2 之间高达 100Gbps 的带宽吞吐,也可以支持您进行大规模,快速的数据读写。StarRocks 对 S3 做了很好的支持,您可以参考该文档快速以 S3 为数据底座,搭建起您的 StarRocks 集群。

充分发挥 S3 的性能优势,以下是对于 S3 相关的一些使用建议。

开启分区前缀

自 v3.2.4 起,StarRocks 支持基于兼容 S3 的对象存储系统创建带有分区前缀功能的存储卷。当启用此功能时,StarRocks 会将数据存储在存储桶下多个使用统一前缀的分区(子路径)中。由于存储桶的 QPS 或吞吐量限制是基于单个分区设置的,此举可以轻松提高 StarRocks 对存储桶中数据文件的读写性能。

我们可以看到,若没有开启分区前缀功能,每张表的 S3 前缀是一致的(其中 db16172 即为 StarRocks 数据库 ID):

您可以在创建 S3 存储卷时,通过设置 “aws.s3.enable_partitioned_prefix” = “true” 参数,开启分区前缀功能。开启后,我们可以观察到,数据在导入 S3 存储桶时,自动添加了随机前缀:

数据物理隔离

另外,从自 v3.1.0 版本之后,您也可以为每个表配置为不同的存储桶进行单独存储,以便进行底层数据的物理隔离。您可以通过创建 Storage Volume 绑定不同的存储桶,然后在建表时,通过 “storage_volume” 属性将表存储到指定对应的存储卷,以实现数据隔离。

有效利用 DataCache

从性能和成本上考虑,建议您对表开启 DataCache。DataCache 支持您将热数据缓存到 CN 节点本地磁盘上,当出现 Cache Miss 的情况,StarRocks 会以 Block(MB 级别)为单位,按需从远端存储中加载数据,将热数据更新到本地。由此可以:

  1. 让热数据请求命中本地缓存,提升热数据的 I/O 读写性能。
  2. S3 对于数据的写入及读取是按 API 请求次数收费的,开启缓存可以降低对 S3 的读写频次,从而有效降低 S3 的读写费用。

StarRocks 对于 DataCache 的配置也非常灵活,具体如下:

  • 自 v3.2.3 版本起,StarRocks 创建存算分离表时,默认是开启 DataCache 的。您也可以通过配置 “datacache.enable” = “false” 关闭该功能。
  • 同时,您也可以通过指定 “datacache.partition_duration” 属性设置一个特定的时间范围,可以通过以下单位指定:YEAR,MONTH,DAY 和 HOUR。超出该时间范围的数据,将不会被缓存到本地。
  • 支持自动的 LRU 淘汰机制。您可以配置 starlet_star_cache_disk_size_percent 参数,设置 Data Cache 最多可使用的磁盘容量百分比。当本地磁盘数据达到容量阈值时,会自动触发旧数据的缓存淘汰。

在 3.3 版本中,StarRocks 新增了缓存预热的功能。缓存预热命令允许将选定的数据预加载到缓存中,从而减少未来初始查询的延迟。并且在未来版本中,也会引入缓存优先级功能,进一步允许用户为不同的数据设置不同的缓存优先级,确保最关键的数据优先进行缓存,进一步提高关键数据缓存命中率。

完善性能监控

StarRocks 集群支持众多的监控指标。您可以通过 Prometheus 采集 S3 相关指标并通过 Grafana 进行展示。在 StarRocks 官方提供的 Grafana 模板中,也提供了存算分离模式下的 S3 相关的监控指标。您可以重点关注如下指标:

  • fslib read io_latency (average):描述 S3 读取的平均延迟
  • fslib total read data:描述 S3 读取的总数据大小
  • fslib read iops:描述 S3 读取的每秒 I/O 操作次数
  • fslib s3 single upload iops:描述 S3 Put Object 的每秒调用次数
  • fslib cache hit ratio:描述缓存命中率

更多指标详情请参考:https://docs.starrocks.io/zh/docs/administration/management/monitoring/metrics-shared-data/

利用 Elastic Kubernetes Service(EKS)实现快速弹性伸缩

在存算分离架构中,由于计算节点(CN)的无状态特性,我们可以根据算力需求,随时对 CN 节点进行弹性扩缩容,以实现成本最优的基础架构。这一特性非常适用于以下(不限于)对计算能力有突发性需求的场景:

  • 数据批量导入
  • T+1 数据计算
  • 即席查询分析

在传统部署模式下,对 CN 集群进行扩缩容相对较为不便。通过手动方式很难实现根据实际业务负载自动调节资源的效果。而在 EKS 上部署则可以有效解决这一问题,实现计算资源的自动弹性调度。

利用 HPA 对 CN Pod 进行自动弹性伸缩

您可以在通过 Operator 部署 StarRocks 的过程中,自定义 CN Pod 的自动拓展策略以及拓展行为,以下为一个示例:

autoScalingPolicy: 
  maxReplicas: 10
  minReplicas: 2
  hpaPolicy:
    metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          averageUtilization: 70
              type: Utilization
        behavior:
          scaleUp:
            policies:
            - type: Pods
              value: 1
              periodSeconds: 10
          scaleDown:
            selectPolicy: Enable

当 CN Pod 平均 CPU 利用率超过 70% 时,即会触发 CN 计算节点的横向扩容。新增的 CN 节点会自动注册到集群中;而当 CPU 利用率低于 70% 时,CN 节点会进行自动缩容。CN 节点的弹性扩所容可以交由 HPA 管理,无需再做人工维护。

利用 Karpenter 对实例进行自动弹性伸缩

Karpenter 是亚马逊云在 2021 年正式发布的,针对 Kubernetes 集群进行节点扩缩的开源管理组件。相比于传统的 Cluster AutoScaler(CA)组件,Karpenter 抛弃了节点组的概念,利用 EC2 Fleet API 对实例进行更快速的扩缩容,并引入了更为灵活的配置选项,让用户可以选择合适的机型,可用区,以及购买选项等。

您可以通过如下示例 NodePool/NodeClass 资源对象,定义扩展节点池的硬件要求、实例类型、操作系统,以及节点的生命周期管理策略:

apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: default
spec:
  template:
    spec:
      requirements:
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]  #实例架构为amd64
        - key: kubernetes.io/os
          operator: In
          values: ["linux"]  #操作系统为Linux
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["spot"]  #使用Spot实例
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["c", "m", "r"]  #实例类型为c,m或者r系列
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ["2"]  #实例代数大于2
      nodeClassRef:
        apiVersion: karpenter.k8s.aws/v1beta1
        kind: EC2NodeClass
        name: default
  limits:
    cpu: 1000  #设置了最大 CPU 限制为 1000
  disruption:
    consolidationPolicy: WhenUnderutilized  #设置节点合并策略
    expireAfter: 720h # 30 * 24h = 720h  #设置节点生命周期
---
apiVersion: karpenter.k8s.aws/v1beta1
kind: EC2NodeClass
metadata:
  name: default
spec:
  amiFamily: AL2 # 指定AMI
  role: "KarpenterNodeRole-${CLUSTER_NAME}" # 指定角色名称
  subnetSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}" # 定义子网选择条件
  securityGroupSelectorTerms:
    - tags:
        karpenter.sh/discovery: "${CLUSTER_NAME}" # 定义安全组选择条件
  amiSelectorTerms:  # 定义AMI选择条件
    - id: "${ARM_AMI_ID}"
    - id: "${AMD_AMI_ID}"

利用 Graviton 实例有效降低集群成本

当前,云计算服务提供商纷纷推出基于 ARM 架构的新一代实例,如亚马逊云的 Graviton 实例。这些实例凭借出色的性能和优秀的能效比,为用户带来了降低成本的新选择。针对这一趋势,作者对亚马逊云的 Graviton 实例(C7g)和传统 x86 实例(C6i)在 StarRocks on EKS 环境下进行了 TPC-DS 基准测试,以评估 ARM 架构实例在 StarRocks on EKS 场景下的表现。

测试环境配置如下:

  • 部署模式:Shared Data(存算分离)
  • StarRocks 版本:3.2.9
  • EKS 版本:1.29
  • 数据集大小:100GB

注:上图中展示的是 C6i 对比 C7g 在每个 SQL 任务处理时间的比例关系。

在关闭 DataCache 的前提下,结果显示,在相同配置相同实例规格下,C6i 实例的 TPC-DS 总查询时间约为 C7g 实例的 1.4 倍。以 C6i.8xlarge 和 C7g.8xlarge 为例,在美东一区,C6i 价格为 C7g 的近 1.2 倍。这意味着,在 StarRocks on EKS 场景中,Graviton 实例可以以更低的成本,提供提供优于同代 x86 实例的查询性能。关于 StarRocks 新版本对于 ARM 架构的优化特性,在其官网 Blog 中也有提及。

Terraform 一键部署 StarRocks on EKS

在当今云原生时代,Kubernetes 已成为管理和编排容器化应用的首选平台。StarRocks 社区推出了 Operator,极大简化了在 Kubernetes 环境(如 Amazon EKS)中部署和管理 StarRocks 集群的流程。但在实际部署过程中,StarRocks 集群往往需要与其他云原生组件协同工作,如 EBS CSI Driver(用于挂载 EBS 存储)、Prometheus 和 Grafana(用于监控和可视化)等等。手动一一部署和配置这些组件无疑是一件繁琐且容易出错的工作。

有鉴于此,您可以参考下文中的 Terraform 示例,通过代码即可自动化供给所需的亚马逊云资源(如 VPC、子网、安全组等),并一键部署 EKS 集群、StarRocks Operator 以及相关依赖组件。该架构包括:

  • 一个完整 VPC 架构,包括子网/NAT Gateway/IGW 及相关路由配置
  • 一个 EKS 集群,您可以指定集群的规格和规模
  • StarRocks on EKS 集群,您可以指定 FE 和 CN 的节点数量及规格
  • Metrics Server&Karpenter 等组件
  • Prometheus&Grafana 组件及对应的 StarRocks 相关的 DashBoard

Terraform 示例文件请从此处下载。

总结

在本文中,我们探讨了在亚马逊云环境中使用 Elastic Kubernetes Service(EKS)部署 StarRocks 存算分离架构的优势和建议。依托 EKS,S3 以及 Graviton 实例等等亚马逊云服务,您可以轻松构建出高性能、可扩展、低成本的云数据分析平台,满足企业日益增长的数据分析需求。

参考链接

Karpenter 官方文档:https://karpenter.sh/docs/
StarRocks 官方文档:https://docs.starrocks.io/zh/docs/introduction/StarRocks_intro/
StarRocks 官方 Blog 文档:https://www.starrocks.io/blog/starrocks-3.3-is-out-features-and-improvements

本篇作者

孟祥智

亚马逊云科技解决方案架构师

柯俊雄

亚马逊云科技解决方案架构师,专注于数据分析/容器化领域。

黄际东

亚马逊云科技解决方案架构师,有过银行、旅游、直播、教育等行业的十多年项目经验。曾独立主导实现从零到千万用户级别的教育类应用,也参与研发过月活跃用户过千万的全球知名直播平台。在互联网领域拥有多年的研发及运维经验,是一个喜欢编程的解决方案架构师。