স্কালা Event Sourcing এবং CQRS

স্কালা ডিস্ট্রিবিউটেড সিস্টেম এবং মেসেজিং - স্কালা প্রোগ্রামিং (Scala Programming) - Computer Programming

284

Event Sourcing এবং CQRS (Command Query Responsibility Segregation) হল দুটি শক্তিশালী আর্কিটেকচারাল প্যাটার্ন, যা একসাথে ব্যবহৃত হলে স্কালার সিস্টেমকে আরও স্কেলেবল, পারফরম্যান্স অপটিমাইজড, এবং রিঅ্যাকটিভ করতে সাহায্য করে। এই দুটি প্যাটার্ন রিঅ্যাকটিভ ডিস্ট্রিবিউটেড সিস্টেম ডিজাইনে জনপ্রিয়, যেখানে ডেটার স্টেট পরিবর্তন এবং পড়া আলাদা করা হয় এবং ডেটার ইতিহাস সংরক্ষিত থাকে।


১. Event Sourcing

Event Sourcing হল এমন একটি আর্কিটেকচারাল প্যাটার্ন, যেখানে অ্যাপ্লিকেশন স্টেট পরিবর্তন সরাসরি ডাটাবেসে সংরক্ষণ না করে ইভেন্ট হিসেবে সংরক্ষণ করা হয়। প্রতিটি স্টেট পরিবর্তন একটি ইভেন্ট হিসেবে ধরে রাখা হয় এবং যখনই বর্তমান স্টেট প্রয়োজন হয়, তখন পুরানো ইভেন্টগুলিকে পুনরায় খেলা (replay) করা হয়। এর মাধ্যমে সিস্টেমের স্টেটের পূর্ণ ইতিহাস ট্র্যাক করা যায় এবং কোন সময়ে স্টেট হারিয়ে গেলেও, পুরনো ইভেন্টগুলির মাধ্যমে সঠিক স্টেট পুনরুদ্ধার করা সম্ভব হয়।

১.১ Event Sourcing এর মূল উপাদান:

  • ইভেন্ট: এটি একটি কার্যকলাপ বা স্টেট পরিবর্তন যা সিস্টেমে ঘটেছে।
  • ইভেন্ট স্টোর: সমস্ত ইভেন্ট সংরক্ষিত থাকে। এটি ঐতিহাসিক ডেটা যা পুনরায় খেলা যেতে পারে।
  • স্টেট পুনঃপ্রতিষ্ঠা: ডেটার বর্তমান স্টেট ইভেন্টগুলির replay মাধ্যমে পুনরুদ্ধার করা হয়।

১.২ Event Sourcing উদাহরণ

sealed trait AccountEvent
case class Deposit(amount: Int) extends AccountEvent
case class Withdraw(amount: Int) extends AccountEvent

case class Account(id: String, balance: Int)

object EventSourcingExample {

  def handleEvent(account: Account, event: AccountEvent): Account = event match {
    case Deposit(amount) => account.copy(balance = account.balance + amount)
    case Withdraw(amount) => account.copy(balance = account.balance - amount)
  }

  def main(args: Array[String]): Unit = {
    var account = Account("123", 0)

    val events: List[AccountEvent] = List(Deposit(100), Withdraw(50), Deposit(200))

    events.foreach(event => account = handleEvent(account, event))

    println(account)  // Output: Account(123,250)
  }
}

এখানে:

  • Deposit এবং Withdraw ইভেন্টগুলো Account অবজেক্টের স্টেট পরিবর্তন করে।
  • ইভেন্টগুলো replay করে অ্যাকাউন্টের বর্তমান ব্যালেন্স পুনরুদ্ধার করা হয়েছে।

২. CQRS (Command Query Responsibility Segregation)

CQRS হল একটি আর্কিটেকচার প্যাটার্ন যেখানে সিস্টেমের Command এবং Query অপারেশনগুলোকে আলাদা করা হয়।

  • Command: সিস্টেমের স্টেট পরিবর্তন করা, যেমন ডেটা আপডেট বা ইনসার্ট করা।
  • Query: সিস্টেমের স্টেট পড়া, যেমন ডেটা ফেচ করা বা কুয়েরি চালানো।

CQRS প্যাটার্নে, Write Model এবং Read Model আলাদা রাখা হয়। Command অপারেশনগুলি স্টেট পরিবর্তন করে, এবং Query অপারেশনগুলি শুধুমাত্র ডেটা পড়ে, স্টেট পরিবর্তন না করে।

২.১ CQRS এর সুবিধা:

  • পারফরম্যান্স অপটিমাইজেশন: কুয়েরি এবং কমান্ড অপারেশন আলাদা করার মাধ্যমে পারফরম্যান্স উন্নত করা যায়। কুয়েরি অপারেশনগুলিকে অপটিমাইজড এবং ফাস্ট করা যায়।
  • স্কেলেবিলিটি: পৃথক কুয়েরি এবং কমান্ড মডেল স্কেলিং সহজ করে তোলে, যেমন ডেটাবেসে পৃথক ইনডেক্সিং বা ডেটাবেস শার্ডিং।
  • সাধারণ সিস্টেমের কার্যকারিতা বৃদ্ধি: একে অপরের ওপর নির্ভরশীল না হওয়ার কারণে সিস্টেমের লোড সঠিকভাবে পরিচালনা করা যায়।

২.২ CQRS উদাহরণ

// Command Side - Write Model
case class Command(id: String, amount: Int)

class CommandHandler {
  def handleCommand(command: Command): String = {
    // Process command and perform write operation
    s"Processed command with id: ${command.id} and amount: ${command.amount}"
  }
}

// Query Side - Read Model
case class Query(id: String)

class QueryHandler {
  def handleQuery(query: Query): String = {
    // Process query and fetch data
    s"Fetched data for query with id: ${query.id}"
  }
}

object CQRSExample {
  def main(args: Array[String]): Unit = {
    val commandHandler = new CommandHandler
    val queryHandler = new QueryHandler

    // Handling command
    val commandResult = commandHandler.handleCommand(Command("123", 100))
    println(commandResult)  // Output: Processed command with id: 123 and amount: 100

    // Handling query
    val queryResult = queryHandler.handleQuery(Query("123"))
    println(queryResult)  // Output: Fetched data for query with id: 123
  }
}

এখানে:

  • CommandHandler সিস্টেমের স্টেট পরিবর্তন করে, যেমন ডেটা ইনসার্ট বা আপডেট।
  • QueryHandler শুধুমাত্র ডেটা পড়ার জন্য ব্যবহৃত হয়, ডেটা পরিবর্তন নয়।

৩. Event Sourcing এবং CQRS একসাথে ব্যবহৃত হলে

এখন যদি Event Sourcing এবং CQRS একসাথে ব্যবহৃত হয়, তবে আপনি সিস্টেমের স্টেট পরিবর্তন ইভেন্ট হিসেবে সংরক্ষণ করবেন এবং সেই ইভেন্টগুলো replay করে স্টেট পুনরুদ্ধার করবেন। সিস্টেমের Command এবং Query অপারেশন আলাদা করা হবে, যা পারফরম্যান্স এবং স্কেলেবিলিটি আরও উন্নত করবে।

৩.১ Event Sourcing এবং CQRS একসাথে উদাহরণ

// Event Sourcing with CQRS

case class OrderCreated(id: String, item: String, quantity: Int)

class CommandHandler {
  def handleCreateOrder(order: OrderCreated): Unit = {
    // Save the event to event store
    println(s"Saving event: OrderCreated(${order.id}, ${order.item}, ${order.quantity})")
  }
}

class QueryHandler {
  def getOrder(id: String): String = {
    // Fetch order details from read model
    s"Fetching order details for id: $id"
  }
}

object EventSourcingCQRSExample {
  def main(args: Array[String]): Unit = {
    val commandHandler = new CommandHandler
    val queryHandler = new QueryHandler

    // Command: Create an order
    val order = OrderCreated("123", "Laptop", 1)
    commandHandler.handleCreateOrder(order)

    // Query: Fetch the order
    val orderDetails = queryHandler.getOrder("123")
    println(orderDetails)  // Output: Fetching order details for id: 123
  }
}

এখানে:

  • CommandHandler ইভেন্টটি ডাটাবেসে সংরক্ষণ করে (এটি বাস্তবে ইভেন্ট স্টোর হতে পারে)।
  • QueryHandler ডেটা থেকে বিস্তারিত প্রাপ্তি করে, যা আলাদা read model থেকে এসেছে।

সারাংশ

  • Event Sourcing হল একটি প্যাটার্ন যেখানে সমস্ত স্টেট পরিবর্তন ইভেন্ট হিসেবে সংরক্ষণ করা হয়, এবং এই ইভেন্টগুলি replay করে স্টেট পুনরুদ্ধার করা হয়।
  • CQRS হল একটি প্যাটার্ন যেখানে Command (স্টেট পরিবর্তন) এবং Query (স্টেট পড়া) আলাদা করে দেওয়া হয়, যা পারফরম্যান্স এবং স্কেলেবিলিটি উন্নত করে।
  • Event Sourcing এবং CQRS একসাথে ব্যবহৃত হলে, আপনি একটি সিস্টেম ডিজাইন করতে পারেন যা দ্রুত এবং স্কেলেবল, এবং এর ডেটার ইতিহাস সংরক্ষণ এবং পুনরুদ্ধার করা সম্ভব।
Content added By
Promotion

Are you sure to start over?

Loading...