সেশন ২২

Chaos Engineering - ইচ্ছে করে ভাঙা, যাতে হঠাৎ না ভাঙে

এই সেশনের লক্ষ্য: Redundancy সত্যিই কাজ করে কিনা, সেটা কাগজে নয়, নিজের চোখে দেখে নিশ্চিত হওয়া শেখা। Steady state আর hypothesis দিয়ে একটা নিয়ন্ত্রিত experiment সাজানো, blast radius ছোট রাখা, abort condition ঠিক করা, আর পুরো team মিলে একটা game day চালানো বোঝা।

০০ যে প্রশ্নগুলোর উত্তর খুঁজবো

আগের সেশনগুলোতে আমরা system কে টেকসই বানানোর অনেক কৌশল শিখেছি। Server এর replica রেখেছি, database এর failover সাজিয়েছি, timeout আর circuit breaker বসিয়েছি। কিন্তু একটা প্রশ্ন এখনো বাকি: এগুলো সত্যিই কাজ করে তো?

এই সেশনে আমরা সেই প্রশ্নের উত্তর খোঁজার একটা পদ্ধতি শিখবো। পদ্ধতিটা শুনতে একটু অদ্ভুত: নিজের system নিজেই, ইচ্ছে করে, নিয়ম মেনে ভাঙা। শেষে আপনি বুঝবেন, কেন বড় বড় কোম্পানি এটা নিয়মিত করে, আর একটা নতুন team কীভাবে নিরাপদে শুরু করতে পারে।

  • ১ "আমাদের সবকিছুর ২ টা replica আছে" বললেই কি failover কাজ করবে?
  • ২ Staging এ failover test পাস করলে production নিয়ে নিশ্চিন্ত থাকা যায় না কেন?
  • ৩ Chaos engineering কী, আর Chaos Monkey কোথা থেকে এলো?
  • ৪ একটা experiment এর steady state আর hypothesis কীভাবে লিখবো?
  • ৫ Fault injection এ কোন কোন failure ঢোকানো যায়?
  • ৬ Blast radius কী, আর সেটা কীভাবে ছোট রাখবো?
  • ৭ একটা game day কীভাবে চলে? (তাসনিমের এগারো মিনিট)
  • ৮ Abort condition কী, আর abort action নিজেই অচল হলে কী হয়?
  • ৯ অভিজ্ঞতা নেই এমন একটা team কোথা থেকে শুরু করবে?

০১ “আমাদের সবকিছুর ২ টা replica আছে” বললেই কি failover কাজ করবে?

বৃহস্পতিবার, বিকেল ঠিক তিনটা। Meeting room এ ছয়জন মানুষ, সবার চোখ দেয়ালের বড় screen এ। তাসনিম mouse এ হাত রেখে বললো, “Primary database বন্ধ করছি।” তারপর click করলো। Payment success rate এর সবুজ রেখাটা ঝপ করে নিচে নেমে গেলো। কেউ ঘাবড়ালো না, কারণ সবাই জানে replica এক মিনিটের মধ্যে দায়িত্ব নিয়ে নেবে। এক মিনিট গেলো। তিন মিনিট গেলো। পাঁচ মিনিটের মাথায় ঘরটা একদম চুপ হয়ে গেলো। রেখাটা আবার উপরে উঠলো ঠিক এগারো মিনিট পরে।

তাসনিম একটা bill payment application এর backend team এ কাজ করে। মানুষ এই application দিয়ে বিদ্যুৎ, গ্যাস আর internet এর bill দেয়। Team এর একটা গর্বের কথা ছিলো: “আমাদের সবকিছুর ২ টা করে replica আছে।” Load balancer দুইটা (সেশন ০২), app server ছয়টা, আর database এর একটা primary আর একটা replica (সেশন ০৩)। কাগজে কলমে কোথাও কোনো SPOF নেই। SPOF (single point of failure) মানে এমন একটা অংশ, যেটা একা বন্ধ হলেই পুরো system বন্ধ হয়ে যায় (সেশন ০১)।

এই game day এর তিন সপ্তাহ আগে, এক standup meeting এ, senior engineer অর্ণব একটা ছোট প্রশ্ন করেছিলেন: “Failover শেষ কবে নিজের চোখে দেখেছেন?” কেউ উত্তর দিতে পারেনি। শেষবার test হয়েছিলো আট মাস আগে, তাও staging এ। এর মধ্যে code বদলেছে, configuration বদলেছে, traffic তিন গুণ হয়েছে।

যা ভেবেছিলাম যা ঘটলো ~30s: replica নিজেই দায়িত্ব নেবে 11 মিনিট: বেশিরভাগ payment fail 0 2 4 6 8 10 primary বন্ধ করার পর কত মিনিট
কাগজে failover এর সময় ছিলো আধা মিনিট। বাস্তবে, প্রথম game day তে, সেটা লাগলো এগারো মিনিট। দুটো বারের মাঝের ফাঁকটুকুই হলো সেই দুর্বলতা, যেটা কেউ জানতো না।

Replica থাকা আর failover কাজ করা এক কথা নয়। Replica মানে শুধু একটা দ্বিতীয় machine, যেটা তৈরি হয়ে বসে আছে। Failover ঠিকমতো হতে হলে তিনটা কাজ পরপর ঠিকঠাক হতে হয়:

  1. ধরা পড়া (detection): কেউ একজনকে বুঝতে হবে যে primary আর সাড়া দিচ্ছে না।
  2. দায়িত্ব বদল (promotion): Replica কে নতুন primary বানাতে হবে, যাতে সে write নিতে পারে।
  3. পথ বদল (rerouting): সব app server কে জানাতে হবে যে এখন থেকে নতুন primary তে যেতে হবে।

এই তিনটার যেকোনো একটা ধীর হলে, বা ভুল হলে, পুরো failover আটকে যায়। আর কোনটা ভুল, সেটা আপনি জানতে পারবেন শুধু তখনই, যখন সত্যিই primary বন্ধ হবে।

আসল কথা

যে redundancy কখনো test হয়নি, সেটা আসলে একটা অনুমান। আপনি জানেন না সেটা কাজ করবে কিনা, শুধু আশা করেন। আর অনুমানটা ভুল কিনা, সেটা জানার সবচেয়ে খারাপ সময় হলো ঈদের আগের রাত দুইটা।

০২ Staging এ failover test পাস করলে production নিয়ে নিশ্চিন্ত থাকা যায় না কেন?

Staging হলো production এর একটা ছোট নকল। নতুন code release এর আগে এখানে চালিয়ে দেখা হয়। আট মাস আগে তাসনিমের team staging এ primary বন্ধ করেছিলো, আর failover হয়েছিলো ৪০ সেকেন্ডে। তাহলে production এ এগারো মিনিট লাগলো কেন?

কারণ staging দেখতে production এর মতো, কিন্তু ভেতরে অনেক পার্থক্য:

বিষয়StagingProduction
Traffic~2 request/sদুপুরে ~150, ঈদের আগে ~1,200 request/s
App server১ টা৬ টা
DNS TTL০ সেকেন্ড৩০০ সেকেন্ড
Database connection৫ টাপ্রতি server এ ৫০ টা, মোট ৩০০ টা
Data2 GB test data800 GB আসল data
Configurationআট মাস আগেরপ্রায় প্রতি সপ্তাহে বদলায়

তালিকার প্রতিটা পার্থক্য দেখতে ছোট। কিন্তু failure ঠিক এই ছোট জায়গাগুলোতেই লুকিয়ে থাকে। যেমন DNS TTL এর লাইনটা দেখুন। DNS নাম থেকে server এর address বের করে দেয় (সেশন ০৬)। আর TTL হলো একটা উত্তর কতক্ষণ মনে রাখা যাবে, তার মেয়াদ (সেশন ০৪)। Staging এ TTL শূন্য, তাই address বদলালেই সবাই সাথে সাথে নতুনটা পায়। Production এ TTL ৩০০ সেকেন্ড, তাই app server গুলো পাঁচ মিনিট ধরে পুরোনো address টাই ব্যবহার করতে থাকে। Staging এর test এই পাঁচ মিনিটের দেখা কখনো পায়নি।

আরেকটা সমস্যার নাম configuration drift। শুরুতে staging আর production এর setting এক থাকে। তারপর production এ কেউ একটা timeout বাড়ায়, কেউ একটা নতুন setting যোগ করে, কিন্তু staging এ সেটা আর করা হয় না। মাসের পর মাস এভাবে দুটো ধীরে ধীরে আলাদা হয়ে যায়।

এছাড়া production এ আসল user থাকে, আসল bank আর SMS provider এর সাথে আসল সংযোগ থাকে। Staging এ এগুলোর বেশিরভাগই নকল (mock) দিয়ে চালানো হয়।

Staging আর production কোন প্রশ্নের উত্তর দেয়

Staging উত্তর দেয়: “Code টা কি ঠিক আছে?” Production উত্তর দেয়: “পুরো system টা কি ঠিক আছে?” দ্বিতীয় প্রশ্নের উত্তর শুধু production ই দিতে পারে। তাই বলে staging বাদ দেবেন না। Staging হলো প্রথম ধাপ, শেষ ধাপ নয়।

০৩ Chaos engineering কী, আর Chaos Monkey কোথা থেকে এলো?

অফিসের fire drill

অনেক অফিসে বছরে একবার fire drill হয়। কোথাও আগুন লাগেনি, তবু হঠাৎ alarm বাজে। সবাই কাজ ফেলে সিঁড়ি দিয়ে নেমে মাঠে জড়ো হয়। এই মহড়াতেই অনেক কিছু ধরা পড়ে। হয়তো জরুরি সিঁড়ির দরজায় তালা দেওয়া। হয়তো নতুন কর্মীরা জানেনই না কোথায় জড়ো হতে হবে। আগুনের দিনে এগুলো জানলে অনেক দেরি হয়ে যায়।

Software এর fire drill এর নামই chaos engineering। এখানে ইচ্ছে করে, নিয়ন্ত্রিতভাবে system এ একটা failure ঢোকানো হয়। তারপর দেখা হয় system টা কেমন আচরণ করে। উদ্দেশ্য একটাই: আসল failure আসার আগেই দুর্বলতা খুঁজে বের করা।

নামে “chaos” (বিশৃঙ্খলা) থাকলেও কাজটা খুব গোছানো। এটা আসলে একটা বৈজ্ঞানিক experiment, ঠিক school এর বিজ্ঞান ক্লাসের মতো। আগে মাপা, তারপর অনুমান লেখা, তারপর পরীক্ষা, শেষে মিলিয়ে দেখা:

fix করে আবার চালান abort রেডি রেখে প্রতি চক্রে একটু বড় ১. Steady state মাপুন স্বাভাবিক দিনে success 99.7% ২. Hypothesis লিখুন "primary গেলে 60s এ ঠিক হবে" ৩. ছোট করে fault inject অল্প blast radius, সীমিত সময় ৪. তুলনা করুন, শিখুন হিসাব মিললো? না মিললে কেন?
প্রতিটা chaos experiment এই চক্রে চলে। আগে মাপুন, তারপর অনুমান লিখুন, তারপর ছোট করে ভাঙুন, শেষে মিলিয়ে দেখুন। দুর্বলতা পেলে ঠিক করুন, তারপর একটু বড় পরিসরে আবার চালান।

পরের তিনটা section এ এই চক্রের প্রতিটা ধাপ আলাদা করে দেখবো।

Chaos Monkey: শুরুর গল্প

২০০৮ সালে Netflix এর একটা database এ data corrupt হয়ে যায়। তখন Netflix ডাকে DVD পাঠাতো। এই এক ঘটনায় তিন দিন তারা কোনো DVD পাঠাতে পারেনি। এরপর Netflix নিজেদের data center ছেড়ে AWS cloud এ যাওয়া শুরু করে।

Cloud এ একটা নতুন বাস্তবতা ছিলো: যেকোনো server যেকোনো সময় হারিয়ে যেতে পারে। Netflix এর engineer রা ঠিক করলেন, এই failure এর জন্য অপেক্ষা না করে তাঁরা নিজেরাই এটা ঘটাবেন। তাঁরা বানালেন Chaos Monkey, একটা tool যেটা production এর random server বন্ধ করে দেয়। মজার ব্যাপার হলো, এটা চলে শুধু কাজের দিনে, অফিসের সময়ে। কারণ তখন engineer রা জেগে থাকেন, আর কিছু ভাঙলে সাথে সাথে ঠিক করতে পারেন।

ফল হলো চমৎকার। প্রতিদিন server হারাতে হারাতে team গুলো এমন service বানাতে শিখলো, যেটা একটা server চলে গেলে টেরই পায় না।

2008 2010-11 2011 2012 DB corruption 3 দিন DVD পাঠানো বন্ধ তারপর cloud এ যাত্রা Chaos Monkey অফিস সময়ে random server বন্ধ করে Simian Army Latency Monkey (দেরি), Chaos Gorilla (পুরো zone) Open source যে কেউ নিজের system এ চালাতে পারে
একটা বড় outage থেকে Netflix শিখলো যে failure আসবেই। তাই তারা ঠিক করলো, failure কে অপেক্ষা না করে নিজেরাই নিয়মিত, অফিসের সময়ে, ছোট করে ঘটাবে।

পরে আরো “বানর” যোগ হয়। Latency Monkey ইচ্ছে করে network এ দেরি ঢোকায়। Chaos Gorilla একটা পুরো availability zone বন্ধ করে দেয় (zone কী, সেটা section ০৫ এ দেখবো)। ২০১২ সালে Netflix Chaos Monkey কে open source করে দেয়। আজ AWS Fault Injection Service, Gremlin বা Chaos Mesh এর মতো tool দিয়ে যেকোনো team এই কাজ করতে পারে।

Chaos মানে ভাঙচুর নয়

Hypothesis ছাড়া, মাপা ছাড়া, থামার plan ছাড়া একটা server বন্ধ করে দেওয়া chaos engineering নয়। সেটা শুধু ঝুঁকি নেওয়া। Experiment হতে হলে আগে থেকে জানতে হবে আপনি কী মাপছেন, কী আশা করছেন, আর কখন থামবেন।

০৪ একটা experiment এর steady state আর hypothesis কীভাবে লিখবো?

Steady state: স্বাভাবিক দেখতে কেমন

কিছু ভাঙার আগে জানতে হবে, ঠিক থাকা অবস্থায় system দেখতে কেমন। এই স্বাভাবিক অবস্থাকে একটা মাপা যায় এমন সংখ্যায় লিখে ফেলাকে বলে steady state।

এখানে একটা সাধারণ ভুল হয়। অনেকে steady state হিসেবে machine এর সংখ্যা বেছে নেন, যেমন CPU বা memory। কিন্তু user CPU দেখে না। User দেখে তার payment হলো কিনা। তাই steady state হওয়া উচিত এমন একটা সংখ্যা, যেটা user এর অভিজ্ঞতা সরাসরি বলে দেয়:

MetricSteady state হিসেবে চলে?কেন
CPU ৪০%নাCPU ঠিক থাকলেও user এর payment fail হতে পারে
Payment success rate ৯৯.৭%হ্যাঁUser যা অনুভব করে, সরাসরি সেটাই
p99 latency 350msহ্যাঁসবচেয়ে ধীর অভিজ্ঞতার user রা কতক্ষণ অপেক্ষা করে
প্রতি সেকেন্ডে সফল payment ~১৫০হ্যাঁহঠাৎ কমে গেলেই বোঝা যায় কিছু আটকেছে

p99 latency মানে, ১০০ টা request এর মধ্যে ৯৯ টা এই সময়ের মধ্যে শেষ হয় (percentile এর বিস্তারিত সেশন ১৯ এ)। Netflix ও steady state হিসেবে user এর দিক থেকে একটা সংখ্যা দেখে: প্রতি সেকেন্ডে কতজন একটা video চালু করলো।

Hypothesis: পরীক্ষার আগে অনুমান লিখে ফেলা

Hypothesis হলো experiment এর আগে লিখে রাখা একটা অনুমান। এর গঠন সাধারণত এমন: “X ঘটলে steady state Y এর মধ্যে থাকবে।” ভালো hypothesis কে ভুল প্রমাণ করা যায়। “System মোটামুটি ঠিক থাকবে” ভুল প্রমাণ করা যায় না, তাই এটা hypothesis নয়। “৬০ সেকেন্ডের মধ্যে success rate আবার ৯৯% এর উপরে উঠবে” ভুল প্রমাণ করা যায়।

তাসনিমের team game day এর এক সপ্তাহ আগে এই কাগজটা লিখেছিলো:

Experiment #1: Primary DB failover
তারিখ: বৃহস্পতিবার, বিকেল 3:00 থেকে 3:15

Steady state (গত চার বৃহস্পতিবার, একই সময়ে):
  traffic             ~150 request/s
  payment success     99.7%
  p99 latency         350ms

Hypothesis:
  Primary DB বন্ধ করলে 60 সেকেন্ডের মধ্যে replica primary হবে।
  এই 60 সেকেন্ডের পর success rate আবার 99% এর উপরে উঠবে।

Fault:
  Primary DB এর machine টা বন্ধ করা (replica ছোঁয়া হবে না)

Abort condition:
  success rate টানা 2 মিনিট 95% এর নিচে থাকলে experiment থামবে

Abort action:
  পুরোনো primary আবার চালু করা

খেয়াল করুন, steady state এর সংখ্যাগুলো এসেছে গত চার বৃহস্পতিবারের একই সময় থেকে। এই পুরোনো দিনগুলো এখানে তুলনার ভিত্তি। বড় system এ আরো ভালো উপায় আছে। User দের দুই দলে ভাগ করা হয়। Control group এর উপর কিছুই করা হয় না। Experiment group এর উপর fault ঢোকানো হয়। একই সময়ে দুই দলের সংখ্যা পাশাপাশি রাখলে যে পার্থক্য দেখা যায়, সেটা fault এর কারণেই। এই কারণেই একে বলে controlled experiment।

অনুমানটা আগে লিখুন

Hypothesis টা experiment শুরুর আগে কাগজে লিখে ফেলুন। পরে লিখলে মানুষ ফলাফল দেখে মনের অজান্তেই অনুমান বদলে ফেলে: “আসলে আমরা তো ১১ মিনিটই আশা করেছিলাম।” লেখা থাকলে এই সুযোগ থাকে না।

০৫ Fault injection এ কোন কোন failure ঢোকানো যায়?

ইচ্ছে করে system এ একটা নির্দিষ্ট failure ঢোকানোকে বলে fault injection। প্রতিটা fault বাস্তবের কোনো একটা ঘটনাকে নকল করে। সবচেয়ে প্রচলিত পাঁচটা:

blast radius ছোট থেকে বড় Instance kill 6 টা app server এর 1 টা বন্ধ নকল করে: server crash Latency যোগ SMS API call এ বাড়তি 500ms নকল করে: ধীর dependency Packet drop network এ 5% packet হারিয়ে যায় নকল করে: খারাপ network Disk ভরানো একটা server এর log disk 95% ভরে দেওয়া নকল করে: log জমে disk শেষ Zone down 3 টা zone এর 1 টা পুরো বন্ধ নকল করে: data center এ বিদ্যুৎ নেই
প্রতিটা fault বাস্তবের একটা failure কে নকল করে। উপরের গুলো ছোট আর নিরাপদ, তাই শুরু করা হয় সেখান থেকে। নিচের দিকে যত নামবেন, ক্ষতির পরিধি তত বড়, তাই সেগুলো আসে অনেক পরে।

Zone down এর হিসাবটা দেখুন

তাসনিমের ছয়টা app server তিনটা zone এ ছড়ানো, প্রতি zone এ দুইটা করে। প্রতিটা server সর্বোচ্চ 250 request/s সামলাতে পারে। একটা zone বন্ধ হলে থাকে চারটা server, মানে 4 × 250 = 1,000 request/s। দুপুরের 150 request/s এর জন্য এটা অনেক বেশি। কিন্তু ঈদের আগের রাতে traffic ওঠে 1,200 request/s এ। তখন 1,000 দিয়ে কুলাবে না। কাগজে redundancy আছে, কিন্তু যথেষ্ট capacity নেই। এই হিসাবটা চোখে পড়ে শুধু তখনই, যখন কেউ zone down এর কথা সত্যিই ভাবে।

ধীর হওয়া, বন্ধ হওয়ার চেয়েও বিপজ্জনক

একটা server পুরো বন্ধ হলে request সাথে সাথে fail করে, আর load balancer তাকে দ্রুত বাদ দেয়। কিন্তু একটা server ধীর হলে সে বেঁচে থাকার ভান করে। প্রতিটা request তার কাছে গিয়ে আটকে থাকে, thread গুলো একে একে ব্যস্ত হয়ে যায়, আর ধীরতাটা পুরো system এ ছড়িয়ে পড়ে। তাই latency injection প্রায়ই instance kill এর চেয়ে বেশি দুর্বলতা খুঁজে পায়।

০৬ Blast radius কী, আর সেটা কীভাবে ছোট রাখবো?

নতুন একটা তরকারিতে লবণ ঠিক হলো কিনা, সেটা দেখতে কেউ পুরো হাঁড়ি খেয়ে ফেলে না। এক চামচ চেখে দেখে। লবণ বেশি হলে নষ্ট হয় শুধু ঐ এক চামচ।

Chaos experiment এও একই নিয়ম। Experiment টা ভুল হলে ক্ষতি কতদূর ছড়াবে, তার পরিধিকে বলে blast radius। কতজন user এর উপর প্রভাব পড়বে, কয়টা service এ, কতক্ষণ ধরে, এই সবকিছু মিলিয়ে blast radius।

পুরো system (সব user) একটা zone একটা পুরো service 1% user 1 server ছোট রাখার চারটা উপায় কম জিনিস 6 টা server এর মাত্র 1 টা কম user আগে 1% user এর উপর কম সময় সর্বোচ্চ 10 মিনিট, তারপর থামবে কম ভিড়ের সময় দুপুর 3 টা (150 req/s), ঈদের রাত নয় প্রথম game day: primary DB মানে সবচেয়ে বাইরের রিং
Blast radius হলো experiment ভুল হলে ক্ষতিটা কতদূর ছড়াবে। ভেতরের রিং থেকে শুরু করুন। একটা রিং এ system টিকে গেলে তবেই পরের রিং এ যান। তাসনিমের team প্রথম দিনেই সবচেয়ে বাইরের রিং বেছে নিয়েছিলো, কারণ primary database এর উপর সব user নির্ভর করে।

Blast radius ছোট রাখার চারটা উপায় আছে:

  1. কম জিনিস: ছয়টা server এর মধ্যে মাত্র একটা বন্ধ করুন। পাঁচটা ঠিক থাকলে ক্ষতি সীমিত থাকে।
  2. কম user: প্রথমে মাত্র ১% user এর request এ fault ঢোকান। নতুন কিছু প্রথমে অল্প কিছু user এর উপর চালানোর এই কৌশলকে বলে canary।
  3. কম সময়: আগে থেকে সর্বোচ্চ সময় ঠিক করুন, যেমন ১০ মিনিট। সময় শেষ হলে experiment নিজে থেকেই থামবে।
  4. কম ভিড়ের সময়: দুপুর তিনটায় traffic 150 request/s, ঈদের আগের রাতে 1,200। কম ভিড়ের সময় বেছে নিলে একই ভুলে আট ভাগের এক ভাগ মানুষ ভোগে।

এবার তাসনিমের প্রথম experiment টা আবার দেখুন। Primary database এর উপর সব user, সব payment নির্ভর করে। মানে প্রথম দিনেই তারা সবচেয়ে বাইরের রিং টা বেছে নিয়েছিলো। সময় আর ভিড়ের দিক থেকে তারা সাবধান ছিলো, কিন্তু জিনিস আর user এর দিক থেকে ছিলো না। পেছন ফিরে দেখলে, প্রথম experiment হিসেবে এটা অনেক বড় ছিলো।

ভেতর থেকে বাইরে

সবসময় সবচেয়ে ছোট রিং থেকে শুরু করুন। সেখানে system টিকে গেলে, আর আপনি নিশ্চিত হলে, তবেই এক রিং বাইরে যান। Blast radius বাড়ানো উচিত আত্মবিশ্বাসের সাথে তাল মিলিয়ে, তার আগে নয়।

০৭ একটা game day কীভাবে চলে?

আগে থেকে ঠিক করা একটা দিন, যেদিন পুরো team একসাথে বসে ইচ্ছে করে একটা failure ঘটায়, দেখে, আর শেখে, তাকে বলে game day। অফিসের fire drill এর দিনটার মতো। সবাই জানে কী হতে যাচ্ছে, সবাই তৈরি থাকে।

আগে (এক সপ্তাহ) চলাকালীন (1 ঘণ্টা) পরে (দুই দিন) Steady state আর hypothesis Abort condition আর action Support team কে জানানো কে কোন কাজ করবে, ঠিক করা Operator fault inject করে Observer dashboard দেখে Scribe সময় ধরে লিখে রাখে Lead যেকোনো সময় abort করে Blameless postmortem Fix এর list, প্রতিটার owner Runbook আপডেট আবার test এর তারিখ
Game day এর আসল কাজ হয় আগে আর পরে। মাঝের এক ঘণ্টায় শুধু চারজন মানুষ চারটা আলাদা দায়িত্ব পালন করেন, যাতে কেউ দিশেহারা না হয়।

চলার সময় চারজন মানুষের চারটা আলাদা দায়িত্ব থাকে:

Game day এর পরে একটা blameless postmortem হয়, মানে এমন একটা আলোচনা যেখানে কাউকে দোষ না দিয়ে শুধু কারণ খোঁজা হয় (বিস্তারিত সেশন ২০ এ)।

তাসনিমের এগারো মিনিট, মিনিট ধরে ধরে

Scribe এর লেখা থেকে বানানো timeline টা এমন:

00:00 00:10 01:30 02:00 02:10 07:00 09:30 11:00 Primary DB বন্ধ করা হলো Payment success rate নামতে শুরু করলো Success rate 95% এর নিচে Abort condition এর 2 মিনিটের ঘড়ি চালু হলো Failure ধরা পড়লো Health check 30s পর পর চলে, টানা 3 বার fail লাগে, তাই 90s Replica এখন নতুন primary DNS record বদলালো, কিন্তু DNS TTL 300s Abort এর সময় হলো, কিন্তু abort action অচল পুরোনো primary চালু করলে দুটো primary: split brain DNS cache এর মেয়াদ শেষ তবু pool এর পুরোনো connection এ প্রতিটা request 30s আটকে থাকে App server restart শুরু 6 টা server, একটা একটা করে, প্রতিটায় ~15s Success rate আবার 99.7% মোট সময়: 11 মিনিট
এগারো মিনিটের পেছনে একটা বড় ভুল ছিলো না, ছিলো চারটা ছোট ভুল: ধীর health check, লম্বা DNS TTL, পুরোনো connection আঁকড়ে থাকা pool, আর এমন একটা abort action, যেটা দুই মিনিট পরেই অচল হয়ে যায়।

এগারো মিনিটের পেছনে কোনো একটা বড় ভুল ছিলো না। ছিলো চারটা ছোট ভুল, যেগুলো একটা আরেকটার উপর জমেছে:

  1. ধীর detection: Health check প্রতি ৩০ সেকেন্ডে একবার চলতো, আর টানা তিনবার fail না হলে কেউ কিছু করতো না। শুধু ধরা পড়তেই লাগলো ৯০ সেকেন্ড।
  2. লম্বা DNS TTL: Replica primary হওয়ার পর DNS record বদলানো হলো। কিন্তু TTL ৩০০ সেকেন্ড হওয়ায় app server গুলো পাঁচ মিনিট ধরে পুরোনো address এই যেতে থাকলো।
  3. পুরোনো connection আঁকড়ে থাকা pool: প্রতিবার database এর সাথে নতুন connection খুলতে সময় লাগে। তাই application কিছু connection খুলে রাখে আর বারবার ব্যবহার করে। এই সংগ্রহকে বলে connection pool। DNS ঠিক হওয়ার পরও pool টা পুরোনো, অচল connection গুলো ফেলে দেয়নি। প্রতিটা request ৩০ সেকেন্ড অপেক্ষা করে তারপর fail করছিলো। শেষে server restart করে pool খালি করতে হলো।
  4. অচল abort action: এটার গল্প section ০৮ এ।

একই এগারো মিনিট graph এ দেখতে এমন:

100% 50% 0% 0 2 4 6 8 10 12 fault inject করার পর কত মিনিট steady state: 99.7% abort সীমা: 95% inject replica primary (2:00) DNS expire (7:00) restart (9:30) ঠিক (11:00) hypothesis: যা ভেবেছিলাম বাস্তবে যা ঘটলো
Dashed রেখাটা hypothesis: এক মিনিটের ছোট একটা ধাক্কা, তারপর সব স্বাভাবিক। মোটা রেখাটা বাস্তব: success rate নেমে প্রায় ১০% এ থেকে গেলো। DNS এর মেয়াদ শেষ হলে একটু উঠলো, আর পুরোপুরি ঠিক হলো server restart এর পর।

এই experiment এর দাম কত পড়লো

তাসনিমের মন খারাপ হয়েছিলো। প্রায় ৮৯,০০০ payment request fail করেছে, অনেক মানুষকে আবার চেষ্টা করতে হয়েছে। কিন্তু অর্ণব তাকে একটা হিসাব দেখালেন:

Game day এর দাম (বৃহস্পতিবার, দুপুর 3 টা):
  traffic              150 request/s
  সময়                  11 মিনিট = 660 সেকেন্ড
  মোট request          150 x 660        = 99,000
  fail হলো (~90%)                       = ~89,000

একই failure ঈদের আগের রাতে, রাত 2 টায় ঘটলে:
  traffic              1,200 request/s
  কেউ জেগে নেই, ধরা পড়তে আরো ~20 মিনিট
  সময়                  11 + 20 = 31 মিনিট = 1,860 সেকেন্ড
  মোট request          1,200 x 1,860    = 22,32,000
  fail হতো (~90%)                       = ~20 লাখ

Error budget (SLO 99.9%, এক মাস):
  মাসে মোট মিনিট       30 x 24 x 60     = 43,200
  0.1% খারাপ সময়        43,200 x 0.001   = 43.2 মিনিট
  game day খরচ করলো    11 / 43.2        = ~25%

Game day এ ক্ষতি হয়েছে ঠিকই, কিন্তু সেটা ছিলো দিনের আলোয়, কম ভিড়ের সময়ে, সবাই চোখ রেখে বসে থাকা অবস্থায়। একই দুর্বলতা ঈদের রাতে নিজে থেকে ধরা পড়লে ক্ষতি হতো প্রায় বাইশ গুণ। Error budget এর হিসাবও আছে। Error budget হলো SLO এর ভেতরে মাসে যতটুকু খারাপ সময় মেনে নেওয়া যায় (সেশন ২০)। এই team এর SLO ৯৯.৯%, তাই মাসে ৪৩ মিনিটের মতো খারাপ সময় চলে। Game day সেই budget এর এক চতুর্থাংশ খরচ করেছে, ইচ্ছে করে, একটা শিক্ষা কিনতে।

Game day এর পরে যা বদলালো

Postmortem থেকে পাঁচটা fix এলো, প্রতিটার একজন owner:

সমস্যাআগেFix এর পরে
Failure ধরা পড়তে দেরি৩০ সেকেন্ড পর পর check, মোট ৯০ সেকেন্ড১০ সেকেন্ড পর পর check, মোট ৩০ সেকেন্ড
DNS এর পুরোনো উত্তরTTL ৩০০ সেকেন্ডTTL ৩০ সেকেন্ড
Pool এ অচল connectionconnect timeout ৩০ সেকেন্ড, কোনো যাচাই নেইconnect timeout ৩ সেকেন্ড, ব্যবহারের আগে ছোট যাচাই
Abort action অচলএকটাই actionpromotion এর আগে আর পরে আলাদা action
কী করতে হবে কেউ জানে নাকোনো লেখা নিয়ম নেইআট ধাপের runbook (সেশন ২০)

তিন সপ্তাহ পরে team একই experiment আবার চালালো। এবার failover হলো ৪৮ সেকেন্ডে। Hypothesis টিকে গেলো।

Game day এর আসল ফল

Game day এর ফল একটা সংখ্যা নয়, একটা fix এর তালিকা। আর সেই তালিকা সত্যিই কাজ করেছে কিনা, সেটা প্রমাণ হয় পরের game day তে, একই experiment আবার চালিয়ে।

০৮ Abort condition কী, আর abort action নিজেই অচল হলে কী হয়?

Abort condition হলো আগে থেকে লেখা একটা সীমা। Experiment চলার সময় সেই সীমা পার হলেই experiment থামবে, কারো মতামতের অপেক্ষা না করে। কয়েকটা উদাহরণ:

আর সীমা পার হলে যা করা হয়, তাকে বলে abort action: fault বন্ধ করে system কে আগের অবস্থায় ফিরিয়ে আনা। ভালো abort action একটা মাত্র command, যেটা যে কেউ এক সেকেন্ডে চালাতে পারে।

Fault inject চলছে যেমন: 6 টা server এর 1 টা বন্ধ 10s পরে আবার Metric check success rate, p99 latency, error সীমা পার সীমার ভেতরে ABORT: এক command এ fault বন্ধ, system আগের মতো চালিয়ে যান সময় শেষ হলে নিজে থেকেই থামবে abort action টা পুরো সময় জুড়ে কাজ করবে তো?
Experiment চলার পুরো সময় একটা loop পাহারা দেয়। প্রতি দশ সেকেন্ডে সে metric দেখে। সীমা পার হলেই আর কারো মতামতের অপেক্ষা নয়, fault সাথে সাথে বন্ধ। নিচের প্রশ্নটাই তাসনিমের team কে ভুগিয়েছিলো।

যখন abort action নিজেই অচল

তাসনিমের team এর abort condition ঠিক ছিলো, আর সেটা কাজও করেছিলো। ০০:১০ এ success rate ৯৫% এর নিচে নামলো, ০২:১০ এ দুই মিনিট পূর্ণ হলো। Lead বললেন, “Abort।” তাসনিম abort action এর কাগজটা খুললো: “পুরোনো primary আবার চালু করা।”

ঠিক তখনই অর্ণব থামালেন। দশ সেকেন্ড আগে, ০২:০০ এ, replica নতুন primary হয়ে গেছে। এখন পুরোনো primary চালু করলে একসাথে দুটো primary থাকবে। কিছু app server পুরোনোটায় write করবে, কিছু নতুনটায়। দুই জায়গার data আলাদা হয়ে যাবে, আর কোনটা সঠিক, সেটা বলার উপায় থাকবে না। এই অবস্থার নাম split brain (সেশন ০৩)। Payment এর data নিয়ে এই ঝুঁকি নেওয়া যায় না। তাই team কে সামনের দিকেই এগোতে হলো, আর বাকি নয় মিনিট ভুগতে হলো।

শিক্ষাটা পরিষ্কার। Abort action টা experiment এর শুরুতে কাজ করতো, কিন্তু দুই মিনিট পরে আর করতো না। এখন তাদের abort plan এ দুটো আলাদা action লেখা থাকে। Promotion এর আগে abort করলে পুরোনো primary চালু করা হয়। Promotion এর পরে abort করলে app server গুলোকে জোর করে নতুন primary তে পাঠানো হয়। আর দুটো action ই আগে staging এ চালিয়ে দেখা হয়।

থামার পথ না জেনে শুরু করবেন না

Abort condition বলে দেয় কখন থামতে হবে। Abort action বলে দেয় কীভাবে থামতে হবে। দুটোই আগে থেকে লেখা থাকতে হবে, আর abort action টা experiment এর প্রতিটা মুহূর্তে কাজ করে কিনা, সেটা আলাদা করে test করতে হবে। সম্ভব হলে abort টা automatic রাখুন। চাপের মুহূর্তে মানুষ প্রায়ই বলে, “আরেকটু দেখি।“

০৯ অভিজ্ঞতা নেই এমন একটা team কোথা থেকে শুরু করবে?

তাসনিমের team প্রথম দিনেই সবচেয়ে বড় experiment টা করেছিলো। আপনার team কে সেটা করতে হবে না। শুরু করার একটা নিরাপদ সিঁড়ি আছে:

একটা ধাপ পাস করলে তবেই পরের ধাপে ধাপ ১ কাগজে কলমে (tabletop) ধাপ ২ staging এ 1 server বন্ধ ধাপ ৩ production এ 1 server, দুপুরে ধাপ ৪ latency, DB failover ধাপ ৫ নিয়মিত, auto প্রতি সপ্তাহে
প্রথম দিন কিছুই ভাঙতে হয় না, শুধু টেবিলে বসে আলোচনা। তারপর staging, তারপর production এর একটা মাত্র server। Database failover এর মতো বড় experiment আসে চার নম্বর ধাপে, প্রথমে নয়।
  1. Tabletop exercise: কোনো system ছোঁয়া হয় না। Team whiteboard এর সামনে বসে আলোচনা করে: “Primary database বন্ধ হলে ঠিক কী কী হবে? কে টের পাবে? কত সেকেন্ডে?” অবাক হওয়ার মতো বিষয় হলো, শুধু এই আলোচনাতেই অনেক দুর্বলতা ধরা পড়ে। তাসনিমের team এটা করলে হয়তো DNS TTL এর কথাটা আগেই কারো মাথায় আসতো।
  2. Staging এ ছোট fault: একটা server বন্ধ করে দেখুন। এখানে উদ্দেশ্য hypothesis লেখা, dashboard পড়া আর abort action চালানো অভ্যাস করা।
  3. Production এ ছোট fault: কম ভিড়ের সময়ে, পুরো team এর সামনে, ছয়টার মধ্যে একটা app server বন্ধ করুন।
  4. বড় experiment: Latency injection, database failover, এরপর একটা zone। প্রতিবার blast radius এক রিং করে বাড়ান।
  5. নিয়মিত আর automatic: যে experiment গুলো বারবার পাস করে, সেগুলোকে প্রতি সপ্তাহে নিজে থেকে চলার ব্যবস্থা করুন। তাহলে নতুন code বা configuration কোনো পুরোনো fix নষ্ট করলে সাথে সাথে ধরা পড়বে।

শুরুর আগে যা থাকতেই হবে

আজ তাসনিমের team এ প্রতি বৃহস্পতিবার দুপুর তিনটায় ১৫ মিনিটের একটা ছোট experiment চলে। কেউ যখন জিজ্ঞেস করে system কতটা নির্ভরযোগ্য, তাসনিম এখন অন্যভাবে উত্তর দেয়: “আমাদের ২ টা replica আছে। আর গত বৃহস্পতিবার নিজের চোখে দেখেছি, failover ৪৮ সেকেন্ডে হয়।”

ছোট শুরুই আসল শুরু

প্রথম experiment এর কাজ system এর সব দুর্বলতা খুঁজে বের করা নয়। এর কাজ team কে অভ্যাস করানো: hypothesis লেখা, dashboard পড়া, আর নির্ভয়ে abort করা। এই অভ্যাস তৈরি হলে বড় experiment গুলো নিরাপদ হয়।

১০ মগজে প্রেশার দিন

আগে নিজে ভাবুন। তারপর উত্তর খুলে দেখুন: বেশিরভাগ মানুষ কীভাবে ভাবে, সেই চিন্তায় কী বাদ পড়ে, আর আসল কথাটা কোথায়।

প্রশ্ন ১: Production এ ইচ্ছে করে জিনিস ভাঙা কি পাগলামি না? Staging এ করাই কি নিরাপদ নয়?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Production এ আসল user থাকে। তাই সেখানে কিছু ভাঙা ঠিক নয়। সব test staging এ করা উচিত, production কে শান্তিতে থাকতে দেওয়া উচিত।”

Staging এ শুরু করার কথাটা ঠিক। কিন্তু এই চিন্তায় একটা বড় সত্য বাদ পড়েছে।

যে জায়গাটা যোগ করা দরকার

Production এ failure আসবেই। Primary একদিন বন্ধ হবেই, একটা zone একদিন অন্ধকার হবেই। প্রশ্ন শুধু এটা, failure টা কখন আসবে আর তখন কে তৈরি থাকবে। Chaos engineering এ আপনি সময়টা বেছে নেন: দুপুর তিনটা, কম ভিড়, পুরো team সামনে, blast radius ছোট, abort রেডি। না করলে সময়টা failure নিজেই বেছে নেয়, আর সেটা প্রায়ই ঈদের রাত দুইটা।

আর staging production এর সব প্রশ্নের উত্তর দিতে পারে না। DNS TTL, configuration drift, আসল traffic, এগুলো শুধু production এই থাকে।

সঠিক ভাষায়

Chaos engineering ঝুঁকি তৈরি করে না। ঝুঁকিটা আগে থেকেই আছে। Chaos engineering সেই ঝুঁকিকে এমন একটা সময়ে সামনে আনে, যখন সেটা সামলানো সবচেয়ে সস্তা।

প্রশ্ন ২: "Chaos engineering মানে Chaos Monkey চালিয়ে random server বন্ধ করা।" এই কথাটা কতটা ঠিক?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Chaos engineering হলো production এ এলোমেলোভাবে server বন্ধ করা, যাতে engineer রা সতর্ক থাকে। Netflix এর Chaos Monkey ঠিক এটাই করে।”

Chaos Monkey এর বর্ণনাটা ঠিক আছে। কিন্তু chaos engineering এর সংজ্ঞা হিসেবে এটা অসম্পূর্ণ।

যে জায়গাটা যোগ করা দরকার

Random ভাবে server বন্ধ করা একটা fault injection এর উপায় মাত্র। Chaos engineering হলো পুরো experiment টা: আগে steady state মাপা, তারপর hypothesis লেখা, blast radius ছোট রাখা, abort condition ঠিক করা, তারপর ফলাফল মিলিয়ে দেখা। এগুলো ছাড়া server বন্ধ করলে আপনি জিনিস ভাঙলেন ঠিকই, কিন্তু কিছু শিখলেন না।

Chaos Monkey ও কিন্তু এলোমেলো নয়। এটা চলে শুধু অফিসের সময়ে, আর Netflix এর service গুলো আগে থেকেই একটা server হারানো সামলানোর মতো করে বানানো।

মাথায় রাখুন

Fault injection হলো যন্ত্র, chaos engineering হলো পদ্ধতি। Hypothesis আর মাপা না থাকলে সেটা experiment নয়।

প্রশ্ন ৩: Experiment এ hypothesis ভুল প্রমাণ হলো। তাহলে কি experiment টা fail করলো?
উত্তর দেখুন আগে নিজে ভাবুন

সবাই যেভাবে ভাবে

“Hypothesis ছিলো ৬০ সেকেন্ডে failover হবে। লাগলো ১১ মিনিট। মানে experiment fail করেছে, আর team এর জন্য এটা একটা খারাপ দিন।”

তাসনিমেরও প্রথমে ঠিক এমনই মনে হয়েছিলো। কিন্তু হিসাবটা উল্টো।

যে জায়গাটা যোগ করা দরকার

Experiment এর কাজ system কে পাস করানো নয়, সত্যটা জানা। Hypothesis ভুল প্রমাণ হওয়া মানে আপনি একটা লুকানো দুর্বলতা খুঁজে পেয়েছেন, আর সেটাও দিনের আলোয়, সবার সামনে, নিয়ন্ত্রিত পরিবেশে। তাসনিমের game day চারটা দুর্বলতা খুঁজে দিয়েছে, যেগুলো আট মাস ধরে চুপচাপ লুকিয়ে ছিলো। এটা সেই team এর সবচেয়ে কাজের দিনগুলোর একটা।

Experiment আসলে fail করে তখন, যখন কিছুই মাপা হয়নি, কেউ কিছু লেখেনি, আর পরে কোনো fix হয়নি।

মাথায় গেঁথে নিন

Hypothesis টিকে গেলে আপনি আত্মবিশ্বাস পেলেন। Hypothesis ভুল প্রমাণ হলে আপনি একটা দুর্বলতা পেলেন। দুটোই লাভ। ক্ষতি শুধু তখন, যখন experiment থেকে কিছুই শেখা হয় না।

১১ যে টার্মগুলো শিখলাম

টার্মমানে
Chaos engineeringইচ্ছে করে, নিয়ন্ত্রিতভাবে system এ failure ঢুকিয়ে দেখা system কেমন আচরণ করে, যাতে আসল failure এর আগেই দুর্বলতা পাওয়া যায়।
Steady stateSystem এর স্বাভাবিক অবস্থা, একটা মাপা যায় এমন user এর সংখ্যায় লেখা। যেমন payment success rate ৯৯.৭%।
HypothesisExperiment এর আগে লেখা অনুমান: “X ঘটলে steady state Y এর মধ্যে থাকবে।” ভুল প্রমাণ করা যায়, এমন হতে হয়।
Control group / Experiment groupযে দলে fault নেই আর যে দলে fault আছে। দুই দলের পার্থক্যই fault এর প্রভাব।
Fault injectionইচ্ছে করে একটা নির্দিষ্ট failure ঢোকানো: server বন্ধ, latency, packet drop, disk ভরানো, zone down।
Blast radiusExperiment ভুল হলে ক্ষতি কতদূর ছড়াবে: কতজন user, কয়টা service, কতক্ষণ।
Canaryনতুন কিছু প্রথমে অল্প কিছু user (যেমন ১%) এর উপর চালানো।
Availability zoneএকটা cloud region এর ভেতরে আলাদা বিদ্যুৎ আর network ওয়ালা আলাদা data center।
Game dayআগে থেকে ঠিক করা একটা দিন, যেদিন পুরো team একসাথে ইচ্ছে করে failure ঘটায়, দেখে আর শেখে।
Abort conditionআগে থেকে লেখা একটা সীমা। পার হলেই experiment সাথে সাথে থামে।
Abort actionExperiment থামানোর ধাপ: fault বন্ধ করে system কে আগের অবস্থায় ফেরানো।
Tabletop exerciseকোনো system না ছুঁয়ে, শুধু আলোচনা করে একটা failure এর কথা ভেবে দেখা।
Configuration driftসময়ের সাথে staging আর production এর setting ধীরে ধীরে আলাদা হয়ে যাওয়া।
Connection poolDatabase এর সাথে আগে থেকে খুলে রাখা কিছু connection, যেগুলো application বারবার ব্যবহার করে।
Chaos MonkeyNetflix এর tool, যেটা অফিসের সময়ে production এর random server বন্ধ করে। ২০১২ থেকে open source।

১২ শর্ট সামারি

  1. যে redundancy কখনো test হয়নি, সেটা একটা অনুমান মাত্র। Staging production এর সব পার্থক্য (DNS TTL, configuration drift, আসল traffic) দেখাতে পারে না, তাই শেষ উত্তর আসে production থেকেই।
  2. Chaos engineering একটা নিয়ন্ত্রিত experiment। আগে user এর সংখ্যায় steady state মাপা হয়, তারপর ভুল প্রমাণ করা যায় এমন একটা hypothesis লেখা হয়, তারপর ছোট blast radius এ fault inject করে ফলাফল মিলিয়ে দেখা হয়।
  3. প্রতিটা experiment এর আগে abort condition (কখন থামবো) আর abort action (কীভাবে থামবো) লেখা থাকতে হয়, আর abort action টা experiment এর প্রতিটা মুহূর্তে কাজ করে কিনা, সেটাও test করতে হয়।
  4. নতুন team tabletop আলোচনা আর staging দিয়ে শুরু করে, তারপর production এর একটা server, তারপর ধাপে ধাপে বড় experiment। Game day এর আসল ফল হলো fix এর তালিকা, আর পরের game day তে সেই fix এর প্রমাণ।

১৩ মনে রাখুন