Course-এর সূচি

13.4

SNS, Fan-out আর Message Filtering

pub/sub topic, SNS + SQS fan-out, filter policy আর FIFO topic।

24 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই লেসন শেষে তুমি পারবে

  • একটা event অনেক প্রাপকের কাছে সরাসরি call করে পাঠালে কেন পাঠানো পক্ষ সবার সাথে বাঁধা পড়ে যায়, আর Amazon SNS-এর publish/subscribe model কীভাবে সেই বাঁধন খুলে দেয়, সেটা বোঝাতে।
  • Topic, তার publisher আর subscription কী, তা বলতে; কোন কোন subscriber হতে পারে (SQS, Lambda, Firehose, HTTP/S, email, SMS, mobile push) আর কোন AWS service SNS-এ publish করে, তা গুনে বলতে; আর যেসব limit জরুরি, সেগুলো মনে রাখতে।
  • SNS + SQS fan-out ঠিকভাবে সাজাতে: queue access policy, KMS key, অন্য Region আর অন্য account-এর queue, raw message delivery; আর এটা S3 event-এ আর Firehose দিয়ে S3-এ archive করতে কাজে লাগাতে।
  • ক্রম আর deduplication জরুরি হলে FIFO topic বেছে নিতে, আর তার throughput, subscriber আর replay কেমন আচরণ করে, আগেই বলে দিতে।
  • Subscription-এর filter policy লিখতে (attribute-based আর payload-based), আর একটা message ঠিক কোন কোন subscription-এ যাবে, তা হিসাব করে বলতে।
  • Delivery ব্যর্থ হলে SNS কীভাবে retry করে, কখন message হারিয়ে যায়, আর subscription-এর dead-letter queue কীভাবে সেটা বাঁচিয়ে রাখে, তা বোঝাতে।

#একটা event, অনেক প্রাপক

#সরাসরি call করলে সবার সাথে বাঁধা পড়ো

লেসন ১৩.১ থেকে ১৩.৩-এ আমরা queue দেখেছি: একজন producer, এক ধরনের consumer, আর প্রতিটা message একবারই process হয়। কিন্তু অনেক event-এর চরিত্র আলাদা। একজন customer order দিলে ব্যবসার কয়েকটা অংশকে সেটা জানতে হয়: warehouse, notification service, fraud team, analytics। একই message-কে পৌঁছাতে হয় অনেক প্রাপকের কাছে।

সোজা রাস্তা হলো order service নিজেই একে একে প্রত্যেককে call করবে। Slide-এ ছবিটা এরকম: একটা buying service call করছে email notification, fraud service, shipping service আর একটা SQS queue-কে। প্রথম দিন এটা চলে, তারপর থেকে প্রতিদিন ভোগায়:

  • ধীর। Order service প্রতিটা call-এর উত্তরের জন্য বসে থাকে, তাই প্রত্যেক প্রাপকের দেরি customer-এর checkout-এ যোগ হয়।
  • ভঙ্গুর। একজন প্রাপক বন্ধ বা ধীর হলে order service-কে ঠিক করতে হয়: order বাতিল করবে, আবার চেষ্টা করবে, নাকি ওই প্রাপককে বাদ দেবে। একজন দুর্বল প্রাপক সব order-এর ক্ষতি করে।
  • বাঁধা (coupled)। নতুন একজন প্রাপক মানে order service বদলে আবার deploy করা। পাঠানো পক্ষকে প্রত্যেক প্রাপকের ঠিকানা, protocol আর খুঁটিনাটি জানতে হয়।

#Publish/subscribe

Publish/subscribe (pub/sub) model-এ পাঠানো পক্ষ প্রাপকদের সাথে কথাই বলে না। সে একটা topic-এ message একবার publish করে, আর যারা ওই topic-এ subscribe করেছে, তারা প্রত্যেকে নিজের একটা copy পায়। প্রাপক কারা, কতজন, message নিয়ে তারা কী করে, পাঠানো পক্ষ কিছুই জানে না। পাঠানো পক্ষ টেরও পায় না, এমনভাবেই প্রাপক যোগ বা বাদ দেওয়া যায়।

একটা order, অনেক প্রাপক

ঢাকার একটা food-delivery app-কে প্রতিটা নতুন order-এর খবর দিতে হয় rider service, fraud check আর customer-কে। প্রত্যেককে আলাদা করে call করা, আর একবার একটা SNS topic-এ publish করা, দুটো পাশাপাশি দেখো।

পরিস্থিতি

কোনো topic নেই: order service প্রত্যেক প্রাপককে চেনে, আর একে একে call করে।

Order servicepublisher
SQS queuerider service
Lambdafraud check
Email / SMScustomer
call ১
ধাপ 1 / 4
1

Topic না থাকলে order service-কে নিজেই প্রত্যেক প্রাপককে call করতে হয়। প্রথমে rider service।

#Amazon SNS: topic, publisher আর subscriber

Amazon Simple Notification Service (SNS) হলো AWS-এর পুরোপুরি managed, push-based pub/sub messaging service। তোমাকে কোনো server বা broker চালাতে হয় না; তুমি topic আর subscription বানাও, delivery-র scale SNS নিজেই সামলায়।

#তিনটা অংশ

অংশএটা কীউদাহরণ
Topicনাম দেওয়া একটা logical প্রবেশপথ (একটা channel)। Publisher এখানে পাঠায়; এর একটা ARN থাকেarn:aws:sns:ap-southeast-1:111122223333:order-placed-example
Publisherযে-ই topic-এ message পাঠায়: SDK বা CLI দিয়ে তোমার application, অথবা কোনো AWS serviceorder service, একটা S3 bucket, একটা CloudWatch alarm
SubscriptionTopic-এ register করা একটা endpoint, তার protocol আর setting সহ (filter policy, DLQ, raw delivery)একটা SQS queue, একটা Lambda function, একটা email address

পরীক্ষার প্রথম তফাতটাই push বনাম pull। SQS হলো pull: consumer ReceiveMessage call করে, তৈরি হলে message টেনে নেয় (লেসন ১৩.১)। SNS হলো push: message publish হওয়ামাত্র সে প্রতিটা endpoint-এ পৌঁছে দেয়, কাউকে চাইতে হয় না।

SNS কোনো ভান্ডার না। Message পৌঁছে গেলে (বা retry শেষ হলে) standard topic কিছুই রেখে দেয় না। কোনো প্রাপককে যদি পরে process করতে হয়, নিজের কাজ আবার চেষ্টা করতে হয়, বা লম্বা বিভ্রাট সামলাতে হয়, তাহলে topic-এ subscribe করা উচিত একটা SQS queue। এটাই fan-out pattern, নিচে আসছে।

#কারা SNS-এ publish করে

তোমার নিজের code SDK বা CLI দিয়ে publish করে, কিন্তু অনেক AWS service সরাসরিই topic-এ publish করতে পারে, এজন্যই SNS-কে বলা যায় AWS-এর “notification bus”। Slide-এ একটা চেনা তালিকা আছে:

  • CloudWatch alarm (“CPU ৮০ %-এর ওপরে” → on-call-এর email আর SMS; লেসন ১৯.৩),
  • AWS Budgets (লেসন ১.৪-এর billing alert),
  • Auto Scaling group-এর notification (instance চালু হলো, বন্ধ হলো বা ব্যর্থ হলো, লেসন ৬.৫),
  • S3 event notification (লেসন ১০.৭),
  • Lambda (তোমার function-এর code থেকে, বা asynchronous invocation-এর destination হিসেবে),
  • CloudFormation-এর stack-এর অবস্থা বদল, AWS DMS-এর replication event, RDS event subscription (failover, backup, maintenance), DynamoDB (যেমন CloudWatch alarm-এর মাধ্যমে), আরও অনেক।

কোনো service তোমার topic-এ publish করতে চাইলে তার অনুমতি লাগে topic-এর access policy-তে (নিচে security অংশে দেখো)।

#কারা subscribe করতে পারে

দলSubscriber (protocol)সাধারণ ব্যবহার
AWS service (application-to-application, A2A)Amazon SQS queueWorker-দের জন্য টেকসই fan-out; সবচেয়ে জরুরিটা
AWS Lambda functionপ্রতিটা message-এ code চালানো, asynchronous invoke
Amazon Data Firehose streamMessage S3, Redshift, OpenSearch, Splunk…-এ জমা করা
নিজস্ব endpointHTTP / HTTPSWebhook, partner বা third-party API
মানুষ (application-to-person, A2P)Email / email-JSONInbox-এ alert
SMS text messageOTP, order-এর অবস্থা, ফোনে alert
Mobile pushAPNs, FCM, ADM ইত্যাদি দিয়ে iOS, Android আর Fire app-এ notification

যারা সরাসরি subscribe করতে পারে না: S3 bucket (Firehose দিয়ে যাও), Kinesis Data Streams, DynamoDB table, EC2 instance (এদের একটা HTTP endpoint দাও, বা আরও ভালো, একটা SQS queue)। পরীক্ষায় এগুলোকে ভুল উত্তর হিসেবে দেওয়া হয় প্রায়ই।

কিছু খুঁটিনাটি যা অনেকে খেয়াল করে না:

  • Email আর HTTP/S subscription confirm করতে হয়। SNS একটা confirmation message পাঠায়; কেউ link-এ click না করা পর্যন্ত (বা endpoint ConfirmSubscription call না করা পর্যন্ত) subscription থাকে pending confirmation, আর কিছুই পায় না।
  • Email হলো operational alert-এর জন্য, marketing বা বিপুল পরিমাণ customer email-এর জন্য না: প্রতিটা email subscription-এ সেকেন্ডে ১০টা message-এর সীমা, আর sender address ও format SNS-এর নিজের। আসল customer email-এর জন্য Amazon Simple Email Service ব্যবহার করো।
  • SMS পৌঁছায় AWS End User Messaging SMS দিয়ে (আগের নাম Amazon Pinpoint SMS)। নতুন account শুরু করে SMS sandbox-এ, মাসে $১ খরচের সীমা নিয়ে, আর অনেক দেশে message পৌঁছানোর আগে sender ID বা number register করাতে হয়।

#Standard আর FIFO topic

SQS-এর মতোই SNS-এর দুই ধরনের topic:

  • Standard topic: প্রায় সীমাহীন throughput, at-least-once delivery আর best-effort ordering (যথাসম্ভব ক্রম)। সব ধরনের subscriber চলে। এটাই default, আর notification ও বেশিরভাগ fan-out-এর ঠিক উত্তর।
  • FIFO topic (নামের শেষে .fifo): প্রতিটা message group-এর ভেতরে কড়া ক্রম আর deduplication, সীমিত throughput, আর subscriber হতে পারে শুধু SQS queue। এর জন্য নিচে আলাদা অংশ আছে।

#যে limit-গুলো জানা দরকার

বিষয়Standard topicFIFO topic
প্রতি account-এ topic১,০০,০০০১,০০০
প্রতি topic-এ subscription১,২৫,০০,০০০১০০
Message sizeDefault 256 KiB (body + attribute)একই
এক PublishBatch call-এ message১০১০
Publish throughputপ্রতি Region-এ account-ভিত্তিক soft quota (যেমন us-east-1-এ সেকেন্ডে ৩০,০০০, Mumbai বা Singapore-এ ১,৫০০)প্রতি message group-এ সেকেন্ডে ৩০০; default-এ প্রতি topic-এ সেকেন্ডে ৩,০০০ message বা ২০ MB
Filter policyপ্রতি topic-এ ২০০, প্রতি account-এ ১০,০০০একই

পাশের কথা, AWS docs-এ যাচাই করা: সেপ্টেম্বর ২০২৬ থেকে topic-এর MaximumMessageSize attribute বাড়িয়ে 1 MiB পর্যন্ত payload নেওয়া যায়, তবে শুধু তখনই, যখন সব subscription SQS, Lambda বা Firehose আর subscription ১০০টার বেশি না। এর চেয়ে বড় হলে SNS Extended Client Library (Java, Python) payload-টা S3-এ রেখে একটা pointer publish করে, ২ GB পর্যন্ত। পরীক্ষার জন্য SNS message-এর সীমা এখনও 256 KB।

#কীভাবে publish করবে

Slide দুটো উপায় বলে:

  1. Topic publish (সাধারণ পথ, SDK বা CLI দিয়ে): একটা topic বানাও, এক বা অনেকগুলো subscription বানাও, topic-এ publish করো। প্রতিটা subscription একটা করে copy পায়। PublishBatch এক call-এ ১০টা পর্যন্ত message পাঠায়, তাতে API call আর খরচ দুটোই কমে।
  2. Direct publish (mobile app-এর জন্য): কোনো push service-এর credential দিয়ে একটা platform application বানাও (Apple-এর জন্য APNs, Google-এর জন্য FCM, Amazon device-এর জন্য ADM, সাথে Baidu আর Windows-এর push service), প্রতিটা device token-কে একটা platform endpoint হিসেবে register করো, তারপর কোনো topic ছাড়াই সরাসরি একটা endpoint-এর ARN-এ publish করো। একজন customer-এর ফোনে “তোমার rider বাইরে দাঁড়িয়ে” এভাবেই পাঠানো হয়। সবাইকে একসাথে জানাতে (“ঈদ অফার: ২০ % ছাড়”) mobile endpoint-গুলো topic-এও subscribe করানো যায়।

প্রতিটা publish করা message-এর সাথে ১০টা পর্যন্ত message attribute থাকতে পারে (নাম, type String, String.Array, Number বা Binary, আর value)। Attribute হলো body-র বাইরের metadata; নিচের filter policy এগুলোই ব্যবহার করে।

খরচ মোটামুটি: standard topic-এ প্রতি দশ লাখ publish request-এ প্রায় $০.৫০ (প্রতিটা 64 KB টুকরো এক request ধরা হয়), SQS আর Lambda-তে delivery-র জন্য message-প্রতি কোনো খরচ নেই, আর HTTP, email, SMS ও mobile push-এ delivery-প্রতি দাম। Attribute-based filtering বিনা পয়সায়; payload-based filtering-এ প্রতি GB scan-এর জন্য দাম লাগে।

#SNS-এর নিরাপত্তা

Slide SNS-এর security-কে দুই ভাগে দেখায়: encryption আর access control; পুরোটাই SQS (লেসন ১৩.১) আর S3-এর (লেসন ১০.২ আর ১০.৮) মতো।

Encryption

  • চলার পথে (in flight): SNS API চলে HTTPS-এ। চাইলে topic policy দিয়ে জোর করতে পারো: aws:SecureTransport false হলে request deny। Server-side encryption চালু থাকা topic এমনিতেই শুধু HTTPS request নেয়।
  • জমা অবস্থায় (at rest): KMS key দিয়ে server-side encryption (AWS managed key aws/sns, বা customer managed key)। Standard topic-এ এটা default-এ বন্ধ, SQS-এর উল্টো, যেখানে নতুন queue default-এই SSE-SQS দিয়ে encrypted। SSE encrypt করে শুধু message body: topic-এর metadata আর message attribute encrypted হয় না, তাই attribute-এ কখনো গোপন তথ্য রেখো না। (Encrypted topic-এও attribute ধরে filtering চলে, কারণটাও এটাই।)
  • Client-side encryption: client নিজেই payload encrypt আর decrypt করতে চাইলে SNS শুধু ciphertext বয়ে নেয়।

Access control

  • User আর role-এর IAM policy ঠিক করে কে SNS API call করতে পারবে (sns:Publish, sns:Subscribe, sns:CreateTopic…), অধ্যায় ২-এর মতোই।
  • SNS access policy হলো topic-এর ওপর বসানো resource-based policy, S3 bucket policy-র মতো (resource-based policy নিয়ে লেসন ২.২)। এটা লাগে:
    • cross-account access-এ: অন্য একটা account তোমার topic-এ publish বা subscribe করলে;
    • topic-এ publish করা AWS service-এর জন্য, যেমন S3, CloudWatch বা Budgets: service principal-কে allow করো (যেমন s3.amazonaws.com), আর aws:SourceArn ও aws:SourceAccount দিয়ে সীমা বেঁধে দাও।
  • Topic যদি KMS key ব্যবহার করে, publish করা service-এর ওই key-তে kms:GenerateDataKey আর kms:Decrypt অনুমতিও লাগে। AWS managed key aws/sns-এর policy বদলানো যায় না, তাই যে topic-এ S3 বা CloudWatch publish করে, তার লাগবে customer managed key।

পাশের কথা: message data protection (২০২২) দিয়ে topic policy message-এর ভেতরের card number বা জাতীয় পরিচয়পত্রের নম্বরের মতো স্পর্শকাতর তথ্য পথেই audit, mask বা block করতে পারে। Compliance-এর জন্য কাজের, তবে encryption-এর বিকল্প না।

#SNS + SQS: fan-out pattern

#একবার push, প্রতিটা queue-তে পাওয়া

Fan-out হলো SNS-এর সবচেয়ে জনপ্রিয় architecture, আর পরীক্ষায় সবচেয়ে বেশি আসা pattern-গুলোর একটা। একজন publisher একটা SNS topic-এ message পাঠায় একবার; কয়েকটা SQS queue subscribe করা থাকে; SNS একই মুহূর্তে প্রতিটা queue-তে একটা করে copy push করে; তারপর প্রতিটা queue-এর নিজের worker নিজের copy process করে asynchronously, একসাথে (parallel)। বৈদ্যুতিক পাখার মতো: একই বাতাস একসাথে চারদিকে ছড়ায়।

Fan-out: একটা topic, তিনটা queue

একটা online shop “order placed” একবারই publish করে। তিনটা SQS queue subscribe করা: inventory, notification আর fraud। প্রতিটা queue-এর নিজের worker আছে।

পরিস্থিতি

SNS-এ একবার push, প্রতিটা subscribed queue-তে পাওয়া, তারপর একসাথে আলাদা আলাদা processing।

Shoppublisher
SNS topicorders
Inventoryqueue
Workerstock
Notifyqueue
Workeremail + SMS
Fraudqueue
Workerfraud
order ১০৩৬
ধাপ 1 / 4
1

Shop একটা “order placed” message publish করে, order ১০৩৬। Order নিয়ে যত team-ই মাথা ঘামাক, call একটাই।

#Queue কী যোগ করে

SNS একা পৌঁছে দিয়ে ভুলে যায়। প্রতিটা subscription-এর পেছনে একটা SQS queue বসালে এমন জিনিস যোগ হয়, যা SNS-এর নেই (প্রথম তিনটা slide-এ আছে):

  • জমিয়ে রাখা (persistence): কোনো worker process না করা পর্যন্ত message queue-তে অপেক্ষা করে (default ৪ দিন, সর্বোচ্চ ১৪)। Consumer crash করলেও কিছু হারায় না; note-এর “data loss হয় না” কথাটা এটাই।
  • দেরিতে processing: প্রত্যেক consumer নিজের গতিতে কাজ করে, delay queue বা রাতের batch-ও ঠিক আছে।
  • কাজের retry: কোনো worker ব্যর্থ হলে সে message delete করে না; visibility timeout-এর পরে সেটা আবার দেখা দেয়, আর maxReceiveCount বার চেষ্টার পরে queue-এর নিজের DLQ-তে যায় (লেসন ১৩.২)।
  • আলাদা আলাদা scale: প্রতিটা queue নিজের Auto Scaling group বা Lambda concurrency চালাতে পারে (লেসন ১৩.১)।
  • সময়ের সাথে নতুন consumer: নতুন team একটা নতুন queue subscribe করে; publisher আর পুরোনো queue যেমন ছিল তেমনই থাকে।

SNS থেকে SQS-এ delivery নিজেই খুব নির্ভরযোগ্য: SQS হলো AWS-managed endpoint, ২৩ দিন পর্যন্ত retry হয় (নিচে “Delivery, retry আর dead-letter queue” অংশ দেখো)।

#Queue-কে topic-কে লেখার অনুমতি দিতে হবে

একটা SQS queue শুধু তাদের message-ই নেয়, যাদের তার access policy অনুমতি দেয়। Console-এ queue subscribe করলে console নিজেই statement-টা যোগ করে; CLI, CloudFormation বা Terraform দিয়ে করলে তোমাকেই যোগ করতে হবে, নইলে ওই queue-তে প্রতিটা delivery “access denied”-এ ব্যর্থ হবে:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowOrdersTopic",
    "Effect": "Allow",
    "Principal": { "Service": "sns.amazonaws.com" },
    "Action": "sqs:SendMessage",
    "Resource": "arn:aws:sqs:ap-southeast-1:111122223333:inventory-example",
    "Condition": { "ArnEquals": { "aws:SourceArn": "arn:aws:sns:ap-southeast-1:111122223333:orders-example" } }
  }]
}

aws:SourceArn শর্তটা জরুরি: এটা না থাকলে যেকোনো account-এর যেকোনো SNS topic তোমার queue-তে লিখতে পারত।

Queue যদি SSE-KMS দিয়ে encrypted হয়, SNS-কে key-টাও ব্যবহার করতে দিতে হবে। AWS managed key aws/sqs কাউকে দেওয়া যায় না, তাই এমন একটা customer managed key নাও, যার key policy sns.amazonaws.com-কে kms:GenerateDataKey আর kms:Decrypt করতে দেয়। (Default SSE-SQS encryption-ওয়ালা queue-তে বাড়তি কিছু লাগে না।)

#Region আর account পেরিয়ে

  • Cross-Region delivery চলে SQS queue আর Lambda function-এ: ap-southeast-1-এর topic eu-west-1-এর queue-তে পাঠাতে পারে। Subscribe command চালাও topic-এর Region-এ, আর Region-এর মাঝে সাধারণ data transfer-এর খরচ দাও। (Bahrain বা Hong Kong-এর মতো opt-in Region-এ queue policy-তে Region-ভিত্তিক service principal লাগে।)
  • Cross-account fan-out-এ দুটো অনুমতি লাগে: topic policy অন্য account-কে sns:Subscribe করতে দেবে (অথবা topic-এর মালিক নিজেই queue subscribe করাবে), আর queue policy topic-কে sqs:SendMessage করতে দেবে। অন্য account-এর queue-এর জন্য topic-এর মালিক subscription বানালে queue-এর মালিককে সেটা confirm করতে হয়; queue-এর মালিক নিজে বানালে confirm লাগে না।

#Raw message delivery

Default-এ SNS তোমার message-কে একটা JSON মোড়কে (envelope) মুড়ে দেয় (Type, MessageId, TopicArn, Timestamp, Message, MessageAttributes, signature-এর field), ফলে SQS consumer তোমার order JSON-টা পায় Message field-এর ভেতরে escape করা একটা string হিসেবে। Subscription-এ raw message delivery চালু করো (SQS, HTTP/S আর Firehose-এ চলে), তাহলে queue ঠিক যা publish হয়েছিল তা-ই পায়, আর SNS-এর message attribute হয়ে যায় SQS-এর message attribute। যেসব consumer সরাসরি SQS-এ পাঠানো message-এর জন্য লেখা, সেগুলো কোনো বদল ছাড়াই চলে।

#Fan-out-এর দুটো চেনা ব্যবহার

#S3 event অনেকগুলো queue-তে

লেসন ১০.৭-এ S3 event notification আর তার overlap rule দেখেছ: একই event type-এর দুটো rule, যাদের prefix আর suffix overlap করে (যেমন images/-এ ObjectCreated), একসাথে থাকতে পারে না, তাই নিজস্ব notification একটা event পাঠায় একটাই destination-এ। একই event যদি কয়েকটা queue বা function-এর লাগে, ওই একটা rule-কে একই Region-এর একটা standard SNS topic-এর দিকে তাক করো, আর সবাইকে সেখানে subscribe করাও: এটাই fan-out। Topic-এর access policy-কে s3.amazonaws.com-কে publish করতে দিতে হবে, aws:SourceArn আর aws:SourceAccount দিয়ে শুধু ওই bucket-এর জন্য। (FIFO topic S3-এর destination হতে পারে না। আধুনিক আরেকটা উত্তর হলো bucket-এ EventBridge চালু করা, যেখানে একই event-এ যত খুশি rule মিলতে পারে; অধ্যায় ১৯।)

Note-এর চেনা প্রশ্নটাও এখানেই: “S3-এ file upload হওয়ামাত্র email পাঠাতে হবে” → S3 event notification যাবে একটা SNS topic-এ, যার আছে একটা email subscription।

#Firehose দিয়ে SNS থেকে S3-এ

SNS নিজে S3-এ লিখতে পারে না, আর S3 কোনো subscriber type-ও না। কিন্তু Amazon Data Firehose (slide-এ নাম Kinesis Data Firehose; ২০২৪-এ নাম বদলেছে) subscriber হতে পারে। Firehose subscription দিয়ে SNS প্রতিটা message একটা Firehose stream-এ push করে, stream সেগুলো জমিয়ে (size বা সময় ধরে) S3-এ object হিসেবে লেখে, অথবা Firehose-এর যেকোনো destination-এ: Redshift, OpenSearch, Splunk, HTTP endpoint, Apache Iceberg table (লেসন ১৩.৬)। Audit বা analytics-এর জন্য topic-এর message archive করার এটাই চেনা উপায়।

  • Subscription-এর একটা IAM role লাগে, যেটা SNS-কে stream-এ লিখতে দেয় (firehose:PutRecord আর এ জাতীয় action)।
  • একটা standard topic-এ প্রতি subscription মালিকের ৫টা পর্যন্ত Firehose subscription থাকতে পারে।
  • SNS-এর মোড়ক বাদ দিয়ে শুধু তোমার payload রাখতে raw message delivery চালু করো।
  • Firehose-এর delivery প্রায় real time (buffer করে), সাথে সাথে না।

S3 event অনেক জায়গায়, আর SNS থেকে S3-এ

ঢাকার একটা hospital scan-এর ছবি একটা bucket-এ upload করে। দুটো team-এর প্রতিটা upload event লাগবে, আর compliance চায় প্রতিটা message S3-এ archive হোক।

পরিস্থিতি

S3-এর নিজস্ব notification: একটা event type আর prefix-এ একটাই destination।

Scan bucketscans/
SQS queuethumbnail
Lambdavirus scan
object created
ধাপ 1 / 2
1

Thumbnail team একটা notification rule যোগ করে: scans/-এ object created হলে তাদের SQS queue-তে। এখন প্রতিটা upload queue-তে পৌঁছায়।

#FIFO topic

#শুরু থেকে শেষ পর্যন্ত ক্রম আর deduplication

Standard topic একটা message দুবার পাঠাতে পারে, আর publish-এর চেয়ে আলাদা ক্রমেও। অনেক notification-এর জন্য তাতে সমস্যা নেই। কিন্তু ledger, stock-এর হিসাব বা payment-এর ধাপের জন্য আছে। SNS FIFO topic (নামের শেষে .fifo থাকতেই হবে) SQS FIFO-র (লেসন ১৩.৩) নিশ্চয়তাগুলো pub/sub-এ নিয়ে আসে:

  • Message group ID ধরে ক্রম। প্রতিটা message-এর একটা MessageGroupId থাকে; একই group-এর message পৌঁছায় ঠিক যে ক্রমে publish হয়েছিল। আলাদা group একে অপরের থেকে স্বাধীন, একসাথে পৌঁছায়।
  • Deduplication। গত ৫ মিনিটে publish হওয়া কোনো message-এর একই message deduplication ID নিয়ে আরেকটা message এলে সেটা নেওয়া হয়, কিন্তু আর পাঠানো হয় না। Content-based deduplication চালু থাকলে SNS message body-র একটা hash-কেই deduplication ID ধরে, তাই তোমাকে আলাদা করে ID দিতে হয় না।
  • Subscriber: শুধু SQS। FIFO topic পাঠায় SQS FIFO queue-তে, আর ২০২৩ থেকে SQS standard queue-তেও। Lambda, HTTP/S, email, SMS, mobile push বা Firehose-এ পাঠাতে পারে না। Lambda consumer লাগলে সে FIFO queue থেকে পড়ে।
  • FIFO topic-এর পেছনে standard queue message ক্রম অনুযায়ীই পায়, কিন্তু standard queue তার consumer-এর জন্য ক্রম ধরে রাখে না, duplicate-ও ঠেকায় না। যে subscriber-এর এসব নিয়ে মাথাব্যথা নেই, তার জন্য এটা চলে।

#SNS FIFO + SQS FIFO fan-out

যখন fan-out + ক্রম + deduplication তিনটাই লাগে, slide-এর উত্তর: একটা SNS FIFO topic, তাতে subscribe করা SQS FIFO queue। প্রতিটা queue প্রতিটা group-এর প্রতিটা message পায় ক্রম অনুযায়ী আর একবারই (deduplication window-এর মধ্যে), আর প্রত্যেক team-এর consumer নিজের copy ক্রম মেনে process করে।

#Throughput

Slide বলে FIFO topic-এর throughput “SQS FIFO-র সমান”। এখনকার সংখ্যাগুলো:

  • প্রতি message group-এ সেকেন্ডে ৩০০ message, আর default-এ প্রতি topic-এ সেকেন্ডে ৩,০০০ message (বা ২০ MB), deduplication যাচাই হয় পুরো topic জুড়ে।
  • High-throughput mode (জানুয়ারি ২০২৫): topic-এর FifoThroughputScope করো MessageGroup। ক্রম থাকে group ধরে, deduplication-ও হয় group ধরে, আর topic account-এর Regional publish quota পর্যন্ত ব্যবহার করতে পারে (যেমন us-east-1-এ সেকেন্ডে ৩০,০০০)। এর সুবিধা নিতে message অনেক group-এ ছড়িয়ে দাও।
  • একটা FIFO topic-এ সর্বোচ্চ ১০০টা subscription।

অর্থাৎ throughput বাড়ে group-এর সংখ্যার সাথে: ৫টা ব্যস্ত group থাকলে সর্বোচ্চ ৫ × ৩০০ = সেকেন্ডে ১,৫০০ message; ২০টা group থাকলে প্রতি topic-এর ৩,০০০-এর default সীমাটাই বাধা হয়ে দাঁড়ায়।

#Archive আর replay

পাশের কথা (অক্টোবর ২০২৩): একটা FIFO topic তার পাওয়া প্রতিটা message ১ থেকে ৩৬৫ দিন পর্যন্ত archive করে রাখতে পারে (topic-এ একটা archive policy), আর কোনো subscriber নিজের বেছে নেওয়া সময় থেকে archive করা message replay করাতে পারে (তার subscription-এ একটা replay policy)। কোনো bug-এ data নষ্ট করে ফেলা team সেটা আবার গড়ে নিতে পারে; নতুন subscriber পুরোনো ইতিহাস ধরে ফেলতে পারে। Replay-এ বাড়তি খরচ লাগে, আর এটা শুধু FIFO topic-এ (application-to-application) চলে। পরীক্ষায় “data stream replay করতে হবে” মানে এখনও Kinesis (লেসন ১৩.৫)।

FIFO topic: ক্রম ঠিক, duplicate নেই

একটা mobile wallet প্রতিটা payment-এর event ক্রম অনুযায়ী publish করে: created, paid, settled। Ledger-কে এগুলো ঠিক এই ক্রমেই, আর ঠিক একবারই বসাতে হবে।

পরিস্থিতি

একটা payment-এর সব event-এর message group ID একই, তাই শুরু থেকে শেষ পর্যন্ত ক্রম ঠিক থাকে।

Wallet APIpublisher
FIFO topicpayments.fifo
LedgerFIFO queue
Ledger worker
Notifystandard queue
Notify worker
3 · 2 · 1
ধাপ 1 / 3
1

Wallet payment P-77-এর তিনটা event publish করে, message group ID P-77 দিয়ে: ১ created, ২ paid, ৩ settled।

নিজেকে যাচাই করোপ্রশ্ন

একটা payment platform প্রতিটা payment-এর created, paid আর settled event publish করে। তিনটা team-এর প্রত্যেককে প্রতিটা event পেতে হবে, প্রতিটা payment-এর ক্রম ঠিক রেখে, duplicate ছাড়া, আর প্রত্যেক team নিজের গতিতে process করবে। Architect কী ব্যবহার করবে?

#Message filtering

#কেন filter

সাধারণত একটা topic-এর প্রতিটা subscription প্রতিটা message পায়। প্রায়ই সেটা চাই না: refund team-এর placed order-এ কোনো আগ্রহ নেই, premium desk শুধু premium order চায়। Filtering না থাকলে প্রত্যেক consumer-কে সবকিছু নিতে হয়, নিজের code-এ যাচাই করতে হয় message-টা তার কাজের কি না, তারপর বাকিগুলো delete করতে হয়। এতে compute, SQS request আর টাকা নষ্ট হয়, আর routing-এর যুক্তি ছড়িয়ে পড়ে অনেকগুলো code base-এ।

Message filtering দিয়ে প্রতিটা subscription বলে দেয় সে কোন message চায়। SNS প্রতিটা message subscription-এর filter policy-র সাথে মিলিয়ে দেখে, আর শুধু মিললেই পাঠায়। যে message মেলে না, সেটা শুধু ওই subscription-এ যায় না (বাকিদের কাছে ঠিকই যায়)।

#Attribute আর filter policy

  1. Publisher প্রতিটা message-এর সাথে message attribute জুড়ে দেয়, body-র বাইরের metadata, যেমন state = placed আর order_type = premium।
  2. প্রতিটা subscription পায় একটা filter policy: ছোট্ট একটা JSON document, যেখানে থাকে সে কোন attribute-এর নাম দেখবে আর কোন value নেবে।
{
  "state": ["placed"],
  "order_type": ["premium", "gold"],
  "amount": [{ "numeric": [">=", 10000] }],
  "city": [{ "anything-but": ["Dhaka"] }]
}

মেলানোর নিয়ম:

  • Policy নেই → সব message। Slide-ও এটা বলে: filter policy ছাড়া subscription সবকিছু পায়।
  • Key-গুলোর মধ্যে AND: policy-র প্রতিটা key মিলতেই হবে।
  • List-এর ভেতরে OR: একটা key-র list-এর যেকোনো একটা value মিললেই চলে (premium অথবা gold)। $or operator দিয়ে পুরো বিকল্প শর্তও জোড়া যায়।
  • যে attribute নেই, সেটা কোনো key-র সাথে কখনো মেলে না, {"exists": false} ছাড়া।
  • String মেলানো case-sensitive: Placed আর placed মেলে না (যদি না equals-ignore-case ব্যবহার করো)।
  • Policy-তে যে attribute-এর উল্লেখ নেই, সেটা উপেক্ষা করা হয়।
Operatorউদাহরণকী মেলে
হুবহু string"state": ["placed"]state ঠিক placed
anything-but"city": [{"anything-but": ["Dhaka"]}]city আছে, আর সেটা Dhaka না
prefix / suffix"sku": [{"prefix": "MED-"}]যেসব value MED- দিয়ে শুরু
equals-ignore-case"state": [{"equals-ignore-case": "placed"}]placed, Placed, PLACED
numeric"amount": [{"numeric": [">", 0, "<=", 5000]}]০ < amount ≤ ৫,০০০
exists"coupon": [{"exists": true}]attribute-টা আছে
IP address"source_ip": [{"cidr": "10.0.0.0/24"}]ওই range-এর address
wildcard"file": [{"wildcard": "*.jpg"}]pattern-এর সাথে মেলা value

যে সীমাগুলো মনে রাখবে: প্রতি policy-তে সর্বোচ্চ ৫টা key, সর্বোচ্চ ১৫০টা combination (প্রতিটা key-র value-সংখ্যা গুণ করো: ৩ × ৫ × ১০ = ১৫০ হলো সীমা), প্রতি policy 256 KB, প্রতি topic-এ ২০০টা policy। নতুন বা বদলানো policy পুরোপুরি কার্যকর হতে ১৫ মিনিট পর্যন্ত লাগতে পারে। Filter policy standard আর FIFO দুই topic-এই চলে।

#Attribute-based আর payload-based filtering

  • Attribute-based (default; subscription-এর FilterPolicyScope হলো MessageAttributes): policy মেলানো হয় শুধু message attribute-এর সাথে, String, String.Array আর Number type-এ। Policy nested হতে পারে না। পরীক্ষার প্রশ্ন সাধারণত এটাই বোঝায়।
  • Payload-based (নভেম্বর ২০২২ থেকে; FilterPolicyScope = MessageBody): policy মেলানো হয় JSON body-র সাথেই, nested key সহ, যেমন {"order": {"state": ["placed"]}}। যখন তোমার নিয়ন্ত্রণের বাইরের publisher (অন্য team, কোনো AWS service) সবকিছু body-তে রাখে আর কোনো attribute দেয় না, তখন এটা কাজে লাগে। Body-কে valid JSON হতে হয়, আর প্রতি GB scan-এ সামান্য খরচ আছে।

Filter policy: প্রত্যেক subscriber নিজের message বেছে নেয়

প্রতিটা order event-এর সাথে attribute থাকে। Placed queue-এর policy state = placed, cancelled queue-এর state = cancelled, আর analytics queue-এর কোনো policy-ই নেই।

পরিস্থিতি

SNS প্রতিটা subscription-এর policy-র সাথে message মিলিয়ে দেখে, আর শুধু মিললেই পাঠায়।

Order service
SNS topicorders
Placedstate = placed
Cancelledstate = cancelled
Analyticspolicy নেই
state=placed

Message attribute

order

1036

state

placed

order_type

premium

ধাপ 1 / 3
1

Order service order ১০৩৬ publish করে, attribute state = placed আর order_type = premium দিয়ে। Body-তে পুরো order; attribute হলো বাইরে লাগানো ছোট্ট একটা লেবেল।

নিয়মগুলো নিজে চালিয়ে দেখো: একটা message বানাও, আর দেখো আটটা subscription-এর কোনগুলো সেটা পায়।

Filter policy lab

Orders topic-এর জন্য একটা order message বানাও, আর দেখো আটটা subscription-এর কোনগুলো সেটা পায়। ফাঁদগুলোও চেষ্টা করো: একটা বড় হাতের অক্ষর, একটা হারানো attribute, fields শুধু body-তে।

১. Message

state
order_type
amount
city
Field কোথায় পাঠানো

২. কে পায়

ওপরে value বেছে নাও; কিছু না বদলানো পর্যন্ত কিছুই পাঠানো হয় না।

#Filter-ওয়ালা একটা topic, নাকি অনেকগুলো topic?

  • একটা topic + filter policy, যখন message-গুলো একই ধরনের event আর প্রাপকরা আলাদা আলাদা অংশ চায়। Publisher সরল থাকে (একটাই topic), আর নতুন কোনো অংশ মানে শুধু একটা নতুন policy।
  • আলাদা topic, যখন event-গুলো সত্যিই আলাদা (order বনাম inventory alarm), মালিক বা অনুমতি আলাদা, বা আলাদা topic type লাগে (standard বনাম FIFO)।
  • Routing-এর নিয়ম জটিল হয়ে গেলে (অনেক source, content বদলানো, schedule, SaaS source) বড় হাতিয়ার হলো EventBridge rule (অধ্যায় ১৯); SNS filtering দ্রুত, সরল, বিপুল পরিমাণ fan-out-এর জন্য।

#Delivery, retry আর dead-letter queue

#SNS কীভাবে retry করে

Endpoint unavailable থাকায় delivery ব্যর্থ হলে (একটা server-side error: HTTP 5xx, 429, throttled Lambda), SNS একটা delivery policy মেনে আবার চেষ্টা করে, যেটা protocol অনুযায়ী আলাদা:

EndpointRetry policyবদলানো যায়?
SQS, Lambda (AWS-managed endpoint)৩ বার সাথে সাথে, ২ বার ১ সেকেন্ড পরপর, ১০ বার backoff দিয়ে ২০ সেকেন্ড পর্যন্ত, তারপর ১,০০,০০০ বার ২০ সেকেন্ড পরপর: ২৩ দিনে ১,০০,০১৫ বার চেষ্টানা
Email, SMS, mobile push৬ ঘণ্টায় ৫০ বার চেষ্টানা
HTTP / HTTPSDefault: ৩ বার retry, ২০ সেকেন্ড পরপর। Topic বা subscription-এ নিজের policy: ১০০ বার পর্যন্ত retry, backoff function (linear, arithmetic, geometric, exponential), মোট retry-এর সময় সর্বোচ্চ ১ ঘণ্টা, চাইলে একটা throttle (maxReceivesPerSecond)-ওহ্যাঁ, শুধু এটাই

Delivery policy শেষ হয়ে গেলে SNS message ফেলে দেয়, যদি না subscription-এ dead-letter queue থাকে।

Client-side error আলাদা জিনিস: endpoint delete হয়ে গেছে, queue বা function-এর policy আর SNS-কে অনুমতি দেয় না, KMS key ব্যবহার করা যাচ্ছে না, বা HTTP endpoint 4xx উত্তর দিচ্ছে (429 ছাড়া)। এগুলোতে SNS একবারও retry করে না, কারণ retry-ও একইভাবে ব্যর্থ হতো।

Retry মানে একটা endpoint একই message একাধিকবার পেতে পারে (standard topic at-least-once): consumer-কে idempotent বানাও, যেমন MessageId মনে রেখে।

#Subscription-এর dead-letter queue

SNS-এর dead-letter queue (DLQ) হলো একটা সাধারণ SQS queue, যেটা একটা redrive policy (deadLetterTargetArn) দিয়ে জোড়া থাকে একটা subscription-এর সাথে (topic-এর সাথে না)। Client-side error-এ ব্যর্থ হওয়া, বা retry ফুরিয়ে যাওয়া message হারানোর বদলে সেখানে যায়। নিয়ম:

  • DLQ-কে subscription-এর একই account আর Region-এ থাকতে হবে।
  • FIFO topic-এর subscription-এর DLQ হবে FIFO; standard topic-এর হবে standard queue।
  • DLQ-র access policy-কে SNS-কে পাঠানোর অনুমতি দিতে হবে, আর encrypted হলে একটা customer managed KMS key-কে SNS-কে অনুমতি দিতে হবে।
  • DLQ-র retention সর্বোচ্চ, ১৪ দিন রাখো, আর এর ApproximateNumberOfMessagesVisible-এর ওপর একটা CloudWatch alarm বসাও।
  • Delivery ব্যর্থ হলে subscription বন্ধ হয় না। NumberOfNotificationsFailed metric-এর দিকে চোখ রাখো, আর delivery status logging চালু করো (CloudWatch Logs-এ, SQS, Lambda, HTTP/S, Firehose, SMS আর mobile push-এর জন্য)।

Note-এর DLQ অংশে যে “SNS-এরও DLQ আছে” বলা আছে, সেটা এটাই: SQS-এর DLQ হলো সেই message-এর জন্য, যেটা consumer বারবার process করতে ব্যর্থ হয় (লেসন ১৩.২); SNS-এর DLQ সেই message-এর জন্য, যেটা সে পৌঁছাতে পারেনি; আর Lambda-র DLQ বারবার ব্যর্থ হওয়া asynchronous invocation-এর জন্য (অধ্যায় ১৫)।

Delivery ব্যর্থ হলে: retry আর subscription-এর DLQ

একটা courier partner HTTPS webhook-এ order event নেয়। Webhook বন্ধ থাকলে, আর কখনো না ফিরলে, আর ভুলটা তোমার দিকে হলে SNS কী করে, দেখো।

পরিস্থিতি

Server-side error (5xx, 429) delivery policy অনুযায়ী আবার চেষ্টা করা হয়।

Order service
SNS topic
Courier webhookHTTPS
DLQsubscription-এ
Publish
ধাপ 1 / 5
1

একটা order publish হলো। Topic-এ courier partner-এর webhook-এর জন্য একটা HTTPS subscription আছে।

#SNS আর SQS পাশাপাশি

SQS আর SNS অংশটা note শেষ করেছে পরীক্ষার আগের রাতের একটা রিক্যাপ দিয়ে। এখানে সেটাই, লেসন ১৩.১–১৩.৪-এর খুঁটিনাটি সহ:

SQSSNS
ModelQueue: প্রতিটা message একজন consumer-এর কাছেPub/sub: প্রতিটা message প্রতিটা subscription-এ
DeliveryPull (consumer poll করে)Push
Message রাখে?হ্যাঁ, ১৪ দিন পর্যন্ত, delete না হওয়া পর্যন্তনা (standard); FIFO topic replay-এর জন্য archive করতে পারে
চেনা শব্দDecouple, buffer, হঠাৎ ভিড় সামলানো, asynchronous, workerNotify, alert, email/SMS, push notification, অনেক subscriber
ব্যর্থতা সামলানোVisibility timeout, maxReceiveCount, DLQProtocol অনুযায়ী delivery retry, subscription-এর DLQ
ক্রমStandard: যথাসম্ভব; FIFO: group ধরেStandard: যথাসম্ভব; FIFO: group ধরে
একসাথেFan-out: ১টা SNS topic → অনেকগুলো SQS queue (parallel processing)Filtering: প্রতিটা subscription শুধু মেলা message পায় (compute বাঁচে)

তৃতীয় model Kinesis (replay করা যায় এমন stream) আসছে লেসন ১৩.৫-এ, আর SQS বনাম SNS বনাম Kinesis-এর পুরো তুলনা লেসন ১৩.৭-এ।

#কোথায় গোলমাল হয়

লক্ষণসম্ভাব্য কারণসমাধান
Subscribe করা SQS queue-তে কোনো message আসে নাQueue-এর access policy sns.amazonaws.com-কে অনুমতি দেয় না (CLI বা template দিয়ে subscribe)SNS principal-এর জন্য sqs:SendMessage, aws:SourceArn = topic
Encrypted queue-তে delivery ব্যর্থQueue-তে AWS managed key aws/sqs, যেটা SNS ব্যবহার করতে পারে নাCustomer managed key, যার policy SNS-কে kms:GenerateDataKey আর kms:Decrypt দেয়
S3 topic-এ notification save করতে পারে নাTopic policy s3.amazonaws.com-কে অনুমতি দেয় না; topic FIFO; topic অন্য Region-এ; KMS key policyTopic policy ঠিক করো; bucket-এর Region-এ standard topic; customer managed key
Email subscriber কিছুই পায় নাSubscription এখনও pending confirmationConfirmation link-এ click করো; spam folder দেখো
Consumer message parse করতে পারে নাSNS-এর মোড়ক: payload আছে Message-এর ভেতরে string হয়েRaw message delivery চালু করো, বা মোড়ক খোলো
Filter policy-ওয়ালা queue কিছুই পায় নাAttribute নেই, type ভুল, case ভুল, বা field শুধু body-তেAttribute দাও; case মেলাও; payload-based filtering নাও; বদলের পরে ১৫ মিনিট পর্যন্ত অপেক্ষা করো
বিভ্রাটের সময় HTTP endpoint-এর message হারিয়েছেDefault HTTP policy (৩ retry, ২০ সেকেন্ড) শেষ; DLQ নেইSubscription DLQ; নিজস্ব delivery policy; মাঝে SQS queue
Webhook একই order দুবার process করেAt-least-once delivery আর timeout-এর পরে retryMessageId ধরে idempotent consumer; অথবা FIFO topic + FIFO queue
FIFO topic-এ Publish throttle হচ্ছেপ্রতি group-এ সেকেন্ডে ৩০০, প্রতি topic-এ ৩,০০০আরও message group; high-throughput mode; batching
Lambda-কে FIFO topic-এ subscribe করানো যায় নাFIFO topic শুধু SQS-এ পাঠায়একটা SQS FIFO queue subscribe করাও, আর সেখান থেকে Lambda trigger করো
বড় message-এ publish InvalidParameter-এ ব্যর্থPayload 256 KiB-এর বেশি (body + attribute)S3 সহ Extended Client Library; বা subscriber অনুমতি দিলে MaximumMessageSize বাড়াও
বিদেশে SMS পৌঁছায় নাSandbox, খরচের সীমা, বা register করা sender ID বা number নেইSandbox থেকে বের হও, সীমা বাড়াও, একটা origination identity register করো

#System design-এ SNS

  • মানুষকে notification। CloudWatch alarm, Budgets আর ASG event → একটা topic → email, SMS, আর Lambda বা HTTPS দিয়ে chat tool। প্রতিটা account-এ SNS-এর সবচেয়ে চেনা প্রথম ব্যবহার।
  • Service-গুলোর মধ্যে event fan-out। একটা domain event (order-placed) → একটা standard topic → প্রতিটা consumer service-এর জন্য একটা SQS queue। Producer আর consumer আলাদা আলাদা deploy আর scale হয়; microservice-এর চেনা choreography ধরন।
  • Fan-out + filtering। প্রতি ধরনের event-এর জন্য একটা topic, filter policy দিয়ে প্রত্যেক service শুধু নিজের ভাগটা পায়। অনেকগুলো topic-এর চেয়ে সস্তা আর সরল।
  • ক্রম মেনে fan-out। Ledger, inventory আর state machine-এর জন্য FIFO topic + FIFO queue; group ID = entity-র ID।
  • একাধিক Region আর account। এক Region-এর topic থেকে DR Region-এর বা অন্য account-এর queue-তে delivery (দুই দিকেই cross-account policy)।
  • Archive। S3-এ audit trail-এর জন্য Firehose subscription; consumer-কে state আবার গড়তে হলে FIFO-র archive আর replay।
  • নাজুক endpoint-এর সামনে buffer। যা অনেকক্ষণ বন্ধ থাকতে পারে, তার আর SNS-এর মাঝে SQS বসাও: partner-এর webhook, on-premises system।
  • কখন অন্য কিছু নেবে, জেনে রাখো। অনেক source, জটিল routing আর schema → EventBridge (অধ্যায় ১৯)। বিপুল পরিমাণ stream-এর replay আর অনেক পাঠক → Kinesis (লেসন ১৩.৫)। AMQP বা MQTT বলা পুরোনো app → Amazon MQ (লেসন ১৩.৭)।

#নিজে করে দেখো

সব command চলবে ap-southeast-1-এ; নামের শেষে -example। Output ছোট করে দেখানো।

# 1. A standard topic and two queues
aws sns create-topic --name orders-example
#   { "TopicArn": "arn:aws:sns:ap-southeast-1:111122223333:orders-example" }
aws sqs create-queue --queue-name inventory-example
aws sqs create-queue --queue-name refunds-example
#   { "QueueUrl": "https://sqs.ap-southeast-1.amazonaws.com/111122223333/inventory-example" }

# 2. Let the topic write to each queue (policy.json is the queue policy shown in the lesson)
aws sqs set-queue-attributes \
  --queue-url https://sqs.ap-southeast-1.amazonaws.com/111122223333/inventory-example \
  --attributes file://inventory-policy.json

# 3. Subscribe the queues: raw delivery, and a filter policy on the refunds queue
aws sns subscribe --topic-arn arn:aws:sns:ap-southeast-1:111122223333:orders-example \
  --protocol sqs --notification-endpoint arn:aws:sqs:ap-southeast-1:111122223333:inventory-example \
  --attributes RawMessageDelivery=true
aws sns subscribe --topic-arn arn:aws:sns:ap-southeast-1:111122223333:orders-example \
  --protocol sqs --notification-endpoint arn:aws:sqs:ap-southeast-1:111122223333:refunds-example \
  --attributes '{"RawMessageDelivery":"true","FilterPolicy":"{\"state\":[\"cancelled\",\"declined\"]}"}'
#   { "SubscriptionArn": "arn:aws:sns:ap-southeast-1:111122223333:orders-example:6b0e71bd-7e97-4d97-80ce-4a0994e55286" }

# 4. An email subscription stays pending until the link is clicked
aws sns subscribe --topic-arn arn:aws:sns:ap-southeast-1:111122223333:orders-example \
  --protocol email --notification-endpoint ops@example.com
#   { "SubscriptionArn": "pending confirmation" }

# 5. Publish a placed order with attributes: inventory gets it, refunds does not
aws sns publish --topic-arn arn:aws:sns:ap-southeast-1:111122223333:orders-example \
  --message '{"order":1036,"item":"pencil","qty":4}' \
  --message-attributes '{"state":{"DataType":"String","StringValue":"placed"}}'
#   { "MessageId": "f1d0a8e2-3c51-5f1a-9b8e-2a7c4d0e9b11" }
aws sqs receive-message --wait-time-seconds 10 \
  --queue-url https://sqs.ap-southeast-1.amazonaws.com/111122223333/inventory-example
#   "Body": "{\"order\":1036,\"item\":\"pencil\",\"qty\":4}"   (raw: no SNS envelope)
aws sqs receive-message --wait-time-seconds 10 \
  --queue-url https://sqs.ap-southeast-1.amazonaws.com/111122223333/refunds-example
#   (no output: filtered out)

# 6. Switch a subscription to payload-based filtering, and give it a DLQ
aws sns set-subscription-attributes --subscription-arn <refunds-subscription-arn> \
  --attribute-name FilterPolicyScope --attribute-value MessageBody
aws sns set-subscription-attributes --subscription-arn <refunds-subscription-arn> \
  --attribute-name RedrivePolicy \
  --attribute-value '{"deadLetterTargetArn":"arn:aws:sqs:ap-southeast-1:111122223333:refunds-dlq-example"}'

# 7. A FIFO topic with content-based deduplication, and an ordered publish
aws sns create-topic --name payments-example.fifo \
  --attributes FifoTopic=true,ContentBasedDeduplication=true
aws sns publish --topic-arn arn:aws:sns:ap-southeast-1:111122223333:payments-example.fifo \
  --message '{"payment":"P-77","event":"paid"}' --message-group-id P-77
#   { "MessageId": "…", "SequenceNumber": "10000000000000003000" }

# 8. See every subscription and its state
aws sns list-subscriptions-by-topic \
  --topic-arn arn:aws:sns:ap-southeast-1:111122223333:orders-example

খেয়াল করার মতো: ধাপ ৫-এ filtering আর raw delivery একসাথে দেখা যায় (RawMessageDelivery ছাড়া একবার চালিয়ে মোড়কটার সাথে তুলনা করো); ধাপ ৪ দেখায় email alert কেন মাঝে মাঝে “কাজ করে না”; আর ধাপ ৭-এর FIFO topic-এ ৫ মিনিটের মধ্যে একই body দুবার publish করলে সেটা পৌঁছায় একবারই।

#সারসংক্ষেপ

মূল কথা

  • অনেক প্রাপককে সরাসরি call করা ধীর, ভঙ্গুর আর বাঁধা। SNS হলো AWS-এর managed, push-based pub/sub service: publisher একটা topic-এ একবার পাঠায়, আর প্রতিটা subscription একটা করে copy পায়। YouTube channel আর তার subscriber-দের মতো।
  • Subscriber: SQS, Lambda, Data Firehose (A2A); HTTP/S; email, SMS, mobile push (A2P)। S3, Kinesis Data Streams বা EC2 সরাসরি না। Email আর HTTP/S confirm করতে হয়। অনেক AWS service SNS-এ publish করে (CloudWatch alarm, Budgets, ASG, S3 event, RDS, DMS, CloudFormation…)।
  • Limit: standard topic-এ ১,২৫,০০,০০০ subscription (FIFO-তে ১০০), প্রতি account-এ ১,০০,০০০ topic (FIFO ১,০০০), 256 KB message (২০২৬ থেকে শুধু SQS/Lambda/Firehose-ওয়ালা topic-এ 1 MiB পর্যন্ত বাড়ানো যায়; Extended Client Library দিয়ে ২ GB)।
  • Publish: topic publish (SDK/CLI, PublishBatch-এ ১০টা) বা mobile platform endpoint-এ direct publish (APNs, FCM, ADM…)।
  • Security: চলার পথে HTTPS; জমা অবস্থায় KMS দিয়ে SSE (default-এ বন্ধ, শুধু body, attribute encrypted না); client-side encryption; API call-এর জন্য IAM; cross-account আর S3-এর মতো AWS service-এর জন্য topic access policy।
  • Fan-out: SNS topic → অনেকগুলো SQS queue: পুরোপুরি decoupled, data হারায় না, জমিয়ে রাখা, দেরিতে processing, retry, পরে queue যোগ। Queue access policy-কে topic-কে অনুমতি দিতে হবে; encrypted queue-তে customer managed key; cross-Region আর cross-account চলে; raw message delivery মোড়ক সরায়।
  • ব্যবহার: S3 event অনেক target-এ (একটা rule → topic), আর archive-এর জন্য SNS → Firehose → S3।
  • FIFO topic: message group ID ধরে ক্রম, deduplication (৫ মিনিট, ID বা content-based), subscriber শুধু SQS (FIFO বা standard), প্রতি group-এ সেকেন্ডে ৩০০ আর প্রতি topic-এ ৩,০০০ (বেশি লাগলে high-throughput mode), archive আর replay। SNS FIFO + SQS FIFO = fan-out + ক্রম + deduplication।
  • Filtering: প্রতি subscription-এ একটা JSON filter policy; policy নেই = সবকিছু; key-তে AND, list-এ OR; case-sensitive; attribute না থাকলে মেলে না; attribute-based (default) বা payload-based। Compute বাঁচায়, routing-এর যুক্তি consumer-এর code থেকে সরায়।
  • Retry: SQS/Lambda ২৩ দিনে ১,০০,০১৫ বার; email/SMS/push ৬ ঘণ্টায় ৫০ বার; HTTP/S default ৩ বার, এক ঘণ্টা পর্যন্ত নিজের মতো বদলানো যায়। Client-side error-এ retry নেই। Subscription DLQ (SQS, একই account আর Region) হারিয়ে যেত এমন message রেখে দেয়।