使用Kubernetes竞争消费者模式扩展任务处理 - vinsguru


在分布式系统中,我们通过通过服务总线/消息队列传递消息来实现系统之间的松散耦合。有时,当消息的发送量很高时(即每单位时间传入的消息数大于每单位时间处理的消息数),队列最终将容纳无限数量的消息。消息队列最终可能会由于内存不足错误而失败,并且客户端可能永远不会收到其已发送消息的响应!为避免这种情况,我们通常以最多流量来计划N台服务器,但是如果这么多服务器很少接收处理任何消息,则最终需要为这些未使用的服务器付费。
具有成本效益的解决方案将是自动缩放!这个概念并不新鲜。在本文中,我们将基于Kubernetes集群中的CPU使用率来扩展/扩展消息消费者。这样,当1台服务器努力处理所有消息时,我们带来了更多服务器以加快处理速度,以减少单台服务器上的负载并平衡工作量。
 
案例
将重用我们之前在这里使用过的应用程序。checkout出来以更好地理解。


    • 我们的应用程序将在请求到达时将一些任务放入消息队列中。
    • 任务将在斐波那契数列中找到第N个位置!我将使用2 ^ N算法使过程非常缓慢。
    • 将有一些类别,如低,高,紧急来对任务进行优先级排序。显然,应该首先执行紧急任务!
    • 任务执行器是使用消息的消息处理器。默认情况下,我们将有1个消息处理器启动并始终运行。
      • 但是有时1个节点可能还不够。
      • 根据CPU利用率,我们的自动缩放器会弹出更多Pod。


优点:
这种方法有几个优点。
  • 生产者和消费者之间的松散耦合。
  • 我们可以根据需求动态扩展或扩展。(在本文中,我们使用CPU利用率。我们也可以根据队列中的消息计数使用)
  • 可靠
  • 负载均衡。单个服务器不负责处理所有消息。负载分布在多个消息处理器/消费者之间。

 
Kubernetes资源
  • 我们将创建如图所示的资源。

 

  • Redis配置:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: redis-master
      name: redis-master
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis-master
      template:
        metadata:
          labels:
            app: redis-master
        spec:
          containers:
          - image: redis
            name: redis-master
            ports:
            - containerPort: 6379
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: redis-master
      name: redis-master
    spec:
      ports:
      - name: redis-port
        port: 6379
        protocol: TCP
        targetPort: 6379
      selector:
        app: redis-master
      type: ClusterIP

  • 任务调度器
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: task-scheduler
      name: task-scheduler
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: task-scheduler
      template:
        metadata:
          labels:
            app: task-scheduler
        spec:
          containers:
          - image: vinsdocker/task-scheduler
            name: task-scheduler
            env:
            - name: REDIS_HOST
              value: redis-master
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: task-scheduler
      name: task-scheduler
    spec:
      ports:
      - name: task-scheduler
        port: 8080
        protocol: TCP
        targetPort: 8080
        nodePort: 32001
      selector:
        app: task-scheduler
      type: NodePort
  • 任务执行者
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: task-executor
      name: task-executor
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: task-executor
      template:
        metadata:
          labels:
            app: task-executor
        spec:
          containers:
          - image: vinsdocker/task-executor
            name: task-executor
            env:
            - name: REDIS_HOST
              value: redis-master
            resources:
              requests:
                cpu: 200m
                memory: 512Mi
  • 水平Pod自动缩放器(HPA):
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: task-executor
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: task-executor
      minReplicas: 1
      maxReplicas: 3
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 50

 
资源利用率:
  • 当没有负载时,集群的CPU /内存利用率或多或少是这样的。
    NAME                              CPU(cores)   MEMORY(bytes)
    redis-master-65f7f8cf88-8tqxm     3m           2Mi
    task-executor-7dd8855487-2gzbf    4m           184Mi
    task-scheduler-86d64c5598-kd6sr   3m           192Mi
  • HPA输出如下所示(kubectl get hpa)。
    NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    task-executor   Deployment/task-executor   3%/50%    1         3         1          5m
  • 我向任务计划程序发送了数百条消息,并等待2分钟。
  • 我可以看到CPU利用率增加,任务执行程序的数量从1增加到3。
    // kubectl get hpa

    NAME            REFERENCE                  TARGETS     MINPODS   MAXPODS   REPLICAS   AGE
    task-executor   Deployment/task-executor   205%/50%    1         3         3          7m

    // kubectl top pods

    NAME                              CPU(cores)        MEMORY(bytes)
    redis-master-65f7f8cf88-8tqxm     5m                3Mi
    task-executor-7dd8855487-2gzbf    526m              176Mi
    task-executor-7dd8855487-5897f    489m              176Mi
    task-executor-7dd8855487-t8tbp    512m              179Mi
    task-scheduler-86d64c5598-kd6sr   3m                189Mi
  •  
  • 处理完消息后,请等待5分钟,然后kubernetes会扩展这些使用消费者。

成功演示基于CPU利用率的消息使用方自动扩展,以实现负载均衡,松耦合和加速消息处理。