YugabyteDB 架构
如下图架构图所示,YugabyteDB 由两种分布式服务组成。
- YB-Master:负责保存系统元数据(如分片到节点的映射),协调系统范围的操作(如创建/更改删除表),并启动维护操作(如负载平衡)。它会持续监控和重新平衡可用节点之间的数据分片,即使在 Kubernetes 集群等高度动态的环境中也是如此。出于容错目的,YB-Master 的数量等于集群的复制因子 (RF)。容错所需的小 RF 为 3。
- YB-TServer:负责在分片(也称为平板电脑)中托管/提供用户数据的数据节点。集群中的数据节点数量可以按需增加或减少。
YugabyteDB 集群架构
将 YugabyteDB 建模为 Kubernetes 上的工作负载
使用 Kubernetes 编排有状态应用程序强调了在 Kubernetes 中运行有状态应用程序(例如数据库)如何需要使用StatefulSets 工作负载 API。在这种情况下,YB-Master 和 YB-TServer 被建模为独立的 StatefulSet,如Github 上的YugabyteDB Kubernetes YAML所示。这些 StatefulSet pod 中的每一个都实例化同一yugabytedb/yugabyte
容器映像的一个实例,但用于启动容器的命令会根据所需的服务器类型进行更改。接下来的几节详细介绍了在 Kubernetes 上运行四节点 RF3 集群的上下文中 YugabyteDB StatefulSet 的结构。
在 Kubernetes 上运行 YB-Master
Kubernetes 上的 YB-Master 部署需要一个 StatefulSet 和两个 Service。这些服务之一是能够发现底层 StatefulSet pod 的Headless服务,另一个是查看 YB-Master 管理 UI 所需的 LoadBalancer 服务。YugabyteDB 管理客户端(例如 YugabyteDB EE 管理控制台)使用 headless 服务连接到任何 pod,而管理员用户可以连接到 LoadBalancer 服务。
Kubernetes 上的 YB-Master
yb-master StatefulSet
所述YugabyteDB Kubernetes YAML具有用于YB-主StatefulSet的截面。规范中需要强调的几点。
副本数
如上图所示,使用 RF3 设置一个 4 节点的 YugabyteDB 集群,只需要 3 个 yb-master StatefulSet pod。因此,副本的 YAML 设置为 3。
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: yb-master
标签:
app: yb-master
spec:
serviceName: yb-masters
podManagementPolicy: "Parallel"
replicas: 3
Pod 反亲和性
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- yb-master
Pod 反关联规则用于确保不能将两个 yb-master Pod 调度到同一个 Kubernetes 节点上。这可以实现大的容错能力,因为单个节点故障只会影响一个 yb-master pod,即使其余两个 yb-master pod 位于其他两个节点上,集群也将继续正常运行。此外,正如 Kubernetes 文档中所述,这preferredDuringSchedulingIgnoredDuringExecution
是Kubernetes的软保证,更适合requiredDuringSchedulingIgnoredDuringExecution
在生产等关键任务环境中使用。
与其他yb-masters交流
command:
- "/home/yugabyte/bin/yb-master"
- "--fs_data_dirs=/mnt/data0"
- "--rpc_bind_addresses=$(POD_IP)"
- "--master_addresses=yb-masters.default.svc.cluster.local:7100"
- "--master_replication_factor=3"
每个 yb-master 通过使用yb-masters
Headless服务的完全限定端点填充 –master_addresses 标志来了解其他 yb-master yb-masters.default.svc.cluster.local:7100
(参见下一节)。
端口
ports:
- containerPort: 7000
name: master-ui
- containerPort: 7100
name: master-rpc
其他 yb-masters 和 yb-tservers 通信的 rpc 端口是,7100
而用于检查 master 当前状态的 UI 端口是7000
。
卷挂载
volumeMounts:
- name: datadir
mountPath: /mnt/data0
…
volumeClaimTemplates:
- metadata:
name: datadir
--fs_data_dirs
命令中的标志指向/mnt/data0
使用datadir
卷挂载挂载到容器的同一个磁盘。
更新策略
updateStrategy:
type: RollingUpdate
该RollingUpdate
策略将按照相反的顺序更新 yb-master StatefulSet 中的所有 pod,同时尊重 StatefulSet 保证。
yb-masters Headless服务
Kubernetes StatefulSets 需要使用Headless服务,以便 StatefulSet pod 可以单独发现并由其他服务(例如客户端应用程序)直接通信。Kubernetes 不负责这些 pod 之间的任何负载平衡。通过简单地将服务的 clusterIP 指定为None
.
apiVersion: v1
kind: Service
metadata:
name: yb-masters
labels:
app: yb-master
spec:
clusterIP: None
ports:
- name: ui
port: 7000
- name: rpc-port
port: 7100
selector:
app: yb-master
如上图,yb-masters headless service yaml极其简单。它只是打开底层 yb-master pod 的 UI 和 rpc 端口。
yb-master-ui LoadBalancer 服务
apiVersion: v1
kind: Service
metadata:
name: yb-master-ui
labels:
app: yb-master
spec:
clusterIP:
ports:
- name: ui
port: 7000
selector:
app: yb-master
type: LoadBalancer
可以在7000
任何 yb-master的端口上查看 yb-master 的集群范围管理 UI 。该yb-master-ui
服务属于LoadBalancer
此端口的类型,这意味着该服务将在所有底层 pod 之间对所有传入请求进行负载平衡。
在 Kubernetes 上运行 YB-TServer
假设您不需要查看 YB-TServer 的管理 UI,YB-TServer Kubernetes 部署需要一个 StatefulSet 和一个Headless服务。需要注意的重要一点是,YB-Master 服务必须在 YB-TServer 服务之前启动并运行。
Kubernetes 上的 YB-TServer 和 YB-Master
yb-tserver StatefulSet
YugabyteDB Kubernetes YAML 有一个用于 yb-master StatefulSet 的部分。规范中需要强调的几点。
副本数
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: yb-tserver
labels:
app: yb-tserver
spec:
serviceName: yb-tservers
podManagementPolicy: "Parallel"
replicas: 4
如上图所示,要使用 RF3 设置一个 4 节点的 YugabyteDB 集群,需要 yb-master StatefulSet pod 的 4 个副本。
Pod 反亲和性
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- yb-tserver
Pod 反关联规则用于确保不能将两个 yb-tserver Pod 调度到同一个 Kubernetes 节点上。这可以强制实现大容错,因为单个节点故障只会影响一个 yb-tserver pod,并且只要 yb-tserver pod 的法定人数可用,集群就会继续正常运行。请注意,1 个 yb-tserver pod 和 1 个 yb-master pod 可以位于同一节点上。再次如 yb-masters 部分所述,更强的保证requiredDuringSchedulingIgnoredDuringExecution
更适合关键任务环境。
与yb-masters的交流
Command:
- "/home/yugabyte/bin/yb-tserver"
- "--fs_data_dirs=/mnt/data0"
- "--tserver_master_addrs=yb-masters.default.svc.cluster.local:7100"
- "--tserver_master_replication_factor=3"
每个 yb-tserver--tserver_master_addrs
通过使用 yb-masters headless service 的完全限定端点填充的标志来了解其他 yb-master yb-masters.default.svc.cluster.local:7100
。
端口
ports:
- containerPort: 9000
name: tserver-ui
- containerPort: 9100
name: tserver-rpc
- containerPort: 9042
name: cassandra
- containerPort: 6379
name: redis
yb-masters 和其他 yb-tservers 通信的 rpc 端口是,9100
而用于检查 tserver 当前状态的 UI 端口是9000
. 此外,YCQL(Cassandra 兼容 API)在端口可用,9042
YEDIS(Redis 兼容 API)在端口可用6379
。PostgreSQL API 目前处于测试阶段,可以通过添加端口来启用5433
。
卷挂载
volumeMounts:
- name: datadir
mountPath: /mnt/data0
…
volumeClaimTemplates:
- metadata:
name: datadir
该--fs_data_dirs
标志指向使用 datadir 卷挂载挂载到容器的同一个磁盘 /mnt/data0。
更新策略
updateStrategy:
type: RollingUpdate
该RollingUpdate
更新策略将更新YB-TSERVER StatefulSet所有的吊舱,以相反的顺序顺序,同时尊重StatefulSet保证。
yb-tservers Headless服务
apiVersion: v1
kind: Service
metadata:
name: yb-tservers
labels:
app: yb-tserver
spec:
clusterIP: None
ports:
- name: ui
port: 9000
- name: rpc-port
port: 9100
- name: cassandra
port: 9042
- name: redis
port: 6379
selector:
app: yb-tserver
正如预期的那样,yb-tservers Headless服务 yaml 非常简单。它打开了底层 yb-tserver pod 的 UI、rpc 端口以及客户端 API 端口。
Kubernetes 上的 YugabyteDB 实战
为了让事情变得简单易懂,我们就会对4个节点的集群YugabyteDB minikube,对当地的环境中运行Kubernetes的方法。
先决条件
如果您还没有安装 minikube 和 kubectl,请按照说明安装它们。
步骤 1 – 下载 YugabyteDB Kubernetes YAML
mkdir ~/yugabyte && cd ~/yugabyte
wget https://raw.githubusercontent.com/YugaByte/yugabyte-db/master/cloud/kubernetes/yugabyte-statefulset.yaml
步骤 2 – 将 yb-tserver 副本数从 3 更改为 4
在您选择的编辑器中打开 YAML,并将 yb-tserver 副本计数设置为 4。
spec:
serviceName: yb-tservers
podManagementPolicy: "Parallel"
replicas: 4
步骤 3 – 创建数据库集群
现在您可以通过以下命令创建 YugabyteDB 集群。
kubectl apply -f yugabyte-statefulset.yaml
步骤 4 – 检查 Pod 和服务的状态
由于 Kubernetes 必须首先从 http://hub.docker.com 拉取 yugabytedb/yugabyte 映像,因此集群可能需要几分钟才能生效。您可以使用以下命令检查状态。
kubectl get pods
NAME READY STATUS RESTARTS AGE
yb-master-0 0/1 ContainerCreating 0 7s
yb-master-1 0/1 ContainerCreating 0 7s
yb-master-2 0/1 ContainerCreating 0 7s
yb-tserver-0 0/1 ContainerCreating 0 7s
yb-tserver-1 0/1 ContainerCreating 0 7s
yb-tserver-2 0/1 ContainerCreating 0 7s
yb-tserver-3 0/1 ContainerCreating 0 7s
当集群准备好时,它将拥有所有 7 个 pod(3 个用于 yb-master,4 个用于 yb-tserver)处于 Running 状态。
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 7m
yb-master-1 1/1 Running 0 7m
yb-master-2 1/1 Running 0 7m
yb-tserver-0 1/1 Running 0 7m
yb-tserver-1 1/1 Running 0 7m
yb-tserver-2 1/1 Running 0 7m
yb-tserver-3 1/1 Running 0 7m
您还可以检查我们启动的 3 个服务的状态以及默认 kubernetes 服务本身的状态。
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 10m
yb-master-ui LoadBalancer 10.102.121.64 7000:31283/TCP 8m
yb-masters ClusterIP None 7000/TCP,7100/TCP 8m
yb-tservers ClusterIP None 9000/TCP,9100/TCP,9042/TCP,6379/TCP 8m
后,您可以查看 Kubernetes 提供的漂亮的 UI 仪表板,您可以通过以下命令启动它。
minikube dashboard
安装了 YugabyteDB 的 Kubernetes 仪表板
步骤 5 – 查看 YB-Master 管理界面
集群上线后,您可以启动 YB-Master Admin UI。首先使用下面的命令获取 UI 的确切 URL,然后通过浏览器启动 URL。
minikube service yb-master-ui --url
http://192.168.99.100:31283
YB-Master 管理界面
步骤 6 – 执行第 2 天的操作任务
接下来的几个步骤展示了如何执行常见的第 2 天操作任务,例如添加/删除节点和执行滚动升级。所有这些操作都不会影响客户端应用程序的可用性和性能,从而允许应用程序继续正常运行。
添加节点
使用 YugabyteDB 和 Kubernetes,水平扩展轻而易举,这个过程再简单不过了。我们所要做的就是让 Kubernetes 知道要扩展到多少副本。
kubectl scale statefulset yb-tserver --replicas=5
statefulset "yb-tserver" scaled
现在我们可以检查缩放操作的状态。请注意,YugabyteDB 会自动将一些 tablet-leader 和一些 tablet-follower 移动到新添加的节点中,以便集群在所有节点之间保持平衡。
kubectl get pods
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 4h
yb-master-1 1/1 Running 0 4h
yb-master-2 1/1 Running 0 4h
yb-tserver-0 1/1 Running 0 4h
yb-tserver-1 1/1 Running 0 4h
yb-tserver-2 1/1 Running 0 4h
yb-tserver-3 1/1 Running 0 4h
yb-tserver-4 1/1 Running 0 1m
删除两个节点
删除节点也很简单。减少副本数量,剩下的工作由 Kubernetes 和 YugabyteDB 的组合完成。kubectl scale statefulset yb-tserver --replicas=3
statefulset "yb-tserver" scaled
正如在 StatefulSets 中预期的那样,我们可以看到具有大序数索引(即 4 和 3)的节点首先被删除。
kubectl get pods
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 4h
yb-master-1 1/1 Running 0 4h
yb-master-2 1/1 Running 0 4h
yb-tserver-0 1/1 Running 0 4h
yb-tserver-1 1/1 Running 0 4h
yb-tserver-2 1/1 Running 0 4h
yb-tserver-3 0/1 Terminating 0 4h
yb-tserver-4 0/1 Terminating 0 2m
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 4h
yb-master-1 1/1 Running 0 4h
yb-master-2 1/1 Running 0 4h
yb-tserver-0 1/1 Running 0 4h
yb-tserver-1 1/1 Running 0 4h
yb-tserver-2 1/1 Running 0 4h
执行滚动升级
我们还可以对 YugabyteDB 集群执行滚动升级。这涉及首先在 yb-master StatefulSet 上,然后在 yb-tserver StatefulSet 上将 YugabyteDB 容器映像更改为不同的版本。正如在 StatefulSets 中预期的那样,我们可以看到具有大序数索引的节点首先升级。
升级 yb-master StatefulSet 使用以下命令。假设新的容器镜像还没有在 Kubernetes 中可用,镜像将首先从 http://hub.docker.com 拉取,这可能导致个 pod 升级需要几分钟。
kubectl patch statefulset yb-master --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"yugabytedb/yugabyte:1.0.4.0-b24"}]'
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 17h
yb-master-1 1/1 Running 0 17h
yb-master-2 1/1 Terminating 0 17h
yb-tserver-0 1/1 Running 0 17h
yb-tserver-1 1/1 Running 0 17h
yb-tserver-2 1/1 Running 0 17h
NAME READY STATUS RESTARTS AGE
yb-master-0 1/1 Running 0 6s
yb-master-1 1/1 Running 0 46s
yb-master-2 1/1 Running 0 4m
yb-tserver-0 1/1 Running 0 17h
yb-tserver-1 1/1 Running 0 17h
yb-tserver-2 1/1 Running 0 17h
现在我们也可以升级 yb-tserver StatefulSet。这将导致 yb-tserver pod 以与 yb-master pod 相同的方式升级。
kubectl patch statefulset yb-tserver --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"yugabytedb/yugabyte:1.0.4.0-b24"}]'
概括
使用分布式编排技术(例如 Kubernetes)运行分布式数据库仍然是一个重要的问题。YugabyteDB 是一个分布式数据库,具有独特的分片和复制架构,非常适合基于 Kubernetes 的编排。在这篇博文中,我们回顾了 YugabyteDB 如何在 Kubernetes 上运行的底层细节,以及它在真实集群环境中的运行情况。作为即将发布的 1.1 版本的一部分,我们希望发布更多与 Kubernetes 相关的增强功能,例如在与 YugabyteDB 相同的 Kubernetes 集群上运行 YugabyteDB Enterprise Admin Console。在本页底部订阅我们的博客,并随时关注我们的进展。
原文链接:https://zhuanlan.zhihu.com/p/388704848