扩缩 Kubernetes 部署

在 Kubernetes 环境中,您可以根据工作负载需求的变化动态扩缩数据库资源。如果您使用 Helm 图表部署了 Spanner Omni,请按照以下伸缩程序操作。

准备工作

在扩缩 Kubernetes 部署之前,您必须执行以下操作:

根据最佳实践,我们建议您先将每个服务器的内存垂直伸缩到至少 32 GB,然后再添加更多服务器以进行水平扩容。

限制

Kubernetes 中的扩缩具有以下限制:

  • 仅限非根服务器:非根实例支持横向伸缩。不支持根服务器伸缩。

  • StatefulSet 存储空间限制:由于 Kubernetes volumeClaimTemplates 是不可变的,因此您无法使用单个 helm upgrade 命令来扩展 pod 磁盘。相反,伸缩存储空间需要手动执行扩充卷的步骤。

纵向扩缩

如需调整服务器的 CPU 或内存资源,请使用 Helm 升级来更新配置:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set resources.cpu=CPU_CORES \
  --set resources.memory=MEMORY_LIMIT \
  -n NAMESPACE

替换以下内容:

  • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni。
  • VERSION:Helm 图表的版本,例如 1.0.0。
  • CPU_CORES:要分配给每个服务器 pod 的 vCPU 核心数量,例如 8。
  • MEMORY_LIMIT:每个服务器 pod 的 RAM 限制,例如 32Gi。
  • NAMESPACE:部署的 Kubernetes 命名空间,例如 spanner-ns。

横向扩缩

如需进行横向扩缩,请向部署中添加更多服务器。非根服务器支持横向伸缩。

添加非根服务器

如需添加非根服务器,请增加 Helm 图表配置中的副本数量。您可以统一扩缩所有可用区,也可以扩缩特定可用区。

均匀缩放

如需将部署中的每个可用区扩容到 15 台服务器,请运行以下命令:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set deployment.replicasPerZone=REPLICAS \
  -n NAMESPACE

替换以下内容:

  • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni。
  • VERSION:Helm 图表的版本,例如 1.0.0。
  • REPLICAS:每个可用区内的目标服务器副本数,例如 15。
  • NAMESPACE:Kubernetes 命名空间,例如 spanner-ns。

扩缩特定可用区

如果您的初始部署为各个可用区配置了不同的服务器数量,您可以定位到单个可用区。例如,如需将第一个位置内第一个可用区的副本数增加到 15,请运行以下命令:

helm upgrade spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --reuse-values \
  --set locations[0].zones[0].replicas=REPLICAS \
  -n NAMESPACE

将 REPLICAS 替换为目标可用区副本数量,例如 15。

如需验证新服务器是否已成功加入部署,请查询 Spanner Omni CLI 以列出部署服务器,或查看 Grafana 信息中心。

spanner deployment servers list \
  --zone=ZONE \
  --deployment-endpoint=ENDPOINT

替换以下内容:

  • ZONE:您要列出的可用区,例如 us-central1-a。
  • ENDPOINT:部署的外部端点,例如 ${ENDPOINT}:15000。

移除非根服务器

缩减服务器需要执行额外的步骤,因为系统必须安全地将数据分区从已停用的服务器迁移出去。由于 Kubernetes StatefulSet 会从最高索引到最低索引移除 pod,因此您必须先以最高索引的非根服务器为目标进行移除。

如需缩容服务器数量,请执行以下步骤:

  1. 列出您可用区中的服务器,以确定可移除的候选服务器:

    spanner deployment servers list \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    输出示例:

    NAME                                                          HOST                        PORT_BASE  ROOT  STATE
    zones/us-central1-a/servers/spanner-a-0.pod.spanner-ns:15000  spanner-a-0.pod.spanner-ns  15000      true  -
    zones/us-central1-a/servers/spanner-a-1.pod.spanner-ns:15000  spanner-a-1.pod.spanner-ns  15000      -     -
    

    删除已停用的非根服务器(索引最高),例如 spanner-a-1.pod.spanner-ns:15000:

    spanner deployment servers delete SERVER_NAME \
      --zone=ZONE \
      --deployment-endpoint=ENDPOINT
    

    将 SERVER_NAME 替换为服务器标识符,例如 spanner-a-1.pod.spanner-ns:15000。

    检查服务器列表,直到目标服务器从列表中移除。 删除后,服务器在系统中转换为不健康状态,并从有效服务路径中移除。

  2. 运行 Helm 升级命令,将 Helm 部署缩容到目标副本数。例如,如需将每个可用区的副本数减少到 1 个 pod,请运行以下命令:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set deployment.replicasPerZone=REPLICAS \
      -n NAMESPACE
    

    将 REPLICAS 替换为更新后的副本数量,例如 1。

  3. 删除与已移除的 pod 关联的 Kubernetes 永久性卷声明 (PVC)。为防止意外丢失数据,在缩减 StatefulSet 时,Helm 和 Kubernetes 不会自动删除 PVC。手动删除 PVC 以完全回收存储空间:

    kubectl delete pvc LOGS_PVC DATA_PVC -n NAMESPACE
    

    例如,如需删除命名空间 spanner-ns 中 spanner-a-1 的日志和数据卷,请执行以下操作:

    kubectl delete pvc logs-volume-spanner-a-1 data-volume-spanner-a-1 -n spanner-ns
    

添加区域

向部署中添加新可用区可提高可用性,并保护数据库免受单可用区中断的影响。

例如,以下命令会在 us 区域的 us-east1-b 可用区中初始化 Google Kubernetes Engine (GKE) 上正在运行的单可用区部署:

helm upgrade --install spanner-omni HELM_CHART_PATH \
  --version VERSION \
  --set resources.cpu=2 \
  --set resources.memory=8Gi \
  --set global.platform=gke \
  --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
  -n NAMESPACE

执行以下步骤,将可用区 us-east1-c 添加到此配置中:

  1. 运行 helm upgrade 命令并传递包含新位置区域的更新后的 JSON 代码块,以在新可用区中启动 pod:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"},{"name":"us-east1-c","shortName":"east-c"}]}]' \
      -n NAMESPACE
    
  2. 使用 Spanner Omni CLI 添加新可用区。等待新创建的可用区中的根服务器 pod 进入 Running 和就绪状态。然后,执行可用区创建命令:

    spanner deployment zones create NEW_ZONE \
      --location=LOCATION \
      --root-servers=ROOT_SERVERS_LIST \
      --deployment-endpoint=ENDPOINT
    

    替换以下内容:

    • NEW_ZONE:要添加的可用区的标识符,例如 us-east1-c。
    • LOCATION:部署位置,例如 us。
    • ROOT_SERVERS_LIST:新可用区中根服务器端点的英文逗号分隔列表,例如 spanner-east-c-0.pod.spanner-ns:15000,spanner-east-c-1.pod.spanner-ns:15000,spanner-east-c-2.pod.spanner-ns:15000。
    • ENDPOINT:外部部署端点,例如 ${ENDPOINT}:15000。
  3. 等待区域创建完成。将现有数据库架构和表复制到新可用区需要时间。通过列出部署可用区来监控可用区同步的进度:

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    

移除区域

您可以从多可用区部署中停用某个有效可用区,以减少资源或适应拓扑变更。

执行以下步骤,移除上一部分中创建的区域 us-east1-c:

  1. 删除可用区,并在 Spanner Omni 中启动可用区拆除:

    spanner deployment zones delete ZONE --deployment-endpoint=ENDPOINT
    

    将 ZONE 替换为要移除的可用区,例如 us-east1-c。

  2. 验证可用区是否已移除。运行列表命令,并等待直到输出中不再显示相应可用区:

    spanner deployment zones list --deployment-endpoint=ENDPOINT
    
  3. 运行 helm upgrade 命令并传递一个排除了已移除的可用区的更新后的位置 JSON 代码块,以从 Kubernetes 集群中移除服务器:

    helm upgrade spanner-omni HELM_CHART_PATH \
      --version VERSION \
      --reuse-values \
      --set-json 'locations=[{"name":"us","zones":[{"name":"us-east1-b","shortName":"east-b"}]}]' \
      -n NAMESPACE
    

扩缩存储空间

由于 Kubernetes volumeClaimTemplates 是不可变的,因此您无法直接使用 helm upgrade 命令来扩容 pod 存储容量。您必须改为手动扩展卷。如需了解详情,请参阅 GKE StatefulSet 卷扩展指南。

如需扩充磁盘存储空间,请执行以下步骤:

  1. 在终端中将扩充卷的参数定义为环境变量:

    NEW_SIZE="NEW_SIZE"
    NAMESPACE="NAMESPACE"
    RELEASE_NAME="spanner-omni"
    STATEFULSET_NAMES="STATEFULSET_NAME_1 STATEFULSET_NAME_2 STATEFULSET_NAME_3"
    HELM_CHART_PATH="HELM_CHART_PATH"
    VERSION="VERSION"
    

    替换以下内容:

    • NEW_SIZE:目标存储容量大小,例如 200Gi。
    • NAMESPACE:Kubernetes 命名空间,例如 spanner-ns。
    • STATEFULSET_NAME_1、STATEFULSET_NAME_2、…:部署中的 StatefulSets 的名称,通常对应于可用区的简称(例如 spanner-east-b spanner-east-c)。
    • HELM_CHART_PATH:Helm 图表的路径,例如 oci://us-docker.pkg.dev/spanner-omni/charts/spanner-omni。
    • VERSION:Helm 图表的版本,例如 1.0.0。
  2. 运行命令以修补 PVC、删除 StatefulSet(保持后端 pod 不变)并升级 Helm 部署:

    # Patch all associated PVCs directly.
    for pvc in $(kubectl get pvc -n $NAMESPACE \
      -l app.kubernetes.io/instance=$RELEASE_NAME \
      -o name | grep "data-volume"); do
      kubectl patch $pvc -n $NAMESPACE -p "{\"spec\":{\"resources\":{\"requests\":{\"storage\":\"$NEW_SIZE\"}}}}"
    done
    
    # Delete the StatefulSet while leaving backend pods intact (orphan cascade).
    kubectl delete statefulset $STATEFULSET_NAMES -n $NAMESPACE --cascade=orphan
    
    # Run Helm upgrade to align the templates with the expanded size.
    helm upgrade $RELEASE_NAME $HELM_CHART_PATH \
      --version $VERSION \
      --reuse-values \
      --set storage.data.size=$NEW_SIZE \
      -n $NAMESPACE
    

后续步骤