কম্পিউটার টিউটোরিয়াল

Redis Pub/Sub মাস্টার করুন: একটি প্রায়োগিক হাউ-টু গাইড

Redis pub/sub-এ আমাদের ওভারভিউ আর্টিকেলে pub/sub-এর উদ্দেশ্য এবং Redis pub/sub-এর ডিজাইন চয়েসগুলো আলোচনা করা হয়েছে। এখন আমরা Redis pub/sub কিভাবে ব্যবহার করতে হয় সেটা দেখব, প্রতিটি মূল কনসেপ্ট ধাপে ধাপে: চ্যানেল, পাবলিশিং, সাবস্ক্রাইবিং, এবং প্যাটার্ন ম্যাচিং - Node.js-এর node-redis ক্লায়েন্ট ব্যবহার করে।

চ্যানেল বোঝা

একটি চ্যানেল হলো একটি নাম যা pub/sub সিস্টেমে পাবলিশ হওয়া মেসেজ ক্যাটাগরাইজ করতে ব্যবহৃত হয়। চ্যানেলের নাম সিস্টেম-ডিপেন্ডেন্ট হতে পারে, যেমন system-health:i-36a44b83, trade-prices:RAX, temp-reading:living-room, অথবা খুব জেনেরিক কিছু, যেমন events। চ্যানেলে আসা ডেটা যেকোনো সাবস্ক্রাইবার শুনতে পারে, এবং নতুন পাবলিশার ও সাবস্ক্রাইবার সিস্টেম বড় হওয়ার সাথে সাথে সহজে যোগ করা যায়।

একটি Redis সার্ভারে কোন চ্যানেলগুলো এক্টিভ আছে তা জানতে আপনি PUBSUB CHANNELS কমান্ড ব্যবহার করতে পারেন, যা কিছুই রিটার্ন করে না যখন সিস্টেম এখনো pub/sub-এর জন্য ব্যবহার হচ্ছে না:

$ redis-cli pubsub channels (empty list or set)

চ্যানেল সিস্টেমে তখনই এক্সিস্ট করে যখন সেটায় কোনো সাবস্ক্রাইবার মেসেজ শোনার জন্য লিসেন করে থাকে, তাই চ্যানেল "ক্রিয়েট" বা "রিমুভ" করার দরকার নেই - সেগুলো শুধু তখন পর্যন্ত এক্সিস্ট করে যতক্ষণ একটি সাবস্ক্রাইবার লিসেন করছে। এটি দেখতে আমরা redis-cli ব্যবহার করে একটি কনসোল উইন্ডোতে সাবস্ক্রাইবার হিসেবে কাজ করব, এবং অন্য উইন্ডোতে PUBSUB CHANNELS আবার রান করব:

Console 1:

$ redis-cli subscribe events
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "events"
3) (integer) 1

Console 2:

$ redis-cli pubsub channels
1) "events"

Console 1 ডিসকানেক্ট होते সিস্টেমে আবার কোনো চ্যানেল থাকবে না।

মেসেজ পাবলিশ করা

কমান্ড সিন্ট্যাক্স

PUBLISH কমান্ডটি মেসেজ পাবলিশ করতে ব্যবহৃত হয়।

PUBLISH channel message

চ্যানেলে লিসেন করা সব সাবস্ক্রাইবারকে মেসেজ পাঠানো হবে। যদি মেসেজ রিসিভ করার জন্য কোনো সাবস্ক্রাইবার না থাকে, তবে মেসেজ ড্রপ হয়ে যাবে।

Node.js উদাহরণ

Redis-এ একটি রেগুলার কানেকশন তৈরি করার পর, publish যেকোনো অন্য কমান্ডের মতো ব্যবহার করা যায়:

var client = require("redis").createClient();
client.publish("temp-reading:living-room", "37.0");

অন্য Redis কমান্ডের সাথে ব্যবহার

একটি চ্যানেলে ডেটা পাবলিশ করা একটি ফাস্ট অপারেশন, তাই এটি সাধারণত অন্যান্য অপারেশনের সাথে ট্যান্ডেমে ব্যবহার হয়। অপারেশন কম্বাইন করলে Redis-এর ক্ষমতা আনলক হয়:

var client = require("redis").createClient();
client.multi()
  .publish("temp-reading:living-room", "37.0")
  .lpush("recent-temperatures", "37.0")
  .ltrim("recent-temperatures", 0, 99)
  .exec();

এটি pub/sub সিস্টেমের আগের উদাহরণের মতোই অপারেশন, কিন্তু একই MULTI/EXEC ট্রানজ্যাকশনে তাপমাত্রাটি একটি লিস্টেও পুশ করা হয়েছে যা ১০০টি সবচেয়ে রিসেন্ট তাপমাত্রা রাখে।

এই সংক্ষিপ্ত উদাহরণটি দেখাচ্ছে কিভাবে Redis pub/sub কে একটি বড় সিস্টেম ডিজাইনে ইন্টিগ্রেট করা যায় যাতে মেসেজ হিস্টরি থাকে। এই টাইপের অপারেশন অন্য ক্লায়েন্টদের রিসেন্ট ভ্যালু কোয়েরি করতে দেয় এবং নতুন মেসেজ সাবস্ক্রাইব করতেও দেয়।

মেসেজ সাবস্ক্রাইব করা

কমান্ড সিন্ট্যাক্স

SUBSCRIBE কমান্ডটি চ্যানেল সাবস্ক্রাইব করতে ব্যবহৃত হয়। এই কমান্ড ক্লায়েন্টকে একটি স্পেশাল "subscribed" স্টেটে নিয়ে যায় যেখানে সেটা আর অন্য কমান্ড পাঠাতে পারে না, শুধু অতিরিক্ত SUBSCRIBE বা UNSUBSCRIBE কমান্ড ছাড়া।

SUBSCRIBE channel [channel ...]

Node.js উদাহরণ

এই সাবস্ক্রাইবারটি আগের পাবলিশার উদাহরণের সাথে ব্যবহার করা যেতে পারে:

var subscriber = require("redis").createClient();
subscriber.on("message", function(channel, message) {
  console.log("A temperature of " + message + " was read.");
});
subscriber.subscribe("temp-reading:living-room");

এটি একটি সিম্পল ইভেন্ট এমিটার ব্যবহার করে যা প্রতিবার মেসেজ আসার সময় একটি ফাংশন কল করে। হ্যান্ডলিং ফাংশন এখন শুধু কনসোলে তাপমাত্রা লগ করছে - এটি যেকোনো কিছু করতে পারে।

সাবস্ক্রাইবারসহ অন্যান্য কমান্ড ব্যবহার

আগে বলা হয়েছে, সাবস্ক্রাইব করা ক্লায়েন্টরা একটি স্পেশাল মোডে থাকে এবং অন্যান্য কমান্ডের জন্য ব্যবহার করা যায়না। অন্যান্য কমান্ড ব্যবহার করতে হলে আপনাকে Redis-এ আলাদা একটি ক্লায়েন্ট কানেকশন তৈরি করতে হবে:

var redis = require("redis")
  , subscriber = redis.createClient()
  , client = redis.createClient();
subscriber.on("message", function(channel, message) {
  console.log("A temperature of " + message + " was read.");
  client.incr("temp-count");
});
subscriber.subscribe("temp-reading:living-room");

এই হ্যান্ডলার মেসেজ কনসোলে লগ করে এবং একটি Redis কাউন্টার ইনক্রিমেন্ট করে। কিছু কেসে আপনি রেজাল্ট ক্যালকুলেট করে সেটাকে আলাদা একটি চ্যানেলে পাবলিশ করতে পারেন অন্য সাবস্ক্রাইবারদের জন্য - শুধু সেটাকে সেম চ্যানেলে ফিরিয়ে পাবলিশ করবেন না যেটা আপনি লিসেন করছেন, অন্যথায় ইনফিনিট লুপ হবে :)

প্যাটার্ন ম্যাচিং

কমান্ড সিন্ট্যাক্স

PSUBSCRIBE কমান্ডটি চ্যানেল প্যাটার্ন ম্যাচ করার জন্য ব্যবহৃত হয়।

PSUBSCRIBE pattern [pattern ...]

এটি নরমাল SUBSCRIBE কমান্ডের মতোই কাজ করে কিন্তু চ্যানেলের নাম প্যাটার্নের সাথে ম্যাচ করার সুযোগ দেয়। এতে পাবলিশাররা খুব স্পেসিফিকভাবে ইনফরমেশন পাবলিশ করতে পারে, এবং সাবস্ক্রাইবাররা চ্যানেলের সঠিক নাম না জানলেও অনেক চ্যানেল শুনতে পারে।

সাপোর্ট করা প্যাটার্নগুলো সিম্পল: * যেকোনো ক্যারেক্টার ম্যাচ করে, ? একটি ক্যারেক্টার ম্যাচ করে, এবং ব্র্যাকেট ব্যবহার করে অ্যাকসেপ্টেবল ক্যারেক্টার সেট ম্যাচ করা যায়, যেমন [acd]।

অনেক রুম থেকে তাপমাত্রা রিডিং ম্যাচ করুন:

PSUBSCRIBE temp-reading:*

A/B টেস্ট ইভেন্ট ম্যাচ করুন যেমন site-link:logo:a:clickrate এবং site-link:logo:b:clickrate:

PSUBSCRIBE site-link:logo:?:clickrate

AWS ইনস্ট্যান্স সিরিজের ইভেন্ট ম্যাচ করুন, পাবলিশড ইভেন্টের মতো system-health:us-east-1a:i-36a44b83 এবং system-health:us-east-1c:i-73657420636f636f6:

PSUBSCRIBE system-health:us-east-1[acd]:i-*

Node.js উদাহরণ

এই উদাহরণে, যা আগের পাবলিশিং উদাহরণের সাথে ব্যবহার করা যেতে পারে, তাপমাত্রা লগ হবে সেই রুমের সাথে যেখানে তাপমাত্রা পড়া হয়েছিল।

var subscriber = require("redis").createClient();
subscriber.on("pmessage", function(pattern, channel, message) {
  var room = channel.split(":")[1];
  console.log("A temperature of " + message + " was read in " + room);
});
subscriber.psubscribe("temp-reading:*");

প্যাটার্ন-ভিত্তিক সাবস্ক্রাইবার তার কলব্যাকে কিছু এক্সট্রা ডিটেইল পায়: চ্যানেল এবং মেসেজ ছাড়াও সে নির্দিষ্ট প্যাটার্ন যেটা ম্যাচ হয়েছে - যেহেতু সাবস্ক্রাইবাররা একাধিক চ্যানেল বা প্যাটার্নে লিসেন করতে পারে।

সাইড নোট: PUBLISH-এর পারফরম্যান্স ক্যারেক্টারিস্টিক্স

Redis-এর প্রতিটি কমান্ডের একটি ডকুমেন্টেড টাইম কমপ্লেক্সিটি আছে, এবং অধিকাংশ সময় এগুলো ইন্টুইটিভ। যেহেতু PUBLISH অপারেশন খুব সিম্পল লাগে (প্রায় SET-এর মতো) একে ভাবতে পারেন এর কমপ্লেক্সিটি O(1)। কিন্তু আসলে PUBLISH-এর টাইম কমপ্লেক্সিটি লিনিয়ারলি বড় হয় সাবস্ক্রাইবারের বিহেভিয়র অনুযায়ী।

যখন PUBLISH কমান্ড রান করে, সেটাকে চ্যানেলের সাথে ম্যাচ হতে পারে এমন সব প্যাটার্ন সাবস্ক্রিপশন এবং মেসেজ রিসিভ করতে হবে এমন সব সাবস্ক্রাইবার gennem যেতে হয়, যার ফলে টাইম কমপ্লেক্সিটি হয় O(N+M)।

বেশিরভাগ ডিপ্লয়মেন্টে PUBLISH-এর কমপ্লেক্সিটির কারণে কখনো পারফরম্যান্স সমস্যা হয় না, কিন্তু সেই কমান্ডের পারফরম্যান্স সময়ের সাথে ট্র্যাক করা বুদ্ধিমানের কাজ - সতর্ক থাকুন যদি আপনার কোড অটোমেটিক্যালি চ্যানেল প্যাটার্ন জেনারেট করে লিসেন করার জন্য।

আপনার কোড এখানে?

আমরা Redis pub/sub ব্যবহার করে বানানো কিছু দুর্দান্ত অ্যাপের ওকথ্রু ফিচার করতে চাই। যদি আপনার কাছে কিছু ভালো উদাহরণ থাকে, তবে support@redisgreen.net-এ নোট পাঠান - আমরা যেটা পাবো সেটা ফিচার করার চেষ্টা করব।

  1. রেডিস PUBLISH: রেডিস পাব/সাব দিয়ে মেসেজ পাবলিশ করার বিস্তারিত গাইড

  2. রেডিস পাব/সাব মাস্টার করুন: redis-cli দিয়ে একাধিক চ্যানেলে সাবস্ক্রাইব করুন

  3. জেডিস দিয়ে রেডিস পাব/সাব ইমপ্লিমেন্টেশন: ধাপে ধাপে গাইড

  4. Roku চ্যানেল আনব্লকিং গাইড: জিও-রেস্ট্রিক্টেড কন্টেন্ট নিরাপদে অ্যাক্সেস করুন