IoT Platform ডিজাইন
- ●লক্ষ লক্ষ ডিভাইস থেকে টেলিমেট্রি ইনজেস্ট করতে MQTT ব্রোকার আর টাইম-সিরিজ ডেটাবেস লাগে।
- ●ডিভাইস রেজিস্ট্রি, কমান্ড চ্যানেল আর এজ প্রসেসিং মিলেই পুরো প্ল্যাটফর্ম দাঁড়ায়।
- ●অ্যালার্টিং আর ব্যাকপ্রেশার হ্যান্ডলিং না থাকলে স্কেলে সিস্টেম ভেঙে পড়ে।
ধরো তোমাকে একটা IoT প্ল্যাটফর্ম বানাতে বলা হলো — যেমন স্মার্ট মিটার, এগ্রি-সেন্সর, কিংবা ফ্যাক্টরির মেশিন মনিটরিং। লক্ষ লক্ষ ডিভাইস প্রতি কয়েক সেকেন্ডে ডেটা পাঠাবে, আর আমরা সেগুলো জমা করব, প্রসেস করব, দরকারে ডিভাইসকে কমান্ড পাঠাব। চলো, একজন সিনিয়র যেভাবে ইন্টারভিউতে এটা ভাঙে, সেভাবে ধাপে ধাপে এগোই।
১. সমস্যা বোঝা (Requirements)
প্রথমেই স্পষ্ট করতে হবে আমরা কী বানাচ্ছি।
ফাংশনাল রিকোয়ারমেন্ট:
- ডিভাইস রেজিস্ট্রেশন ও অথেন্টিকেশন (প্রতিটা ডিভাইসের আইডেন্টিটি)।
- টেলিমেট্রি ইনজেশন — সেন্সর রিডিং (তাপমাত্রা, ভোল্টেজ ইত্যাদি) জমা নেওয়া।
- ক্লাউড থেকে ডিভাইসে কমান্ড পাঠানো (যেমন "ভালভ বন্ধ করো")।
- টেলিমেট্রির উপর অ্যালার্টিং (থ্রেশহোল্ড ছাড়ালে নোটিফিকেশন)।
- ঐতিহাসিক ডেটা কুয়েরি ও ড্যাশবোর্ড।
নন-ফাংশনাল রিকোয়ারমেন্ট:
- স্কেল: ১ কোটি ডিভাইস, প্রতি ডিভাইস প্রতি ১০ সেকেন্ডে এক মেসেজ।
- Low latency ইনজেশন; অ্যালার্ট কয়েক সেকেন্ডের মধ্যে।
- High availability — ইনজেশন পাইপলাইন কখনো বন্ধ হলে চলবে না।
- ডিভাইস প্রায়ই constrained (কম CPU, কম ব্যান্ডউইথ, ব্যাটারি, অস্থির নেটওয়ার্ক)।
ভাবো ঢাকার লক্ষ লক্ষ রিকশায় একটা করে GPS লাগানো। প্রত্যেকে প্রতি ১০ সেকেন্ডে নিজের অবস্থান একটা কন্ট্রোল রুমে পাঠাচ্ছে। কন্ট্রোল রুম সব জমা রাখে, ম্যাপে দেখায়, আর কোনো রিকশা নিষিদ্ধ এলাকায় ঢুকলে সাথে সাথে সিগন্যাল পাঠায় — "ফিরে এসো"। এটাই IoT প্ল্যাটফর্মের মূল কাজ।
২. স্কেল আন্দাজ (Estimation)
ন্যাপকিন ম্যাথ না করলে ডিজাইন বাতাসে ভাসে।
ডিভাইস সংখ্যা = 10,000,000 (১ কোটি)
মেসেজ ইন্টারভাল = প্রতি 10 সেকেন্ডে 1টি
ইনজেস্ট রেট (avg) = 10^7 / 10 = 1,000,000 msg/sec (১০ লক্ষ/সে)
পিক (২x ধরি) = ~2,000,000 msg/sec
প্রতি মেসেজ সাইজ ≈ 200 bytes (payload + metadata)
ইনজেস্ট ব্যান্ডউইথ = 10^6 * 200 = 200 MB/sec ≈ 1.6 Gbps (avg)
দৈনিক মেসেজ = 10^6 * 86,400 ≈ 8.6 * 10^10 (৮৬ বিলিয়ন/দিন)
দৈনিক raw স্টোরেজ = 8.6*10^10 * 200B ≈ 17 TB/দিন (raw)
কম্প্রেশন ~10x => ~1.7 TB/দিন স্টোরড
কনকারেন্ট কানেকশন = ~10^7 পার্সিস্টেন্ট MQTT কানেকশন
প্রতি ব্রোকার ~10^5-10^6 কানেকশন => 10-100 ব্রোকার নোড
মূল উপলব্ধি: এটা write-heavy সিস্টেম, এবং কানেকশন সংখ্যা বিশাল। তাই কানেকশন ম্যানেজমেন্ট আর write throughput-ই মূল চ্যালেঞ্জ।
৩. API ডিজাইন
ডিভাইস বেশিরভাগ সময় MQTT টপিকে কথা বলে, কিন্তু রেজিস্ট্রি ও কুয়েরির জন্য REST থাকে।
# MQTT টপিক স্ট্রাকচার (ডিভাইস <-> ব্রোকার)
PUBLISH devices/{deviceId}/telemetry # ডিভাইস ডেটা পাঠায়
SUBSCRIBE devices/{deviceId}/commands # ডিভাইস কমান্ড শোনে
PUBLISH devices/{deviceId}/command/ack # কমান্ডের ফলাফল ফেরত
# REST API (ব্যাকএন্ড / অ্যাডমিন)
POST /v1/devices # নতুন ডিভাইস রেজিস্টার (cert/key ইস্যু)
GET /v1/devices/{id} # ডিভাইস স্ট্যাটাস ও মেটাডেটা
POST /v1/devices/{id}/commands # কমান্ড এনকিউ করা
body: { "action": "valve_close", "args": { "id": 3 } }
GET /v1/devices/{id}/telemetry?from=...&to=...&metric=temp&agg=avg&window=1m
GET /v1/alerts?status=active
লক্ষ করো — কমান্ড API সিনক্রোনাসভাবে ডিভাইসে পৌঁছায় না; এটা শুধু কমান্ড এনকিউ করে, ডিভাইস অনলাইন হলে ডেলিভারি হয়।
৪. ডেটা মডেল
দুই ধরনের ডেটা আলাদা স্টোরেজ চায়: ধীরে বদলায় এমন মেটাডেটা, আর দ্রুত আসা টেলিমেট্রি।
| ডেটা | বৈশিষ্ট্য | স্টোরেজ চয়েস |
|---|---|---|
| Device Registry | কম রাইট, key-by-id রিড | PostgreSQL / DynamoDB |
| Telemetry | বিশাল রাইট, time-range রিড | Time-Series Database (InfluxDB/Timescale) |
| Commands | queue, short-lived | Kafka / Redis Stream |
| Alerts state | মাঝারি, lookup | PostgreSQL |
Telemetry স্কিমা (টাইম-সিরিজ):
measurement: telemetry
tags: device_id, region, type # indexed, low-cardinality
fields: temp, voltage, battery # actual values
time: 2026-06-21T10:00:00Z # primary axis
কেন time-series DB? কারণ এটা টাইমস্ট্যাম্প-অর্ডারড ডেটায় চমৎকার কম্প্রেশন দেয়, পুরোনো ডেটা স্বয়ংক্রিয়ভাবে downsample ও retention দিয়ে মুছে ফেলতে পারে। সাধারণ relational টেবিলে প্রতি সেকেন্ডে ১০ লক্ষ row ঢোকালে ইনডেক্স ফুলে যাবে।
টিপ: tag-এ high-cardinality ফিল্ড (যেমন raw timestamp বা random id) রেখো না — তাতে time-series DB-র series সংখ্যা বিস্ফোরিত হয়।
৫. হাই-লেভেল ডিজাইন
মূল কম্পোনেন্টগুলো:
- MQTT Broker Cluster — ডিভাইসের পার্সিস্টেন্ট কানেকশন রাখে (যেমন EMQX/VerneMQ)।
- Ingestion / Bridge — ব্রোকার থেকে মেসেজ তুলে একটা message queue (Kafka)-এ ঠেলে দেয়। এতে স্টোরেজ আর ব্রোকার ডিকাপলড হয়।
- Stream Processor — Kafka থেকে পড়ে: ভ্যালিডেট, এনরিচ, time-series DB-তে লেখে, আর অ্যালার্ট রুল চেক করে।
- Time-Series DB — টেলিমেট্রি স্টোরেজ ও কুয়েরি।
- Device Registry — পরিচয়, অথ, শ্যাডো/স্টেট।
- Command Service — কমান্ড এনকিউ করে, ব্রোকারের মাধ্যমে ডিভাইসে পাঠায়।
- Alerting + Notification — থ্রেশহোল্ড ভাঙলে SMS/push/webhook।
টেলিমেট্রি ফ্লো:
Device --(MQTT publish)--> Broker --> Ingest Bridge --> Kafka topic
Kafka --> Stream Processor --> [Time-Series DB] + [Alert Engine]
|
Dashboard / API <-- ব্যবহারকারী
কমান্ড ফ্লো:
Admin/API --> Command Service --> Kafka(commands) --> Broker
--> devices/{id}/commands টপিক --> Device executes --> ack ফেরত
মাঝখানে Kafka রাখার মূল কারণ — ব্যাকপ্রেশার। ডাউনস্ট্রিম DB ধীর হলেও Kafka বাফার করে রাখে, মেসেজ হারায় না।
৬. গভীরে (Deep Dive)
(ক) কানেকশন স্কেল ও MQTT
১ কোটি পার্সিস্টেন্ট TCP কানেকশন এক মেশিনে ধরবে না। প্রতি ব্রোকার নোড হয়তো ১০ লক্ষ কানেকশন রাখতে পারে, তাই আমরা horizontally ব্রোকার ক্লাস্টার করি, সামনে একটা L4 load balancer। MQTT-তে QoS লেভেল গুরুত্বপূর্ণ: QoS 0 (at most once, দ্রুত কিন্তু হারাতে পারে), QoS 1 (at least once, ডুপ্লিকেট সম্ভব), QoS 2 (exactly once, ব্যয়বহুল)। বেশিরভাগ টেলিমেট্রির জন্য QoS 1 যথেষ্ট, আর কমান্ডের জন্য QoS 1 + idempotent হ্যান্ডলিং।
(খ) Device Shadow ও কমান্ড ডেলিভারি
ডিভাইস প্রায়ই অফলাইন থাকে। তাই আমরা device shadow রাখি — ডিভাইসের কাঙ্ক্ষিত ও বর্তমান স্টেটের একটা JSON কপি ক্লাউডে। কমান্ড এলে shadow-র "desired" আপডেট হয়; ডিভাইস অনলাইন হলে diff সিঙ্ক করে। ডেলিভারি গ্যারান্টি নিশ্চিত করতে কমান্ড persisted queue-তে রাখি আর ডিভাইসের ack না পেলে retry করি (ব্যাকঅফসহ)।
(গ) এজ প্রসেসিং
সব raw ডেটা ক্লাউডে পাঠানো ব্যয়বহুল। Edge gateway ফ্যাক্টরি/সাইটে বসে: ডেটা ফিল্টার করে (শুধু পরিবর্তন হলে পাঠাও), লোকাল অ্যাগ্রিগেশন করে (প্রতি ১ মিনিটের গড়), আর ইন্টারনেট গেলেও লোকাল রুল চালিয়ে যন্ত্র বন্ধ করার সিদ্ধান্ত নিতে পারে। এতে latency কমে আর ব্যান্ডউইথ বাঁচে।
টেলিমেট্রি আর কমান্ড পথকে কখনো এক DB-তে সিনক্রোনাসভাবে বাঁধবে না। DB ধীর হলে যদি ইনজেশন থেমে যায়, লক্ষ লক্ষ ডিভাইস রিট্রাই শুরু করবে — এটাকে বলে retry storm, যা পুরো ক্লাস্টার ধসিয়ে দিতে পারে। সবসময় queue দিয়ে ডিকাপল করো।
৭. বটলনেক ও স্কেলিং
- Hot partition: Kafka-তে যদি device_id দিয়ে পার্টিশন করো আর কিছু region খুব busy হয়, পার্টিশন আনব্যালান্সড হবে। সমাধান: যথেষ্ট পার্টিশন + ভালো hashing।
- TSDB write আনতে পারছে না: Batch write, downsampling, আর পুরোনো ডেটা cold storage (S3)-এ সরিয়ে নাও।
- Connection স্ট্রম (mass reconnect): নেটওয়ার্ক ফিরে এলে সব ডিভাইস একসাথে কানেক্ট করে। ডিভাইস ফার্মওয়্যারে randomized jittered backoff বসাও।
- Alert engine: প্রতি মেসেজে DB hit না করে in-stream রুল ইভ্যালুয়েশন (Flink/Kafka Streams) করো।
- Multi-region: ডিভাইসকে নিকটতম region-এ রুট করো (GeoDNS), আর region-ভিত্তিক ব্রোকার ও TSDB রাখো।
৮. সারসংক্ষেপ
IoT প্ল্যাটফর্মের কেন্দ্রে দুটো জিনিস: বিশাল সংখ্যক পার্সিস্টেন্ট কানেকশন (MQTT broker cluster) আর প্রচণ্ড write throughput (queue + time-series DB)। মেটাডেটা আর টেলিমেট্রি আলাদা স্টোরেজে রাখো, কমান্ডের জন্য shadow + persisted queue ব্যবহার করো, আর এজ প্রসেসিং দিয়ে ক্লাউডের লোড কমাও। সবকিছুর মাঝে একটা message queue ব্যাকপ্রেশারের ঢাল হিসেবে কাজ করে।
ইন্টারভিউতে প্রথমেই বলো: "এটা write-heavy আর কানেকশন-heavy সিস্টেম।" এই এক বাক্য তোমার পুরো ডিজাইনের দিক ঠিক করে দেবে — MQTT, queue, আর time-series DB স্বাভাবিকভাবেই বেরিয়ে আসবে।
মিনি কুইজ
1. লক্ষ লক্ষ ডিভাইসের কনস্ট্যান্ট কানেকশনের জন্য কোন প্রোটোকল সবচেয়ে উপযুক্ত?
2. বিপুল পরিমাণ সময়-ভিত্তিক সেন্সর ডেটা রাখার জন্য কোন স্টোরেজ সবচেয়ে ভালো?
3. এজ প্রসেসিং কেন দরকার?