云原生事件驱动弹性转码方案解析

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 弹性伸缩组件是架构师在Kubernetes中设计可伸缩架构的重要依托,传统的容器水平伸缩(HPA)是基于指标类型的,具有概念模型简洁,使用简单等特点。但是这种基于阈值的弹性伸缩方式,在面对秒级的弹性时延要求时,就显得力不心。本文会结合一个事件驱动转码业务来给大家介绍下ACK在事件驱动弹性场景下的解决方案。

背景

在容器技术普及之前,事件驱动在数据库领域中被广泛使用。这个概念模型很简单:每当添加、更改或删除数据时,会触发一个事件来执行各种操作。事件驱动的方式可以在非常短的时延内,完成后续动作的执行。事件驱动架构的核心是对系统上的各种事件做出反应并执行相应的动作。弹性伸缩已成为几乎所有云平台中不可或缺的组成部分。Kubernetes中,容器水平伸缩器HPA(Horizontal Pod Autoscaler)是最常用的应用弹性方案。容器水平伸缩的核心是基于资源利用率与预设的阈值水位之间的关系,来确认伸缩的计划。容器水平伸缩的方式具有使用简单、资源指标丰富等特点,但是它对于需要即时弹性的场景,尤其是对基于事件源进行离线作业支撑不足。ACK提供了ack-keda来提供事件驱动弹性能力,事件驱动弹性适用于音视频离线转码、事件驱动作业、流式数据处理等场景。

事件驱动弹性原理

ACK通过增强版本的ack-keda来提供事件驱动弹性能力,下图是ack-keda的基本原理。
image.png
ack-keda会从事件源中进行数据的周期性消费。当消息出现堆积,即可秒级触发一个批次的离线任务伸缩。下一个周期到来时,会异步进行下一个批次的作业伸缩。ack-keda具有以下特性:

  • 丰富的事件源
    ack-keda内置支持Kafka、MySQL、PostgreSQL、Rabbitmq、Redis等多种内置数据源。同时支持从客户自定义的事件源获取事件并进行Job或者pod维度的弹性缩放。
  • 离线任务的并发控制
    对于大规模的离线作业而言,底层管控的稳定性会面临比较大的挑战,需要提供资源、额度、API请求的整体控制。ack-keda提供了单批次、总批次的任务并发控 制,保障系统的稳定性。
  • 结束任务后自动清理元数据&&支持任务回溯
    大规模离线作业执行完毕后,会留存大量的元数据信息。元数据信息的堆积会造成APIServer的稳定性下降,造成集群的性能下降、稳定性不足,甚至可能影响其 他的业务。ack-keda会在任务执行结束后自动清理元数据,降低元数据的量级。同时,ack-keda也支持保留一些执行失败的Job,便于回溯,定位原因。

事件驱动弹性转码案例

在本案例中,我们准备一个简单的转码作业,当有一个新任务到来的时候会向mongoDB插入一条类似下面的数据{"type":"mp4","state":"waiting","createTimeStamp":"1610332940","fileName":"World and peace","endTimeStamp":"","uuid":"1fae72ff-3239-42f5-af97-04711d8007e8"},此时,容器服务的事件驱动控制器会从数据库中查询到状态为"state":"waiting"的作业,弹出与任务数目匹配的Job Pod来承载转码作业,完成转码业务并将数据中的state字段从之前的waiting修改成finished。同时Job完成后,自动清理,降低元数据对APIServer带来的压力,极大的减轻开发者的负担。

1.安装事件驱动弹性控制器 - ack-keda

  • 登录阿里云容器服务kubernetes控制台,点击左侧边栏的应用市场,搜索ack-keda
    image.png
  • 选择对应集群,点击部署,部署到该集群
    image.png
  • 选择左侧边栏的工作负载,选择无状态服务,选择kube-system 命名空间,确认ack-keda部署成功
    image.png

2.部署基于mongoDB事件源驱动弹性示例

1.部署mongoDB

  • 创建mongoDB.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mongodb
  template:
    metadata:
      labels:
        name: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:4.2.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 27017
          name: mongodb
          protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
  name: mongodb-svc
spec:
  type: ClusterIP
  ports:
  - name: mongodb
    port: 27017
    targetPort: 27017
    protocol: TCP
  selector:
    name: mongodb
  • 执行kubectl apply -f mongoDB.yaml -n mongodb部署到集群。

2.mongoDB新建User

// 新建用户
kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.createUser({ user:"test_user",pwd:"test_password",roles:[{ role:"readWrite", db: "test"}]})'
// 登陆认证
kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval  'db.auth("test_user","test_password")'
// 新建collection
kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval  'db.createCollection("test_collection")'

3.部署TriggerAuthentication和ScaledJob

  • 创建TriggerAuthentication

TriggerAuthentication是用来登录mongoDB查询数据时认证使用,TriggerAuthentication中的secretTargetRef字段会将指定Secret中的数据读取到ack-keda中,完成对Mongo的登录认证。

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: mongodb-trigger
spec:
  secretTargetRef:
    - parameter: connectionString
      name: mongodb-secret
      key: connect
---
apiVersion: v1
kind: Secret
metadata:
  name: mongodb-secret
type: Opaque
data:
  connect: bW9uZ29kYjovL3Rlc3RfdXNlcjp0ZXN0X3Bhc3N3b3JkQG1vbmdvZGItc3ZjLm1vbmdvZGIuc3ZjLmNsdXN0ZXIubG9jYWw6MjcwMTcvdGVzdA==
  • 执行kubectl apply -f auth.yaml -n mongodb-test到集群。
  • 创建ScaledJob

ScaledJob主要用来配置Job模板以及指定查询的数据库及查询表达式等,这里我们配置的是从test数据库中的test_collection中,查询满足{"type":"mp4","state":"waiting"}的待转码数据。

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: mongodb-job
spec:
  jobTargetRef:
    // Job模板配置
    template:
      spec:
        containers:
          - name: mongo-update
            image: registry.cn-hangzhou.aliyuncs.com/carsnow/mongo-update:v6
            args:
              - --connectStr=mongodb://test_user:test_password@mongodb-svc.mongodb.svc.cluster.local:27017/test
              - --dataBase=test
              - --collection=test_collection
            imagePullPolicy: IfNotPresent
        restartPolicy: Never
    backoffLimit: 1
  pollingInterval: 15
  maxReplicaCount: 5
  successfulJobsHistoryLimit: 0
  failedJobsHistoryLimit: 10
  triggers:
    - type: mongodb
      metadata:
        dbName: test                                        //要查询的数据库
        collection: test_collection                //要查询的collection
        query: '{"type":"mp4","state":"waiting"}'  //会对查询转码类型为mp4且状态是waiting的数据拉起job进行处理
        queryValue: "1"
      authenticationRef:
        name: mongodb-trigger
  • 执行kubectl apply -f scaledJob.yaml -n mongodb-test到集群。

4.插入待转码业务数据

// 插入5条待转码数据
kubectl exec -n mongodb mongodb-xxxxx -- mongo --eval 'db.test_collection.insert([
  {"type":"mp4","state":"waiting","createTimeStamp":"1610352740","fileName":"My Love","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"},
  {"type":"mp4","state":"waiting","createTimeStamp":"1610350740","fileName":"Harker","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d8007e8"},
  {"type":"mp4","state":"waiting","createTimeStamp":"1610152940","fileName":"The World","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d87767e8"},
  {"type":"mp4","state":"waiting","createTimeStamp":"1610390740","fileName":"Mother","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04799d8007e8"},
  {"type":"mp4","state":"waiting","createTimeStamp":"1610344740","fileName":"Jagger","endTimeStamp":"","uuid":"1gae72ff-3239-42f5-af97-04711d80099e8"},
  ])'

5.查看Job动态

// watch job
watch -n 1 kubectl get job -n mongodb-test

image.png
可以看到成功扩展出5个Job。此时再登录数据库,观察转码业务状态,可以看到数据状态已经从waiting变成了finished
image.png

写在最后

本文介绍的转码业务实际也是我们在日常场景经常会遇到的一个需求,看得出来ack-keda的使用,相对来说还是比较容易的,而且实际效果也能满足我们日常的需求。我们最近在keda社区的基础上,新增了对于mongoDB事件源的支持,并已PR到社区,至此,内置的事件源已经能够满足我们绝大部分事件驱动场景。如果您想了解更多,请点击查看keda社区

相关文章
|
18天前
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
4天前
|
边缘计算 Cloud Native 数据管理
【阿里云云原生专栏】云原生背景下的AIoT布局:阿里云Link平台解析
【5月更文挑战第29天】阿里云Link平台,作为阿里云在AIoT领域的核心战略,借助云原生技术,为开发者打造一站式物联网服务平台。平台支持多协议设备接入与标准化管理,提供高效数据存储、分析及可视化,集成边缘计算实现低延时智能分析。通过实例代码展示,平台简化设备接入,助力智能家居等领域的创新应用,赋能开发者构建智能生态系统。
33 3
|
4天前
|
域名解析 Kubernetes 网络协议
【域名解析DNS专栏】云原生环境下的DNS服务:Kubernetes中的DNS解析
【5月更文挑战第29天】本文探讨了Kubernetes中的DNS解析机制,解释了DNS如何将服务名转换为网络地址,促进集群内服务通信。Kubernetes使用kube-dns或CoreDNS作为内置DNS服务器,每个Service自动分配Cluster IP和DNS条目。通过示例展示了创建Service和使用DNS访问的流程,并提出了优化DNS解析的策略,包括使用高性能DNS解析器、启用DNS缓存及监控日志,以实现更高效、可靠的DNS服务。
|
7天前
|
弹性计算 安全 微服务
【阿里云云原生专栏】容器网络技术前沿:阿里云Terway网络方案详解
【5月更文挑战第26天】阿里云Terway是高性能的容器网络方案,基于ECS的ENI实现,提供低延迟高吞吐的网络服务。它简化网络管理,实现安全隔离,并与阿里云服务无缝集成。Terway由CNI、Node和Controller组成,适用于微服务、混合云和多租户环境,为企业数字化转型中的复杂网络需求提供强大支持。
162 1
|
9天前
|
存储 弹性计算 人工智能
【阿里云弹性计算】深度解析阿里云ECS弹性裸金属服务器:性能与弹性的完美平衡
【5月更文挑战第24天】阿里云ECS弹性裸金属服务器融合物理机高性能与云服务弹性,提供计算、存储及网络优势。支持秒级伸缩、自动扩展,适用于高性能计算、游戏、企业应用及AI场景。示例代码展示如何通过CLI创建实例,是高需求场景的理想选择。
62 0
|
10天前
|
消息中间件 监控 Cloud Native
【阿里云云原生专栏】事件驱动架构在阿里云云原生生态中的角色与实施路径
【5月更文挑战第23天】本文探讨了事件驱动架构在阿里云云原生生态中的关键作用,强调其在微服务协同和应用创新中的效率提升。阿里云提供了EventBridge和EventMesh等服务支持EDA,其中EventBridge作为事件中枢,实现跨平台事件传递,而EventMesh提供高性能事件处理。通过事件模型设计、服务集成、开发处理器和监控优化四个步骤,用户可在阿里云上实施事件驱动架构,构建敏捷响应的云原生应用。随着云原生技术发展,EDA将成为企业数字化转型的重要推动力。
50 0
|
13天前
|
存储 弹性计算 Kubernetes
【阿里云云原生专栏】深入解析阿里云Kubernetes服务ACK:企业级容器编排实战
【5月更文挑战第20天】阿里云ACK是高性能的Kubernetes服务,基于开源Kubernetes并融合VPC、SLB等云资源。它提供强大的集群管理、无缝兼容Kubernetes API、弹性伸缩、安全隔离及监控日志功能。用户可通过控制台或kubectl轻松创建和部署应用,如Nginx。此外,ACK支持自动扩缩容、服务发现、负载均衡和持久化存储。多重安全保障和集成监控使其成为企业云原生环境的理想选择。
174 3
|
18天前
|
JSON Java Maven
Javaweb之SpringBootWeb案例之自动配置以及常见方案的详细解析
Javaweb之SpringBootWeb案例之自动配置以及常见方案的详细解析
14 0
Javaweb之SpringBootWeb案例之自动配置以及常见方案的详细解析
|
18天前
|
canal 消息中间件 关系型数据库
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
114 0
|
18天前
|
安全 数据安全/隐私保护 虚拟化
iOS应用加固方案解析:ipa加固安全技术全面评测
iOS应用加固方案解析:ipa加固安全技术全面评测
50 3

推荐镜像

更多