Course-এর সূচি

13.6

Amazon Data Firehose

S3, Redshift আর OpenSearch-এ প্রায় সঙ্গে সঙ্গে ডেটা পৌঁছানো, buffering, transformation, আর Firehose বনাম Data Streams।

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

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

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

  • Amazon Data Firehose (আগের নাম Kinesis Data Firehose) কী করে বুঝিয়ে বলতে: কোনো consumer code, server বা shard ছাড়াই streaming data destination-এ তুলে দেওয়া।
  • এর source-গুলোর নাম বলতে (Direct PUT, Kinesis Data Streams, Amazon MSK, আর CloudWatch Logs, IoT, EventBridge, SNS, WAF-এর মতো AWS service) আর destination-গুলোর নাম বলতে (S3, S3 হয়ে Redshift, OpenSearch, Iceberg table, Splunk, Snowflake, partner আর যেকোনো HTTP endpoint)।
  • Buffer size আর buffer interval hint দেখে আগে থেকেই বলতে, Firehose কখন একটা batch পাঠাবে, আর file-এর size, file-এর সংখ্যা ও দেরি হিসাব করতে।
  • Lambda transformation, Parquet বা ORC-তে format conversion আর dynamic partitioning ব্যবহার করতে, আর প্রতিটার সীমা জানতে।
  • Destination ব্যর্থ হলে কী হয় বলতে: retry, S3 backup, ২৪ ঘণ্টার সীমা, আর duplicate।
  • পরীক্ষার কোনো scenario-তে Kinesis Data Streams আর Firehose-এর মধ্যে বেছে নিতে, আর কখন দুটোই লাগে তা জানতে।

#Stream থেকে storage পর্যন্ত

#শেষ মাইলের ঝামেলা

লেসন ১৩.৫-এ দেখেছ, Kinesis Data Streams কীভাবে দ্রুত আর না-থামা record-এর স্রোত ধরে রাখে। কিন্তু ধরে রাখা কাজের অর্ধেক মাত্র। আগে হোক পরে হোক, বেশিরভাগ data-কে এমন কোথাও পৌঁছাতে হয় যেখানে সেটা জমা থাকবে আর query করা যাবে: S3-এর file, Redshift-এর table, OpenSearch-এর index, কিংবা Splunk-এর মতো কোনো security tool।

এই শেষ ধাপটা নিজে লিখতে গেলে যতটা সহজ মনে হয়, আসলে তা না। একটা stream থেকে S3-এ data তোলার consumer-কে যা যা করতে হয়:

  • প্রতিটা shard পড়া, আর কোথা পর্যন্ত পড়া হলো সেটা মনে রাখা;
  • হাজার হাজার ছোট record জুড়ে মানানসই size-এর file বানানো, কারণ লাখ লাখ ছোট file হলে S3-এর query ধীর আর দামি হয়ে যায়;
  • file compress আর encrypt করা, আর এমন নাম দেওয়া যাতে পরে খুঁজে পাওয়া যায়;
  • destination ধীর বা বন্ধ থাকলে আবার চেষ্টা করা, data না হারিয়ে আর দুবার না লিখে;
  • ম্যাচের দিন traffic বাড়লে বড় হওয়া, রাতে আবার ছোট হয়ে যাওয়া;
  • কোথাও চলা, patch পাওয়া, নজরদারিতে থাকা।

এর কোনোটাই তোমার আসল business logic না। এগুলো নিছক পাইপলাইনের কাজ, আর প্রতিটা team একই জিনিস নতুন করে লিখত।

#Firehose আসলে কী

Amazon Data Firehose একটা fully managed service, যেটা streaming data নিয়ে সেটাকে একটা destination-এ তুলে দেয় (load করে)। তুমি একটা Firehose stream বানাও, source আর destination বেছে দাও, বাকি পাইপলাইনের কাজ Firehose করে: buffering, batch বানানো, compression, encryption, চাইলে transformation, delivery আর retry। Notes-এ যেমন বলা আছে, data process করার জন্য তোমাকে কোনো consumer code লিখতে হয় না; সে data নেয় আর সরাসরি জায়গামতো জমা করে।

  • Serverless আর fully managed। কোনো server নেই, shard নেই, capacity-র হিসাব নেই। Firehose নিজে নিজেই বাড়ে-কমে।
  • যতটুকু ব্যবহার, ততটুকু খরচ। যত GB ঢোকে তার জন্য টাকা দাও (সাথে ঐচ্ছিক feature-এর খরচ), বসে থাকা capacity-র জন্য না।
  • Near real-time। Record-গুলো সে একটা buffer-এ জমায়, তারপর দলে দলে পাঠায়; তাই data পৌঁছায় পাঠানোর কয়েক সেকেন্ড থেকে কয়েক মিনিট পরে, millisecond-এ না।
  • নিজের কোনো storage নেই। Data সে রাখে শুধু পৌঁছে না দেওয়া পর্যন্ত (delivery বারবার ব্যর্থ হলে বড়জোর ২৪ ঘণ্টা)। Replay করার উপায় নেই।

ফেব্রুয়ারি ২০২৪ পর্যন্ত service-টার নাম ছিল Amazon Kinesis Data Firehose, তারপর AWS নাম বদলে রাখে Amazon Data Firehose। বদলেছে শুধু নাম: API, CLI command (aws firehose), IAM action (firehose:*) আর CloudWatch metric আগের মতোই আছে। পুরোনো পরীক্ষার প্রশ্ন আর blog post-এ এখনো “Kinesis Data Firehose” লেখা পাবে; জিনিস একটাই।

একটা Firehose stream: producer থেকে destination পর্যন্ত

Record আসে একটা app, একটা Kinesis data stream বা CloudWatch Logs থেকে। Firehose সেগুলো buffer-এ জমায়, তারপর দলে দলে S3, Redshift বা OpenSearch-এ পৌঁছে দেয়; তোমাকে কোনো consumer code লিখতে হয় না।

পরিস্থিতি

App সরাসরি Firehose-এ লেখে; কখন S3-এ file পড়বে, সেটা ঠিক করে size অথবা সময়।

Order appSDK
Data stream
CloudWatch Logs
Firehose streambuffer 0.4 / 5 MB
S3 bucket
OpenSearch
Redshift
৫০০ record
ধাপ 1 / 5
1

একটা food-delivery app SDK দিয়ে order event পাঠাচ্ছে: এক batch call-এ সর্বোচ্চ ৫০০টা record বা ৪ MB, প্রতিটা record ১,০০০ KiB পর্যন্ত। কোনো shard-এর হিসাব নেই; Firehose নিজেই scale করে।

#Source: data কীভাবে ঢোকে

একটা Firehose stream-এর source থাকে ঠিক একটা, আর সেটা বেছে নিতে হয় stream বানানোর সময়ই:

Sourceকীভাবে কাজ করেসাধারণ ব্যবহার
Direct PUTProducer নিজেই Firehose-এর API ডাকে: PutRecord (একটা record) বা PutRecordBatch (এক call-এ সর্বোচ্চ ৫০০ record বা ৪ MiB)SDK দিয়ে লেখা app, server-এ বসানো Kinesis Agent, আর যেসব AWS service তোমার হয়ে Firehose-এ লেখে
Kinesis Data StreamsFirehose একটা চালু data stream পড়ে, অন্য যেকোনো consumer-এর মতোযে data-র real-time consumer-ও লাগে, বা replay লাগে
Amazon MSKFirehose একটা managed Kafka cluster-এর topic পড়ে (সেপ্টেম্বর ২০২৩ থেকে)যেসব কোম্পানি আগে থেকেই Kafka-তে আছে

অনেক AWS service তোমার হয়ে Direct PUT দিয়ে data পাঠায়, এজন্যই architecture diagram-এ Firehose এত জায়গায় দেখা যায়:

  • CloudWatch Logs-এর subscription filter (ডিসেম্বর ২০২৩ থেকে Firehose চাইলে নিজেই unzip করে দেয়), আর CloudWatch metric stream;
  • AWS IoT Core-এর rule (sensor data);
  • EventBridge rule, যার target Firehose;
  • SNS subscription (লেসন ১৩.৪: Firehose হয়ে SNS থেকে S3);
  • AWS WAF-এর log, VPC Flow Logs, Route 53 Resolver-এর query log, API Gateway-এর access log, CloudFront-এর standard log (লেসন ১১.১)।

কয়েকটা খুঁটিনাটি জেনে রাখো:

  • একটা record যেকোনো byte-এর দলা, সর্বোচ্চ ১,০০০ KiB (base64 করার আগে)। Slide-এ লেখা “1 MB পর্যন্ত”, কথা একই। JSON, CSV, Avro, সাধারণ text নাকি binary, Firehose-এর তাতে কিছু আসে যায় না; JSON লাগে শুধু format conversion-এর জন্য।
  • প্রতি stream-এ Direct PUT quota: N. Virginia, Oregon আর Ireland-এ সেকেন্ডে ৫,০০,০০০ record, ২,০০০ request আর ৫ MiB; বাকি Region-এ সেকেন্ডে ১,০০,০০০ record, ১,০০০ request আর ১ MiB। Throttling দেখলে Firehose নিজেই এগুলো বাড়ায়, আর তুমি চাইলে আরও চাইতে পারো। Source যদি Kinesis data stream হয়, এই quota খাটে না।
  • যে stream-এর source Kinesis data stream বা MSK, সে PutRecord call নেয় না; producer তখন লেখে data stream-এ।
  • পাশের কথা: নভেম্বর ২০২৪-এ AWS database-কে source হিসেবে preview করেছিল (MySQL আর PostgreSQL থেকে change data capture করে Iceberg table-এ)। সেপ্টেম্বর ২০২৫-এ সেই preview তুলে নেওয়া হয়েছে, তাই এটা আজ Firehose-এর feature না, আর পরীক্ষাতেও আসে না।

#Destination: data কোথায় যায়

প্রতিটা Firehose stream-এর destination একটা (সাথে backup-এর জন্য ঐচ্ছিক একটা S3 bucket, নিচে দেখো):

দলDestinationFirehose কীভাবে পৌঁছায়
Amazon S3যেকোনো bucketBuffer-এর record জুড়ে প্রতি flush-এ একটা object বানায়
Amazon RedshiftProvisioned cluster বা Serverless workgroupআগে file S3-এ লেখে, তারপর একটা COPY command চালিয়ে সেগুলো load করে
Amazon OpenSearchOpenSearch Service domain বা OpenSearch Serverless collection (আগের নাম Elasticsearch)Bulk index request
Apache Iceberg tableS3-এর Iceberg table, Amazon S3 Tables সহঠিক table-এ insert, এমনকি update আর delete-ও (সেপ্টেম্বর ২০২৪ থেকে সবার জন্য চালু)
Third-party partnerSplunk, Snowflake (এপ্রিল ২০২৪ থেকে), Datadog, New Relic, MongoDB, Dynatrace, Coralogix, Elastic, Sumo Logic, Honeycomb আরও অনেকপ্রতিটা partner-এর নিজস্ব ingestion API
Custom HTTP endpointতোমার নিজের যেকোনো HTTPS endpoint, যেটা Firehose-এর request format মানেRecord সহ HTTP POST

যা মনে রাখতে হবে:

  • Redshift-এ যাওয়া মানে S3 হয়ে যাওয়া। Firehose কখনো Redshift-এ সরাসরি row ঢোকায় না। তোমার বেছে দেওয়া একটা S3 bucket-এ আগে file রাখে, তারপর COPY চালায়। Cluster (বা Serverless workgroup) হতে হবে publicly accessible, আর Firehose-এর IP address allow করা, কারণ Firehose তোমার VPC-র বাইরে থেকে connect করে।
  • যা destination না: DynamoDB, RDS, SQS queue, EC2 instance, EFS file system। এগুলোতে পৌঁছাতে নিজের বানানো একটা HTTP endpoint লাগবে, নয়তো Kinesis data stream-এর ওপর একটা Lambda consumer।
  • S3 object-এর নাম। Default-এ key শুরু হয় UTC তারিখ আর ঘণ্টা দিয়ে, YYYY/MM/dd/HH/; সামনে নিজের prefix জুড়ে দিতে পারো, কিংবা !{timestamp:yyyy}-এর মতো expression দিয়ে বানাতে পারো। Record-গুলো কোনো ভাগ-চিহ্ন ছাড়াই গায়ে গায়ে জোড়া থাকে, তাই Athena দিয়ে পড়তে চাইলে new line delimiter চালু করো।
  • অন্য account বা অন্য Region-এ delivery-ও করা যায় (যেমন কেন্দ্রীয় logging account-এর bucket), ঠিকঠাক bucket policy আর IAM role থাকলে।

#Buffering: কেন near real-time

#Size hint আর interval hint

Firehose আসা record-গুলো একটা buffer-এ রাখে, আর দুটো শর্তের মধ্যে যেটা আগে পূরণ হয় তখনই buffer পাঠিয়ে দেয়:

  • buffer size hint (কত MB জমাবে), অথবা
  • buffer interval hint (কত সেকেন্ড অপেক্ষা করবে)।

একটা দিলে অন্যটাও দিতে হয়। এদের hint বলে, কারণ বেশি কার্যকর হলে Firehose একটু অন্যভাবেও পাঠাতে পারে; যেমন delivery পিছিয়ে পড়লে সে নিজেই buffer size বাড়িয়ে দেয়, যাতে ধরে ফেলা যায়।

DestinationBuffer size, MB (default)Buffer interval, s (default)
Amazon S3, Iceberg table, Redshift1–128 (5)0–900 (300)
OpenSearch Service আর Serverless1–100 (5)0–900 (300)
Splunk1–5 (5)0–60 (60)
HTTP endpoint আর বেশিরভাগ partner1–64 (মোটামুটি 5)0–900 (60)
Snowflake1–128 (1)0–900 (0)

অর্থাৎ default setting-এ S3 stream-এ পাঠানো একটা record পৌঁছাতে পাঁচ মিনিট পর্যন্ত অপেক্ষা করতে পারে। Near real-time কথাটার মানে এটাই।

#Zero buffering

Notes বলছে (আর পরীক্ষার পুরোনো উত্তরও তাই), Firehose কমপক্ষে ১ মিনিট বা ১ MB buffer করে। এটা সত্যি ছিল ডিসেম্বর ২০২৩ পর্যন্ত। এখন interval ০ সেকেন্ড দেওয়া যায় (“zero buffering”): তখন Firehose অপেক্ষা করে না, কয়েক সেকেন্ডের মধ্যে পৌঁছে দেয়। সীমাগুলো:

  • S3 backup copy-র জন্য পাওয়া যায় না, dynamic partitioning-এর সাথেও না;
  • ৬০ সেকেন্ডের কম হলে Firehose S3-এ multipart upload করে, তাই PUT request বেশি লাগে, খরচ বাড়ে, আর file ছোট হয়;
  • hint কমানোর আগে partner-এর সুপারিশ করা মান দেখে নাও।

০ সেকেন্ডেও পরীক্ষার ভাষায় Firehose near real-time-এর উত্তর। “Real-time, এক সেকেন্ডের কম, নিজের মতো processing” বললে উত্তর এখনো consumer সহ Kinesis Data Streams।

#একটা flush হিসাব করা

নিয়ম সোজা: ভরতে লাগা সময় = buffer size ÷ data আসার হার। সেটা interval-এর চেয়ে কম হলে size জেতে; নইলে interval জেতে।

  • সেকেন্ডে ৫০ KB, ৫ MB buffer: ৫,১২০ KB ÷ ৫০ KB/s ≈ ১০২ সেকেন্ড, ৩০০ সেকেন্ডের চেয়ে কম, তাই মোটামুটি প্রতি ১০০ সেকেন্ডে একটা ৫ MB file; দিনে ৮৪০টা file।
  • সেকেন্ডে ৫ KB, একই buffer: ভরতে লাগবে ১,০২৪ সেকেন্ড, তাই ৩০০ সেকেন্ডের interval জেতে: প্রতি ৫ মিনিটে ১.৫ MB-এর একটা file; দিনে ২৮৮টা।
  • সেকেন্ডে ৫ KB, ১২৮ MB buffer আর ৯০০ সেকেন্ড interval: এবারও interval, প্রতি ১৫ মিনিটে ৪.৪ MB-এর একটা file; দিনে ৯৬টা, আর record ১৫ মিনিট পর্যন্ত দেরিতে পৌঁছায়।

Buffer বড় মানে file কম আর বড় (query সস্তা আর দ্রুত), কিন্তু দেরি বেশি। Buffer ছোট মানে টাটকা data, কিন্তু সাথে ছোট file-এর সমস্যা: S3 প্রতিটা PUT-এর জন্য টাকা নেয়, আর Athena বা Glue ছোট ছোট file পড়ার চেয়ে খুলতেই বেশি সময় নষ্ট করে।

সংখ্যাগুলো নিজে বদলে দেখো:

Buffer timing ল্যাব

সিলেটের একটা চা-বাগান তার sensor থেকে মাটি আর আবহাওয়ার reading Firehose দিয়ে S3-এ পাঠায়। Data কত দ্রুত আসছে আর buffer-এর দুটো hint বেছে নাও, তারপর একদিন চালিয়ে দেখো কোন hint আগে পূরণ হয়, file কত বড় হয়, আর data কতটা দেরিতে পৌঁছাতে পারে।

Data আসার হার

Buffer size hint

Buffer interval hint

Dynamic partitioning

ফল দেখতে “একদিন চালাও” চাপো।

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

S3-এ যাওয়া একটা Firehose stream-এ buffer size ৫ MB আর interval ৩০০ সেকেন্ড। Producer-রা সেকেন্ডে মোটামুটি ২০ KB পাঠায়। Firehose কত পরপর file লেখে, আর file কত বড়?

#পথের মাঝে data বদলানো

Source আর destination-এর মাঝখানে Firehose data বদলে দিতে পারে। কাজগুলো হয় এই ক্রমে: de-aggregation (চালু থাকলে), Lambda transformation, dynamic partitioning, format conversion, তারপর delivery।

#Lambda transformation

Data transformation চালু করে Firehose-কে একটা Lambda function দাও। সাধারণ কাজ: CSV থেকে JSON (বা notes-এর মতো JSON থেকে CSV), phone number বা card number mask করা, field যোগ করা (postcode থেকে শহরের নাম), debug event ফেলে দেওয়া, timestamp ঠিক করা।

  • Lambda-র জন্য Firehose আলাদা buffer রাখে: ০.২ থেকে ৩ MB (default ১ MB, Splunk আর Snowflake-এর জন্য ২৫৬ KB) অথবা ০ থেকে ৯০০ সেকেন্ড (default ৬০)।
  • Function-কে সে ডাকে synchronously; request আর response দুটোই ৬ MB-এর মধ্যে থাকতে হয়, আর function চলতে পারে সর্বোচ্চ ৫ মিনিট।
  • Function প্রতিটা record ফেরত দেয় একই recordId, একটা result আর নতুন data (base64) সহ। result হয় Ok (পাঠাও), Dropped (জেনেশুনে ফেলে দাও) অথবা ProcessingFailed।
  • Invocation ব্যর্থ হলে (timeout, throttling) Firehose default-এ তিনবার আবার চেষ্টা করে, তারপর পুরো batch-কে ব্যর্থ ধরে।
  • ব্যর্থ record যায় S3-এর processing-failed/ prefix-এ, error আর function-এর ARN সহ। কিছুই চুপচাপ হারায় না।
  • Source record backup দিয়ে S3-এ একটা অবিকৃত copy রেখে দিতে পারো; transformation-এ bug থাকলে আর আবার চালাতে হলে এটা কাজে লাগে।
  • Apache log থেকে JSON-এর মতো সাধারণ কাজের জন্য AWS blueprint (নমুনা function) দেয়।

#Format conversion: JSON থেকে Parquet বা ORC

Data lake-এর জন্য JSON-এর চেয়ে columnar format অনেক ভালো: Athena শুধু query-র দরকারি column পড়ে, আর file-ও ভালো compress হয়। Firehose Lambda ছাড়াই, নিজে নিজে JSON থেকে Apache Parquet বা Apache ORC বানাতে পারে:

  • এর জন্য লাগে একটা schema, AWS Glue Data Catalog-এর একটা table থেকে (লেসন ১৭.৬)।
  • সে একটা deserializer দিয়ে JSON পড়ে (OpenX JSON SerDe, সাধারণত এটাই, অথবা Hive JSON SerDe), তারপর Parquet বা ORC লেখে।
  • Input JSON হতেই হবে। CSV বা অন্য text হলে আগে Lambda transformation দিয়ে JSON বানাও।
  • Schema-র সাথে না মেলা record যায় error prefix-এ, format-conversion-failed হিসেবে।
  • S3-এর জন্য compression: gzip, Snappy, Zip বা Hadoop-compatible Snappy (Redshift-এ শুধু gzip)।

Slide-এ Firehose কোন কোন format “support করে” তার তালিকা আছে (CSV, JSON, Parquet, Avro, raw text, binary), আর conversion-এর কথা (Parquet বা ORC-তে, gzip বা Snappy দিয়ে compression)। এভাবে বুঝে নাও: যেকোনো byte পার হয়ে যেতে পারে, কিন্তু নিজস্ব conversion শুধু JSON থেকে Parquet বা ORC-তে।

#Dynamic partitioning

Default-এ সব file সময়ের prefix-এর নিচে যায়। Dynamic partitioning (২০২১ থেকে) data-র ভেতরের key দিয়ে record ভাগ করে, যেমন customer_id বা city, আর প্রতিটা দলকে নিজের prefix-এ লেখে, যেমন city=sylhet/2026/10/26/। তখন একটা শহরের query শুধু ওই folder-টাই পড়ে।

  • Key আসে JSON-এর ক্ষেত্রে jq দিয়ে inline parsing থেকে, অথবা তোমার Lambda function থেকে; সর্বোচ্চ ৫০টা key।
  • Prefix-এ !{partitionKeyFromQuery:city}-এর মতো expression লেখো।
  • শুধু S3 destination। চালু করা যায় শুধু stream বানানোর সময়, আর পরে বন্ধ করা যায় না।
  • প্রতিটা partition-এর মানের জন্য আলাদা buffer, তাই file ছোট হয়, আর দেরি interval-এর ১.৫ গুণ পর্যন্ত হতে পারে। Zero buffering চলে না।
  • Quota: একসাথে প্রতি stream-এ ৫০০টা active partition (চাইলে ২,৫০০ পর্যন্ত)। এর বেশি হলে record চলে যায় error prefix-এ (activePartitionExceeded)। Partition করো অল্প কয়েকটা মান আছে এমন key দিয়ে, transaction ID দিয়ে কখনো না।
  • প্রতি GB আর প্রতি object-এর জন্য বাড়তি খরচ আছে।

পথের মাঝে: Lambda, Parquet আর dynamic partitioning

bKash ধরনের একটা payment service transaction event পাঠাচ্ছে একটা S3 data lake-এ। দেখো Firehose কীভাবে Lambda দিয়ে এগুলো পরিষ্কার করে, Glue schema দিয়ে Parquet বানায়, আর customer অনুযায়ী আলাদা folder-এ রাখে।

পরিস্থিতি

Firehose batch তুলে দেয় তোমার function-এর হাতে, আর রাখে শুধু সেটুকু যা function ফেরত দেয়।

Payment app
Firehose
Lambdatransform
Glue tableschema
Data lake
কাঁচা event
ধাপ 1 / 4
1

প্রতিটা event-এ customer-এর পুরো phone number আছে। Analyst-রা এটা কখনো দেখতে পারবে না, তাই জমা করার আগেই data mask করতে হবে।

#Delivery ব্যর্থ হলে

Firehose আবার চেষ্টা করে, আর পৌঁছাতে না পারলে data S3-এ backup রাখে, যাতে পরে তুলে দেওয়া যায়। প্রতিটা destination-এর আচরণ একটু আলাদা:

Destinationব্যর্থ হলে Firehose কী করে
S3২৪ ঘণ্টা পর্যন্ত আবার চেষ্টা করে (Direct PUT source হলে)। তারপর data হারিয়ে যায়। Source Kinesis data stream বা MSK হলে, source যতদিন data রাখে ততদিন চেষ্টা চালায়
RedshiftRetry duration (০–৭,২০০ s, default ৩,৬০০) পর্যন্ত COPY আবার চালায়, তারপর batch বাদ দিয়ে errors/-এ বাদ পড়া file-গুলোর একটা manifest লেখে, যাতে হাতে COPY করা যায়
OpenSearchRetry duration (০–৭,২০০ s, default ৩০০) পর্যন্ত চেষ্টা, তারপর document-গুলো backup bucket-এর AmazonOpenSearchService_failed/-এ লেখে
Splunk, HTTP endpoint, partnerএকটা acknowledgement-এর অপেক্ষা করে; error বা timeout হলে retry duration শেষ না হওয়া পর্যন্ত চেষ্টা, তারপর data S3-এ backup
SnowflakeService-এর error হলে আবার চেষ্টা (default ৬০ s); schema-র ভুল থাকা record সোজা S3-এ (snowflake-failed/)

S3 ছাড়া অন্য destination-এর জন্য S3 backup-এর দুটো mode: শুধু ব্যর্থ data (default) অথবা সব data (পুরো একটা copy, সস্তা archive হিসেবে কাজে লাগে)। Slide-এ এটা দেখানো আছে “all or failed data” হিসেবে, একটা S3 backup bucket-এ যাচ্ছে। Destination আর backup bucket দুটোই ব্যর্থ হলে, যেকোনো একটা আবার কাজ না করা পর্যন্ত Firehose delivery থামিয়ে রাখে।

Delivery হয় অন্তত একবার (at-least-once)। Acknowledgement হারিয়ে গেলে Firehose batch আবার পাঠায়, তাই Splunk, HTTP endpoint, OpenSearch আর Redshift-এ duplicate আসতে পারে। ব্যতিক্রম S3, Iceberg table আর Snowflake। প্রতিটা record-এ একটা event ID রাখো, যাতে destination (বা তোমার query) duplicate বাদ দিতে পারে।

Destination ব্যর্থ হলে

একটা garments রপ্তানিকারক তার security log পাঠায় Splunk-এ আর app log পাঠায় OpenSearch-এ, নিরাপত্তার জাল হিসেবে আছে একটা S3 bucket। একেকটা destination নষ্ট করে দেখো Firehose কী করে।

পরিস্থিতি

Retry duration পর্যন্ত চেষ্টা, তারপর document-গুলো S3-এ রেখে দেওয়া।

Log source
Firehose
Splunksecurity team
OpenSearch
Backup bucket
bulk index
ধাপ 1 / 4
1

OpenSearch domain-এর ওপর অনেক চাপ, সে bulk request ফিরিয়ে দিচ্ছে।

#Security, monitoring আর খরচ

Access। Firehose কাজ করে তোমার দেওয়া একটা IAM role দিয়ে: role-টা তাকে source পড়তে (যেমন kinesis:GetRecords), Lambda function ডাকতে, Glue table পড়তে আর bucket-এ লিখতে দেয়। Producer-দের লাগে firehose:PutRecord / PutRecordBatch permission। Delivery থেমে যাওয়ার সবচেয়ে চেনা কারণ নষ্ট হয়ে যাওয়া role।

Encryption।

  • পথে (in transit): সব API call আর delivery TLS (HTTPS) দিয়ে হয়।
  • Firehose-এর ভেতরে থাকা অবস্থায় (at rest): Direct PUT হলে KMS দিয়ে server-side encryption চালু করো (AWS owned key বা তোমার নিজের customer managed key)। Source যদি Kinesis data stream হয়, Firehose তখন stream-এর encryption-এর ওপরই ভরসা করে।
  • Destination-এ: S3-এর জন্য bucket-এর default encryption, অথবা তোমার বেছে দেওয়া একটা SSE-KMS key (লেসন ১০.৮)।

Networking। Private subnet-এর producer একটা interface VPC endpoint দিয়ে internet ছাড়াই Firehose-এ পৌঁছাতে পারে (অধ্যায় ২২)। Firehose VPC-র ভেতরের OpenSearch domain-এও পৌঁছাতে পারে (সে তোমার subnet-এ network interface বসায়, যার আলাদা সামান্য খরচ আছে)।

Monitoring। CloudWatch metric যেমন IncomingRecords, DeliveryToS3.Success, আর সবচেয়ে কাজের DeliveryToS3.DataFreshness: এখনো পৌঁছায়নি এমন সবচেয়ে পুরোনো record-এর বয়স। Freshness-এর ওপর alarm বসাও, আর CloudWatch Logs-এ error logging চালু রাখো।

খরচ। টাকা দাও প্রতি GB ঢোকার জন্য (Direct PUT আর Kinesis source-এ প্রথম ধাপে মোটামুটি $0.029 প্রতি GB), format conversion আর dynamic partitioning-এর জন্য প্রতি GB বাড়তি, সাথে destination-এর নিজের খরচ। একটা ফাঁদ আছে: Direct PUT আর Kinesis source-এ প্রতিটা record পরের ৫ KB পর্যন্ত গোল করে ধরা হয়। সেকেন্ডে ১ KB-এর ১,০০০টা record মানে bill হবে প্রতিটা ৫ KB ধরে, আসল data-র পাঁচগুণ; কয়েকটা event জুড়ে কম কিন্তু বড় record (৫ KB বা তার বেশি) পাঠালে ingestion bill কমে যায়।

#Kinesis Data Streams বনাম Firehose

পরীক্ষায় সবচেয়ে চেনা গুলিয়ে ফেলার জায়গা এই দুটো, কারণ দুটোই streaming data বয়, আর দুটোই একসময় “Kinesis” ছিল।

Kinesis Data StreamsAmazon Data Firehose
কাজStream ধরে রাখা, আর তোমার consumer-কে process করতে দেওয়াStream একটা destination-এ তুলে দেওয়া
CodeProducer আর consumer দুটোই তুমি লেখো (Lambda, KCL app, Flink)Consumer code নেই; শুধু destination বেছে দাও (transformation-এর জন্য Lambda ঐচ্ছিক)
LatencyReal-time: মোটামুটি ২০০ ms (enhanced fan-out-এ ৭০ ms-এর কাছাকাছি)Near real-time: buffer interval ০–৯০০ s (ডিসেম্বর ২০২৩-এর আগে সর্বনিম্ন ৬০ s)
CapacityProvisioned mode-এ shard, নয়তো নিজে নিজে scale হওয়া on-demand modeFully managed, automatic scaling, কিছুই মাপতে হয় না
StorageRecord রাখে default ২৪ ঘণ্টা, সর্বোচ্চ ৩৬৫ দিনকোনো storage নেই; শুধু পৌঁছানো পর্যন্ত (ব্যর্থ হলে বড়জোর ২৪ ঘণ্টা)
Replayহ্যাঁ, retention-এর মধ্যে যেকোনো জায়গা থেকেনা
Consumerঅনেকজন, প্রত্যেকে একই data যার যার গতিতে পড়েপ্রতি stream-এ একটা destination (সাথে S3 backup)
Data কোথায় যায়তোমার code যেখানে পাঠায়S3, Redshift, OpenSearch, Iceberg, Splunk, Snowflake, partner, HTTP
Transformationতোমার consumer-এর ভেতরেনিজস্ব: Lambda, Parquet/ORC, dynamic partitioning
OrderShard (partition key) অনুযায়ীভরসা করার মতো কোনো feature না
দামShard-ঘণ্টা ধরে (provisioned) বা প্রতি GB (on-demand)প্রতি GB ঢোকা ধরে

Notes-এ Firehose-এর গতি লেখা “কমপক্ষে ১ মিনিট বা ১ MB buffer”, আর Data Streams-এর scaling “shard সংখ্যা ম্যানুয়ালি ম্যানেজ করতে হয়”। দুটোই পুরোনো তথ্য: ২০২৩ থেকে Firehose ০ সেকেন্ড buffer করতে পারে, আর ২০২১ থেকে Data Streams-এর একটা on-demand mode আছে, যেটা নিজেই scale করে (লেসন ১৩.৫)। তবু পরীক্ষা এখনো Data Streams-কে বলে যাকে তুমি মাপো, আর Firehose-কে বলে যে নিজে scale করে।

এরা প্রতিদ্বন্দ্বী না। সবচেয়ে চেনা design-এ দুটোই থাকে: producer লেখে একটা Kinesis data stream-এ, একটা real-time consumer (Lambda বা Managed Service for Apache Flink) alert আর dashboard-এর জন্য সেটা পড়ে, আর ওই data stream-কে source বানিয়ে একটা Firehose stream সবকিছু S3-এ archive করে, প্রায়ই Parquet হিসেবে, Athena-র জন্য।

একটাই cricket clickstream: Data Streams, Firehose, না দুটোই

বাংলাদেশ বনাম ভারতের ম্যাচে লাখো দর্শক live-score app-এ tap করছে। Product team চায় এখনই live stats, আর পরে বিশ্লেষণের জন্য পুরো archive। Tool-গুলো পাশাপাশি দেখো।

পরিস্থিতি

Real time, replay, অনেক consumer, আর নিজের লেখা consumer code।

দর্শক
Data stream
Live statsতোমার code
tap
ধাপ 1 / 3
1

প্রতিটা tap একটা record, partition key ম্যাচের ID। লেখার মোটামুটি ২০০ ms পরেই record পড়া যায় (enhanced fan-out-এ ৭০ ms-এর কাছাকাছি)।

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

লক্ষণসম্ভাব্য কারণসমাধান
Data S3-এ পৌঁছায় পাঁচ মিনিট দেরিতেকম traffic-এ default ৩০০ s intervalInterval কমাও (০ s পর্যন্ত), ছোট file মেনে নাও
লাখ লাখ ছোট object, Athena query ধীরছোট buffer size, ছোট interval, অনেক বেশি partitionBuffer size বাড়াও (৬৪–১২৮ MB), partition key কমাও, পরে file জোড়া লাগাও
কিছুই আসছে না, DataFreshness বাড়ছেইFirehose-এর IAM role bucket-এর access হারিয়েছে, বা bucket বা KMS key policy বদলেছেRole বা policy ঠিক করো; Firehose ২৪ ঘণ্টা পর্যন্ত চেষ্টা করে (Direct PUT)
নিজেদের তৈরি S3-এর গোলমালের পরে একদিনের বেশি পুরোনো data নেইDirect PUT data রাখে বড়জোর ২৪ ঘণ্টাFreshness-এ alarm; বেশি সুরক্ষার জন্য source হিসেবে Kinesis data stream
নতুন stream-এ PutRecord ব্যর্থStream-এর source একটা Kinesis data streamFirehose-এ না, data stream-এ লেখো
processing-failed/-এ record জমছেLambda ProcessingFailed ফেরত দিয়েছে, timeout হয়েছে (৫ মিনিটের বেশি), বা ৬ MB-এর বেশি ফেরত দিয়েছেFunction ঠিক করো; Lambda buffer ছোট করো; ব্যর্থ file আবার চালাও
প্রতিটা record-এর Parquet conversion ব্যর্থInput JSON না, CSV; বা Glue schema মেলে নাআগে Lambda-তে CSV থেকে JSON; Glue table ঠিক করো
activePartitionExceeded errorঅনেক বেশি মানওয়ালা key দিয়ে partitionঅল্প মানের key ব্যবহার করো; আরও partition চাও
Splunk বা OpenSearch-এ duplicateAcknowledgement হারানোর পরে at-least-once deliveryEvent ID, আর destination-এ duplicate বাদ দেওয়া
Redshift-এ load বন্ধ, errors/-এ fileCluster-এ পৌঁছানো যাচ্ছে না, বা retry duration-এর চেয়ে লম্বা maintenanceCluster-কে নাগালে আনো; manifest দিয়ে আবার COPY
Data-র তুলনায় ingestion bill অনেক বেশিঅনেক record ৫ KB-এর ছোট (প্রতিটা গোল করে ধরা হয়)কয়েকটা event জুড়ে একটা record বানাও
Dynamic partitioning চালু (বা বন্ধ) করা যাচ্ছে নাএটা শুধু তৈরির সময় ঠিক হয়, আর চিরস্থায়ীনতুন stream বানাও

#System design-এ Firehose

  • কেন্দ্রীয় logging। অনেক account-এর CloudWatch Logs subscription filter → Firehose → একটা logging account-এর S3 (archive, ৯০ দিন পরে Glacier) আর OpenSearch (খোঁজার জন্য)। বিস্তারিত লেসন ১৯.২-এ।
  • Security data, security analytics tool-এ। WAF log, VPC Flow Logs আর CloudTrail (CloudWatch Logs হয়ে) → Firehose → Splunk বা অন্য partner, ব্যর্থ data-র backup S3-এ।
  • Clickstream থেকে data lake। App event → Firehose (Lambda দিয়ে পরিষ্কার, Parquet, dynamic partitioning) → S3 → Glue Data Catalog → Athena আর dashboard। অধ্যায় ১৭-এ এই pipeline শুরু থেকে শেষ পর্যন্ত বানানো হবে।
  • Real-time সাথে archive। Kinesis data stream → live alert-এর জন্য Lambda, আর একই stream থেকে Firehose দিয়ে S3।
  • IoT। Sensor → AWS IoT Core rule → Firehose → ইতিহাসের জন্য S3, দরকার হলে real-time পথের জন্য আরেকটা rule।
  • Fan-out archive। Firehose subscription থাকা একটা SNS topic প্রতিটা publish করা message-এর একটা copy S3-এ রেখে দেয় (লেসন ১৩.৪)।
  • Stream থেকে সরাসরি table-এ। Firehose থেকে Iceberg table বা S3 Tables-এ পাঠালে এমন SQL table পাও যা data আসার সাথে সাথে বদলায়, আলাদা ETL job ছাড়াই (পাশের কথা; পরীক্ষায় এখনো খুব কমই আসে)।

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

Singapore-এ S3-এর দিকে একটা Firehose stream বানাও, কয়েকটা record পাঠাও, আর দেখো সেগুলো কীভাবে পৌঁছায়। Role আর bucket উদাহরণ মাত্র; role-কে firehose.amazonaws.com-কে trust করতে হবে, আর bucket-এ s3:PutObject allow করতে হবে।

# 1. Create a Direct PUT stream to S3: 1 MB or 60 seconds, gzip, custom prefix
aws firehose create-delivery-stream --region ap-southeast-1 \
  --delivery-stream-name clicks-example \
  --delivery-stream-type DirectPut \
  --extended-s3-destination-configuration '{
    "RoleARN": "arn:aws:iam::111122223333:role/firehose-clicks-example",
    "BucketARN": "arn:aws:s3:::clicks-lake-example",
    "Prefix": "clicks/",
    "ErrorOutputPrefix": "errors/",
    "BufferingHints": { "SizeInMBs": 1, "IntervalInSeconds": 60 },
    "CompressionFormat": "GZIP"
  }'
# {
#     "DeliveryStreamARN": "arn:aws:firehose:ap-southeast-1:111122223333:deliverystream/clicks-example"
# }

# 2. Wait until it is ACTIVE (about a minute)
aws firehose describe-delivery-stream --region ap-southeast-1 \
  --delivery-stream-name clicks-example \
  --query 'DeliveryStreamDescription.DeliveryStreamStatus'
# "ACTIVE"

# 3. Send one record (CLI v2 needs raw-in-base64-out to send plain text); add \n yourself
aws firehose put-record --region ap-southeast-1 --delivery-stream-name clicks-example \
  --cli-binary-format raw-in-base64-out \
  --record '{"Data":"{\"match\":\"BAN-IND\",\"event\":\"open_scorecard\"}\n"}'
# {
#     "RecordId": "aBcD1234...example",
#     "Encrypted": false
# }

# 4. Send a batch (up to 500 records or 4 MiB per call); always check FailedPutCount
aws firehose put-record-batch --region ap-southeast-1 --delivery-stream-name clicks-example \
  --cli-binary-format raw-in-base64-out \
  --records '[{"Data":"{\"event\":\"share\"}\n"},{"Data":"{\"event\":\"replay\"}\n"}]'
# {
#     "FailedPutCount": 0,
#     "Encrypted": false,
#     "RequestResponses": [ { "RecordId": "..." }, { "RecordId": "..." } ]
# }

# 5. About a minute later (the interval wins: far less than 1 MB was sent), one object appears
aws s3 ls s3://clicks-lake-example/clicks/ --recursive
# 2026-10-26 09:14:03        212 clicks/2026/10/26/09/clicks-example-1-2026-10-26-09-13-02-1a2b3c4d.gz

# 6. Check freshness: the age in seconds of the oldest undelivered record
aws cloudwatch get-metric-statistics --region ap-southeast-1 --namespace AWS/Firehose \
  --metric-name DeliveryToS3.DataFreshness \
  --dimensions Name=DeliveryStreamName,Value=clicks-example \
  --start-time 2026-10-26T09:00:00Z --end-time 2026-10-26T10:00:00Z \
  --period 300 --statistics Maximum

# 7. Clean up (Firehose has no fixed fee, but the bucket keeps costing)
aws firehose delete-delivery-stream --region ap-southeast-1 --delivery-stream-name clicks-example

API এখনো Firehose stream-কে delivery stream বলে, পুরোনো নামের রেশ। aws firehose update-destination দিয়ে hint বদলে দেখো (এর জন্য describe-delivery-stream থেকে এখনকার version ID লাগবে), আর file-এর size কীভাবে বদলায় লক্ষ করো।

#সারসংক্ষেপ

মূল কথাগুলো

  • Amazon Data Firehose (ফেব্রুয়ারি ২০২৪ পর্যন্ত নাম ছিল Kinesis Data Firehose) streaming data destination-এ তুলে দেয়: fully managed, serverless, automatic scaling, প্রতি GB-এ দাম, consumer code নেই, storage নেই, replay নেই।
  • Source (প্রতি stream-এ একটা): Direct PUT (SDK-এর PutRecord/PutRecordBatch, Kinesis Agent, CloudWatch Logs, IoT, EventBridge, SNS, WAF, VPC Flow Logs…), Kinesis Data Streams, Amazon MSK। Record ১,০০০ KiB পর্যন্ত।
  • Destination (প্রতি stream-এ একটা): S3, Redshift (আগে S3, তারপর COPY), OpenSearch, Iceberg table / S3 Tables, Splunk, Snowflake, partner (Datadog, New Relic, MongoDB…), custom HTTP endpoint।
  • Buffering: size (S3: ১–১২৮ MB, default ৫) অথবা interval (০–৯০০ s, default ৩০০), যেটা আগে পূরণ হয় তখন পাঠায়। Near real-time। ডিসেম্বর ২০২৩ থেকে zero buffering আছে; পুরোনো “কমপক্ষে ৬০ s” এখন আর ঠিক না।
  • Lambda transformation (CSV থেকে JSON, masking; Ok/Dropped/ProcessingFailed, ৫ মিনিট আর ৬ MB-এর সীমা), format conversion: Glue Data Catalog-এর schema দিয়ে JSON থেকে Parquet/ORC (Lambda লাগে না), dynamic partitioning: data-র ভেতরের key দিয়ে (শুধু S3, তৈরির সময়ই ঠিক হয়, ৫০০ active partition)।
  • ব্যর্থতা: retry, তারপর S3 backup (ব্যর্থ data বা সব data); Direct PUT-এ S3 ২৪ ঘণ্টা পর্যন্ত চেষ্টা, তারপর data হারায়; Redshift-এর manifest errors/-এ। At-least-once: S3, Iceberg আর Snowflake ছাড়া duplicate হতে পারে।
  • Data Streams বনাম Firehose: real-time, replay, অনেক consumer, নিজের code, shard বা on-demand → Data Streams। Storage-এ load, code নেই, near real-time, auto scaling → Firehose। প্রায়ই দুটোই: Data Streams → Firehose → S3।