আজকের আর্টিকেলে আমরা আলোচনা করব কীভাবে আপনি আপস্ট্যাশের সুবিধা নিতে পারেন একটি দেশের শেল্টার ম্যাপ সম্পর্কে ইনফরমেশন নিরাপদে সংরক্ষণ ও অ্যাক্সেস করতে রেডিস ব্যবহার করে, এবং রিয়েল-টাইমে ডাটাবেস আপডেট করতে QStash ব্যবহার করে।
ভূমিকা
বর্তমান গ্লোবাল প্রেক্ষাপটে, প্রাকৃতিক দুর্যোগ এবং সৈনিক হুমকি ngày দিন প্রাধান্য পাচ্ছে। তাই সোশ্যাল সার্ভিসেস এলাকায় ডিজিটালাইজেশনের দরকারও বাড়ছে।
AMBER অ্যালার্টের মতো ইমারজেন্সি ব্রডকাস্ট সিস্টেম থেকে COVID-19 ট্র্যাকিং অ্যাপ এবং SOS সিস্টেম পর্যন্ত, আমরা 어떤 ধরনের খতরনাক পরিস্থিতি যা একটি দেশকে প্রভাবিত করে সেটি মোকাবিলা করার জন্য ব্যাপক প্রযুক্তি ব্যবহার দেখেছি।
এখন, আমরা দেখব কীভাবে রেডিস এবং সার্ভারলেস ওয়ার্কলোড একটি রিয়েল-টাইম ইমারজেন্সি রেসপন্স সিস্টেম বিল্ড করতে একটি কী রোল পালন করতে পারে যা সিটিজেনদের নিকটতম বাঙ্কার খুঁজে পেতে সাহায্য করে, এবং তাদের ক্যাপাসিটি, ফিচার (যেমন অক্ষম ব্যক্তিদের সুবিধা) এবং রিসোর্স (পানি, বিদ্যুৎ, ঔষধ ইত্যাদি) সম্পর্কে জানানোর দরকার।
Courtesy of Project Cloud4
কেন সার্ভারলেস?
সার্ভারলেস কনসেপ্ট গত কয়েক বছরে ডেভেলপারদের মধ্যে জনপ্রিয় হয়েছে। আমরা সার্ভারলেস আর্কিটেকচার ফলো করার 스타ার্টআপ সংখ্যা বৃদ্ধি এবং বড় কর্পোরেশনে বর্ধমান দত্তক 见েছি।
বিশেষ করে স্টেট এক্টরদের কথা বললে, একটি র্যাপিড ডেভেলপমেন্ট এনভায়রনমেন্ট এবং অটো-ম্যানেজড সার্ভিসেস ইমারজেন্সি রেসপন্স সিস্টেম বিল্ড করার জটিলতা এবং ওভারহেড 劇적으로 কমাতে পারে। আমাদের দুটি অন্য ফ্যাক্টরও বিবেচনা করতে হবে:
- বাজেট: যদি কোনো দেশ কোনো ইমারজেন্সি ডিজাস্টারের মধ্য দিয়ে না যায়, কোনো ডিসিশন মেকিং রোলের ব্যক্তি কি অনইউজড কম্পিউট পাওয়ারের জন্য পেমেন্ট অনুমোদন করবেন? আমি শंকা করি।
- ট্রাফিক স্পাইক: কল্পনা করুন একটি অ্যালার্ম ট্রিগার হয় এবং মিলিয়ন মিলিয়ন মানুষ ওয়েব প্ল্যাটফর্মে নিকটতম শেল্টার খুঁজতে অ্যাক্সেস করে। আপনার REST API এই হঠাৎ rps (রিকোয়েস্ট-পার-সেকেন্ড) বৃদ্ধি কীভাবে হ্যান্ডেল করবে? এসেনশিয়াল রিয়েল-টাইম কম্পোনেন্টগুলো কীভাবে?
এই সব ভিন্ন প্রশ্নের উত্তর দিতে পারে আপস্ট্যাশ এবং Ably-এর মতো সত্যিকারের সার্ভারলেস প্ল্যাটফর্ম যা অটো-স্কেল করে এবং শুধু ব্যবহৃত রিসোর্সের জন্য চার্জ করে।
কেন রেডিস?
আমাদের প্রজেক্টের ডেটা রিকোয়্যারেমেন্টে বিভিন্ন অ্যালগরিদমিক অপারেশন থাকে যা সর্বোচ্চ সম্ভব গতিতে করা উচিত। একটি শেল্টারের ইনফরমেশন রিপ্রেজেন্ট করার জন্য বেসিক ডেটা স্ট্রাকচার থেকে একটি লোকেশনে উপলব্ধ শেল্টারগুলো বিভিন্ন ক্রাইটেরিয়া দিয়ে সর্ট করার সহজ উপায় পর্যন্ত, রেডিস আমাদের NoSQL ডাটাবেসের ফ্লেক্সিবিলিটি রক্ষা করতে দেয়, এবং ডেভেলপমেন্ট সহজ ও দ্রুত করার জন্য বিভিন্ন ফাংশন প্রদান করে।
কেন QStash?
ট্রেডিশনাল মেসেজ কিউ ইভেন্ট-ড্রিভেন সিস্টেম আর্কিটেকচার করার একটি স olid উপায় প্রদান করে, কিন্তু একটি ক্যAVEAT আছে: অধিকাংশ তারা AMPQ-এর মতো স্টেটফুল প্রোটোকোলের ওপর সম্পূর্ণরূপে নির্ভরশীল, অর্থাৎ সেগুলো সার্ভারলেস ফাংশনের মতো শর্ট-রানিং এনভায়রনমেন্টে ব্যবহার করার জন্য প্রস্তুত নয়।
QStash এই সমস্যাটি সমাধান করে HTTP ব্যবহার করে রিকোয়েস্ট করার অনুমতি দিয়ে, যা সার্ভারলেস এনভায়রনমেন্টে টিপিক্যালি ব্যবহৃত একটি স্টেটলেস প্রোটোকোল। সেটিকে ওয়েবহুকসের সাথে কম্বাইন করে, আমরা ডেটা ডাটাবেস থেকে এবং ডাটাবেসে আপডেট ও ফেচ করার জন্য রিয়েল-টাইম পাইপলাইন তৈরি করতে পারি।
প্রয়োজনীয়তা
P.S.: আপনি যদি শুধু স্যাম্পলগুলো দেখতে চান, রিকোয়্যারেমেন্টস এবং সেটআপ সেকশন স্কিপ করুন। সেগুলো দেখাতে দিয়েছে আমরা কী ব্যবহার করছি এবং কীভাবে।
আপনি যদি নিজে এই ধরনের সিস্টেম বিল্ড করতে চান, আপনাকে নিচের موارد দরকার:
- একটি আপস্ট্যাশ অ্যাকাউন্ট, যেখান থেকে আপনি একটি রেডিস ডাটাবেস তৈরি করবেন এবং একটি QStash এন্ডপয়েন্ট বা টপিক ব্যবহার করবেন;
- একটি Ably অ্যাকাউন্ট এবং একটি ওয়েবহুক ইন্টিগ্রেশন সেটআপ
- একটি Next.js প্রজেক্ট;
- ngrok-এর মতো একটি টানেলিং সার্ভিস যদি আপনি লোকাল রিকোয়েস্টকে ইন্টারনেট-অভেইলেবল URL-এ প্রক্সি করতে চান;
- রিকোয়েস্টেড লাইব্রেরি সাপোর্ট করে যেকোনো প্যাকেজ ম্যানেজার। এই আর্টিকেল npm ব্যবহার করবে, কিন্তু এটা বাধ্যতামূলক নয়।
NOTE: এই আর্টিকেল কিছু বেসিক প্রুফ-অফ-কনসেপ্ট স্যাম্পল প্রদান করবে উক্ত প্রযুক্তিগুলো আমাদের অ্যাপ্লিকেশনের আর্কিটেকচারের প্রেক্ষাপটে ডেমো করার জন্য। দেওয়া কোডটি প্রোডাকশন রেডি নয় এবং বেটার রিডিংয়ের জন্য সিম্পলিফাইড ও শর্টেন করা হয়েছে। ডিপ্লয় করতে চান তবে আশ্বস্ত হন যে আপনি প্রয়োজনীয় মডিফিকেশন করলেন (এক্সেপশন হ্যান্ডলিং, সিকিউরিটি, ইত্যাদি)
সেটআপ
সার্ভারলেস ফাংশন
আমরা Next.js-এর এজ API রাউট ব্যবহার করব সার্ভারলেস ওয়ার্কলোড ইউজারের লোকেশনের কাছাকাছি চালানোর জন্য।
একটি Next.js প্রজেক্ট তৈরি করতে npx create-next-app@latest <your-app-name> পেরেন্ট ডিরেক্টরিতে চালান। তারপর আপনি npm run dev চালাতে পারেন ডেভেলপমেন্ট সার্ভার শুরু করতে, npm run build প্রোডাকশন বান্ডেল তৈরি করতে, এবং npm run start প্রোডাকশন সার্ভার শুরু করতে।
Next.js API রাউটের জন্য ডিফল্ট হিসেবে নোড এনভায়রনমেন্ট ব্যবহার করে। আমরা এটা দুইভাবে চেঞ্জ করতে পারি:
- পের-রাউট অ্যাপ্রোচ। ডিজায়ারড রাউটে নিচের এক্সপোর্ট যোগ করুন:
export const config = { runtime: "experimental-edge", }; - গ্লোবাল অ্যাপ্রোচ। edge কে ডিফল্ট রানটাইম बनाने için, আপনার next.config.js ফাইলে নিচের টুকরো যোগ করুন:
const nextConfig = { // ... experimental: { runtime: "experimental-edge", }, // ... };
আপস্ট্যাশ
আপস্ট্যাশ প্রোভাইডার তৈরি করতে এই গাইড ফলো করুন।
একটি QStash-রিসিভার রাউট সেটআপ করতে এই গাইড ফলো করুন। নোট করুন যে Ably আমাদের ওয়েবহুক মেসেজ এনকোডিংয়ের জন্য দুই অপশন দেয়, JSON এবং MessagePack। আপনি যদি ফর্মার ব্যবহার করতে চান, তবে আপনাকে JWT-এর বদলে অথরাইজেশন হেডার ব্যবহার করতে হতে পারে পটেনশিয়াল এনক্রিপশন কম্প্যাটিবিলিটি প্রোবলেমের কারণে। সিম্পলিসিটির জন্য আমরা JSON-এ থাকব।
Ably
রিয়েল-টাইম ফাংশনালিটির জন্য, আমরা Ably-এর প্রোটোকল ব্যবহার করব, যা পসিবল হলে WebSocket-এ ডিফল্ট করে। শুরু করতে এই গাইড ফলো করুন এবং, যেহেতু আমরা Next.js ব্যবহার করছি, আপনি @ably-labs/react-hooks npm প্যাকেজে এক নজর দিতে পারেন।
আমাদের একটি ওয়েবহুক ইন্টিগ্রেশনও সেটআপ করা উচিত যেটি আমাদের QStash URL-এ পয়েন্ট করবে, এবং যেকোনো প্রয়োজনীয় হেডার যোগ করবে।
আপনি যদি প্রোডাকশনে যান, অথেন্টিকেশন এবং সিকিউরিটি চেক করুন।
ঐচ্ছিক: লোকাল টানেলিং
ngrok-এর সাথে শুরু করতে এই গাইড ফলো করুন
আর্কিটেকচার
ফ্লো
আমাদের অ্যাপ্লিকেশনের ফ্লো ভালো বুঝতে, এই ডায়াগ্রামটি দেখুন (excalidraw.com-এ তৈরি):

আপনি দেখতে পাচ্ছেন আমরা দুটি টাইপের ইউজার ডিফাইন করেছি:
- দ্য সিটিজেন, যিনি একটি শেল্টার বা লোকেশনের ইনফো অ্যাক্সেস করতে পারেন, এবং একটি বাঙ্কারে যাওয়ার ইচ্ছা ঘোষণা করতে পারেন
- দ্য অ্যাডমিন, যারা একটি বাঙ্কারের লজিস্টিক্স ডেটা এবং অভailability মডিফাই করতে পারেন (যেমন, কনফার্ম করা যে একজন ব্যক্তি/পরিবার লোকেশনে পৌঁছেছে)
আমরা ডেটা রিয়েল-টাইমে উপলব্ধ রাখতে চাই যখন ফ্রন্টএন্ড এবং ব্যাকএন্ড যতটা সম্ভব ডিকাপল্ড রাখা। তাই আমরা একটি Ably চ্যানেল ব্যবহার করব ক্লায়েন্টের সাথে কমিউনিকেশন এবং একটি ওয়েবহুক ট্রিগার করার জন্য هر তєм্পল availability পরিবর্তন হলে।
এছাড়া, আমরা Ably-এর REST API ব্যবহার করব ব্যাকএন্ড থেকে মেসেজ পাবলিশ করার জন্য, কারণ আমাদের যেকোনো স্টেটফুল কানেকশন ব্যবহার করা উচিত নয়।
ডেটা
বর্তমানে আমাদের দুটি মেইন ডেটা টাইপ সংরক্ষণ করতে হয়:
-
একটি শেল্টারের ইনফরমেশন, যা একটি রেডিস হ্যাশের আকার নিতে পারে এবং নিচের প্রপার্টিগুলো থাকতে পারে:
- কির নাম
country-city-numberহিসেবে (যেমন:RO-CJ-01) - availability (যেমন:
300) - features (যেমন:
["disabled persons special acces", "counseling"]) - resources:
উদাহরণ:{ resource: quantity, or resource: list ... }{ "water": "200 liters", "medicine": ["insuline", ...] } - electricity:
yes/no - heating:
yes/no - position:
[longitude, latitude]বা{ longitude: number, latitude: number } - _id: আমরা এটি র্যান্ডমলি জেনারেট করব
- কির নাম
-
একটি লোকেশনের ইনফরমেশন
যদিও আমরা করতে পারি একটি নেস্টেড কোয়েরি করে নির্দিষ্ট লোকেশনের জন্য উপলব্ধ শেল্টার খুঁজে বের করতে, তবে সেগুলো আলাদা একটি ডেটা স্ট্রাকচার হিসেবে সংরক্ষণ করা ভালো আইডিয়া যাতে কোয়েরি সিম্পলিফাই ও অপ্টিমাইজ হয়। এটি করার জন্য, আমরা একটি রেডিস সেট ব্যবহার করতে পারি এবং এলিমেন্টের নাম দিতে পারি
<geographical-unit>-<name>(যেমন:country-ROবাcity-CJ)। এইভাবে আমরা ডুপ্লিকেশনও প্রতিরোধ করছিউদাহরণ:
city-CJ : ["RO-CJ-01", "RO-CJ-02", "RO-CJ-03"]
এখনও একটি সমস্যা আছে: কীভাবে আমরা একজন সিটিজেনের বাঙ্কারে যাওয়ার ইচ্ছা এবং একটি আসল occupancy আপডেট যা শেল্টারের অ্যাডমিন দ্বারা কনফার্ম করা হয়েছে — এদের মধ্যে পার্থক্য করব? আমরা দুটি উপায়ে করতে পারি:
-
শেল্টারের availability কি কনস্ট্যান্টলি আপডেট করুন: একজন ইউজার তার যাওয়ার ইচ্ছা ঘোষণা করে (একা বা পরিবারের সাথে) => আমরা x দ্বারা ইনক্রিমেন্ট করি; অ্যাডমিন খুঁজে পায় কনফার্মেশন বৈধ নয় => আমরা x দ্বারা ডিক্রিমেন্ট করি (অথবা -x দ্বারা ইনক্রিমেন্ট করি)
এখানে সমস্যা হলো অ্যাডমিনকে সোর্স অফ 트ুথ হিসেবে কাজ করতে হবে এবং সিটিজেনের লোকেশন ট্র্যাক রাখতে হবে; এছাড়া, শেল্টারের ডেটা অবিলম্বে বিশ্বাসযোগ্য নয়
-
একটি আলাদা স্ট্রিং কি তৈরি করুন নাম
shelter-"availability"(যেমন:RO-CJ-01-availability) এবং রিয়েল-টাইম আপডেটেড ভ্যালু সংরক্ষণ করুন। এইভাবে আমরা রিয়েল-টাইমে আপডেট করতে পারি, এবং আমাদের হ্যাশের availability কিকে সোর্স অফ ট্রুথ হিসেবে রাখতে পারি।নোট করুন যে ক্লায়েন্ট সাইডে আমরা হ্যাশ এবং স্ট্রিং কি দুটো ফেচ করব, এবং সেগুলো আকচুয়াল availability এবং প্রজেক্টেড availability হিসেবে প্রেজেন্ট করব। একটি অল্টারনেটিভ অ্যাপ্রোচ হলো শুধু স্ট্রিং ফেচ করা এবং প্রয়োজনে সোর্স অফ ট্রুথে রিভার্ট করা। যদিও এটি নেটওয়ার্ক লোড কমাবে, অ্যাডমিনকে অবিচ্ছিন্ন ডেটা ভেরিফাই করতে হবে (প্রথম সিনেরিওর মত) এবং, আসলে কম ফেচ করতে হলে, আমাদের শেল্টারের availability কি আলাদা সংরক্ষণ করতে হবে (মনে রাখুন, আমাদের এখনও অন্য ইনফরমেশন পেতে হচ্ছে!)।
সর্টিং
রেডিস ডেটা টাইপের আরেকটি টাইপ নেওয়া যাক যেটি বলা হয় sorted set। maan লই, আমরা একটি লোকেশনে উপলব্ধ বাঙ্কারগুলো availability, facilities বা available resources দিয়ে সর্ট করতে চাই: যেমন আমি আগে বলেছি, আমরা নেস্টেড কোয়েরি করতে পারি কিন্তু টাইম এবং অনেক বড় ডেটা লোডের কাস্টে। একটি ভালো সমাধান হবে প্রতিটি ফিল্টারিং ক্রাইটেরিয়ার জন্য সর্টেড সেট তৈরি করা (আমরা সেগুলো নাম দিতে পারি <geographical-unit>-<name>-<criteria>, যেমন city-CJ-availability বা country-RO-food)
উদাহরণ: city-B-availability
এই উদাহরণে, availability স্কোর ক্যালকুলেট করা হয়েছে total seats - current occupation হিসেবে।
উদাহরণ
আমরা কিছু বেসিক কোড লিখতে পারি আমাদের API এবং ক্লায়েন্টের বিহেবিয়ার ডেমো করার জন্য
এন্ডপয়েন্টস
প্রধানত, আমাদের দরকার:
- একটি ডেটা এন্ডপয়েন্ট যা ক্লায়েন্টকে যেকোনো রিকোয়েস্টেড ইনফরমেশন সার্ভ করবে এবং
- আমাদের ডেটা টাইপ তৈরি বা আপডেট করার একটি এন্ডপয়েন্ট
ক্লায়েন্ট
ইউজারের লোকেশন ট্র্যাক করার পর আমরা অটোমেটিক্যালি "availability" চ্যানেলের সাথে কানেক্ট করব এবং একটি মেসেজ পাবলিশ করব যদি সিটিজেন বাঙ্কারে যাওয়ার ইচ্ছা রাখে।
প্রথমে, /_app.js ফাইল থেকে একটি কানেকশন বানাই:
import { useEffect, useState } from "react"; import "../styles/globals.css"; import { configureAbly } from "@ably-labs/react-hooks"; export default function App({ Component, pageProps }) { const [loaded, setLoaded] = useState(false); useEffect(() => { configureAbly({ // প্রোডাকশন সিস্টেমে, আপনার অথেনটিকেশন কি ব্যবহার করুন key: process.env.NEXT_PUBLIC_ABLY_API_KEY, }); setLoaded(true); }, []); if (!loaded) return <div>loading...</div>; return <Component {...pageProps} />; } তারপর যে কোনো কম্পোনেন্টে চ্যানেলের সাথে কানেক্ট করুন:
import { useChannel } from "@ably-labs/react-hooks"; export default function Test() { const [availability] = useChannel("availability", (msg) => { console.log(msg); }); return <></>; } ডাটাবেসের সাথে কাজ করা
নতুন ডেটা যোগ করা
রেডিসে নতুন ডেটা যোগ করতে আমরা HSET, SET এবং SADD কমান্ড ব্যবহার করতে পারি
export default async (req) => { let data = await req.json(); if (data.type === "shelter") { // 'type' কি রিমুভ করুন কারণ এখন এটা প্রয়োজন নেই delete data.type; const { name: shelter, availability } = data; let shelterData = data; // একটি র্যান্ডম id জেনারেট করুন। shelterData._id = Math.random() .toString(36) .replace(/[^a-z]+/g, "") .substring(0, 7); // শেল্টারের ইনফো হ্যাশ হিসেবে সংরক্ষণ করুন await redis.hset(shelter, shelterData); // রিয়েল-টাইম আপডেটেড availability স্ট্রিং হিসেবে সংরক্ষণ করুন await redis.set(shelter + "-availability", availability); return new Response("ok"); } else if (data.type === "location") { const { name: location, shelters } = data; await redis.sadd(location, ...shelters); return new Response("ok"); } }; এক্সিস্টিং ডেটা আপডেট করা
বেসিক UD (আপডেট-ডিলিট) অপারেশনের বাইরে, আমরা রেডিস INCRBY এবং HINCRBY কমান্ড ব্যবহার করতে পারি শেল্টারের availability মডিফাই করতে।
যদি একজন সিটিজেন একটি বাঙ্কারে যাওয়ার ইচ্ছা ঘোষণা করে, আমরা ক্লায়েন্ট অ্যাপ থেকে একটি মেসেজ পাবলিশ করতে পারি
availability.publish("update", { shelter: "RO-CJ-01", availability: 1, // অথবা -x, যদি ইউজার ক্যান্সেল করে। }); আর্কিটেকচারে ব্যাখ্যা করা মত, এটি একটি ওয়েবহুক ট্রিগার করবে যেখান থেকে আমরা ডেটা নিতে পারি এবং shelter-"availability" কি আপডেট করতে পারি।
await redis.incrby(shelter + "-availability", value); আপনি যদি সার্ভার থেকে আপডেট করেন (যেমন: অ্যাডমিন কনফার্মেশন), REST API ব্যবহার করা ভুলবেন না।
ডেটা রিট্রিভ করা
সার্ভারে, আমরা GET, SMEMBERS এবং HGETALL কমান্ড ব্যবহার করতে পারি।
ক্লায়েন্টে, আমরা চ্যানেলে মেসেজ শোনতে পারি এবং স্টেট যথার্থ আপডেট করতে পারি।
সংক্ষেপে
আজ আমরা দেখেছি কীভাবে একটি পাওয়ারফুল সার্ভারলেস আর্কিটেকচার লিভারেজ করে একটি রিয়েল-ওয়ার্ল্ড ইমারজেন্সি ট্র্যাকিং অ্যাপ বিল্ড করা যায়। যদিও এটি করার একাধিক পদ্ধতি আছে, আমি পারসোনালি এই ধরনের ফ্লো যেতে সুপারিশ করি ডেভেলপার এক্সপেরিয়েন্স সিম্পলিফাইড হওয়ার কারণে।
হয়তো আপনি একজন সিনিয়র ডেভেলপার যিনি ডিস্ট্রিবিউটেড কম্পিউটিং সিস্টেম বিল্ড করার অভ্যাসী এবং একটি ম্যানেজড সার্ভিসের দরকার অনুভব করেন। অথবা, আপনি একজন বिगিনার কিন্তু আপনার একটি আইডিয়া আছে যা ভালোর জন্য dunia বদলাতে পারে। সঠিক টুল খুঁজে পাওয়া সবসময় প্রসেসের একটি অপরিহার্য অংশ।
এই আর্টিকেল সম্পর্কে আপনার মতামত জানাতে পারেন, এবং আপনার কোনো প্রশ্ন থাকলে লিংকডইনে মেসেজ করুন বা আমার গিটহাবে অন্যান্য কোড চেক করুন।