به گزارش از وبسایت cncf 📰

در معماری‌های مبتنی بر رویداد در Kubernetes، استفاده‌ی CPU و حافظه اغلب بار واقعی سیستم را نشان نمی‌دهد. برای مثال، وقتی هزاران پیام در صف Amazon SQS انباشته شده‌اند، یک پاد worker ممکن است از منظر CPU بیکار به نظر برسد. همچنین گاهی پادها مدت‌ها پس از پایان یک جهش ترافیک به کار ادامه می‌دهند. برای بارهای کاری ناهمزمان و صف‌محور، عمق صف (backlog) سیگنال واقعی‌تری برای مقیاس‌گذاری است تا معیارهای زیرساختی سنتی.

در این مقاله خواهید آموخت چگونه عمق صف Amazon SQS می‌تواند به‌عنوان معیاری برای مقیاس خودکار کارگران رویدادمحور عمل کند ⚙️

چرا این مهم است: در سیستم‌های صف‌محور، تأخیر در پردازش پیام به‌طور مستقیم بر تجربه‌ی کاربران و سیستم‌های پایین‌دستی اثر می‌گذارد. مقیاس‌گذاری بر پایه‌ی عمق SQS موجب هم‌راستایی مقیاس‌گذاری با تقاضای واقعی می‌شود، به‌سرعت می‌تواند انفجارهای ترافیکی را مدیریت کند و هزینه‌ی بیکاری منابع را هنگام خالی بودن صف کاهش دهد.

1. پیش‌نیازها

قبل از اجرای مقیاس خودکار مبتنی بر KEDA و Amazon SQS، مطمئن شوید که دارید:
• یک خوشه‌ی Amazon EKS که نسخه‌ی پشتیبانی‌شده‌ای از Kubernetes را اجرا می‌کند و KEDA در خوشه نصب شده است (مثلاً از طریق Helm chart از kedacore).
• یک روش احراز هویت AWS انتخاب‌شده (مثل IRSA یا روش‌های مرتبط با EKS Pod Identity).
• صف‌هایی که پیام‌ها از آن‌ها مصرف می‌شوند (Amazon SQS).

2. معماری و جریان درخواست

این معماری متکی به KEDA است که معیارهای صف Amazon SQS را مشاهده می‌کند و بر اساس بک‌لاگ، یک Kubernetes Horizontal Pod Autoscaler (HPA) را مدیریت می‌کند. جریان درخواست به‌طور خلاصه: تولیدکننده‌ها پیام‌ها را به صف SQS ارسال می‌کنند، KEDA عمق صف را با poll کردن مشاهده می‌کند و بر اساس آن مقیاس را تنظیم می‌نماید.

3. مراحل پیاده‌سازی

نصب KEDA از طریق Helm — روش توصیه‌شده:

# افزودن مخزن KEDA
helm repo add kedacore https://kedacore.github.io/charts
helm repo update

# نصب KEDA در یک namespace اختصاصی
helm install keda kedacore/keda --namespace keda

این نصب اپراتور KEDA و متریک سرور را همراه با CRDهایی مثل ScaledObject و TriggerAuthentication فراهم می‌کند.

استقرار Worker با شناسه‌ی AWS پیوست‌شده — مصرف‌کننده‌ی SQS معمولاً به مجوزهایی مانند: GetQueueAttributes، GetQueueUrl، ReceiveMessage، DeleteMessage و ChangeMessageVisibility نیاز دارد. مثال خط‌مشی IAM:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ConsumeFromQueue",
      "Effect": "Allow",
      "Action": [
        "sqs:GetQueueAttributes",
        "sqs:GetQueueUrl",
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage",
        "sqs:ChangeMessageVisibility"
      ],
      "Resource": "arn:aws:sqs:us-east-1:123456789012:orders-queue"
    }
  ]
}

هدف این رویکرد اعمال اصل کمترین امتیاز (least privilege) با محدود کردن دسترسی‌ها فقط به صف مورد نیاز است.

پیکربندی KEDA: اتصال با TriggerAuthentication و ScaledObject به صف SQS. استفاده از queueURLFromEnv از hard-coding URL صف جلوگیری می‌کند. نمونه مانیفست:

apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: sqs-processor-auth
  namespace: workers
spec:
  podIdentity:
    provider: aws
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: sqs-processor
spec:
  scaleTargetRef:
    name: sqs-processor
  pollingInterval: 10
  cooldownPeriod: 120
  minReplicaCount: 0
  maxReplicaCount: 30
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          stabilizationWindowSeconds: 60
  triggers:
  - type: aws-sqs-queue
    authenticationRef:
      name: sqs-processor-auth
    metadata:
      queueURLFromEnv: QUEUE_URL
      awsRegion: us-east-1
      queueLength: "10"
      activationQueueLength: "1"

این تنظیمات نحوه‌ی احراز هویت KEDA با AWS و نحوه‌ی محاسبه‌ی تعداد کپی‌ها را مشخص می‌کند. در این مثال هر پاد هدف 10 پیام را دارد و وقتی صف خالی است، مقیاس تا صفر فعال می‌شود.

4. منطق محاسبه‌ی Replicaها

KEDA تعداد پادها را با استفاده از مجموع پیام‌های قابل مشاهده و پیام‌های درحال‌پردازش (ApproximateNumberOfMessages + ApproximateNumberOfMessagesNotVisible) محاسبه می‌کند (و در صورت فعال بودن پیام‌های تأخیری را هم لحاظ می‌کند). مثال محاسباتی: اگر صفت هدف queueLength=10 باشد، نتیجه‌ها به‌صورت زیر خواهند بود:
• 0 پیام → 0 پاد
• 8 پیام → 1 پاد
• 25 پیام → 3 پاد
• 95 پیام → 10 پاد

در نهایت تعداد محاسبه‌شده با مقادیر minReplicaCount و maxReplicaCount محدود می‌شود.

5. تأیید پس از اعمال مانیفست‌ها

مراحل پیشنهادی برای اعتبارسنجی:
1. ارسال 50 پیام به صف SQS.
2. بررسی ScaledObject: kubectl get scaledobject sqs-processor -n workers
3. پایش مقیاس‌گذاری: kubectl get pods -n workers -w

خطاهای رایج و راه‌های بررسی:

• مقیاس‌نشدن: ممکن است URL صف نادرست یا مجوزهای IAM ناقص باشد — بررسی کنید: kubectl describe scaledobject و گزارش‌های اپراتور KEDA.
• تعداد زیاد پادها به‌خاطر شمارش پیام‌های در پرواز (in-flight) — بررسی کنید گزینه scaleOnInFlight و تنظیمات SQS.
• صف هرگز تا صفر مقیاس نمی‌شود — ممکن است احراز هویت یا خطاهای واکشی متریک وجود داشته باشد؛ گزارش‌های KEDA و وضعیت بازگشتی را بررسی کنید.

7. نکات تنظیم

• تولید صف را بر اساس توان عملیاتی واقعی انتخاب کنید، نه حدس یا مقادیر دلخواه.
• مقادیر cooldown و رفتار HPA را جداگانه تنظیم کنید — آن‌ها مسیرهای کاهش مقیاس مختلفی را کنترل می‌کنند.
• در آزمایش‌ها، activationQueueLength، queueLength و رفتار scaleDown را متناسب با الگوی مصرف برنامه‌ی خود تنظیم کنید.

نتیجه‌گیری

بارهای کاری صف‌محور بیشترین سود را زمانی می‌برند که مقیاس خودکار بر اساس میزان کار معوق (backlog) تصمیم بگیرد، نه صرفاً معیارهای زیرساختی. مقیاس‌بندی مبتنی بر عمق صف باعث واکنش سریع‌تر به تغییرات تقاضا و کاهش مصرف منابع غیرضروری در زمان‌های کم‌بار می‌شود. اگرچه مثال این مقاله بر Amazon SQS، Amazon EKS و KEDA متمرکز بود، الگوی طراحی مشابه در بسیاری از معماری‌های رویدادمحور و سیستم‌های پیام‌رسان قابل اعمال است. کلید کار انتخاب سیگنال مقیاس‌پذیری است که دقیقاً تقاضای بار کاری را نشان دهد و رفتار مقیاس‌گذاری خودکار را با ویژگی‌های برنامه تطبیق دهد.

با گسترش پذیرش سیستم‌های ناهمزمان و رویدادمحور، مقیاس خودکار مبتنی بر حجم کار به بخش مهمی از ایجاد استقرارهای Kubernetes انعطاف‌پذیر، کارآمد و مقرون‌به‌صرفه تبدیل می‌شود 🚀