ব্লগ

সতর্কবার্তা একবার যায়, প্রতি সার্ভারে একবার নয়

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

লক্ষণ

Mythex কিছু দেখার দরকার হলে আমাদের দলকে সতর্কবার্তা পাঠায়: কোনো সার্ভিস নিচে গেছে, কোনো জব আটকে গেছে, বা একটি বিল্ডারের ক্রেডিট ব্যালেন্স কম এবং তার অ্যাপ প্রকাশিত। প্রতিটি সতর্কবার্তার একটি ডুপ্লিকেট-রোধ উইন্ডো আছে, অর্থাৎ একটি সময়কাল যার মধ্যে একই সতর্কবার্তা একবারই পাঠানো হয়। কম-ক্রেডিট সতর্কবার্তার জন্য সেই উইন্ডো ২৪ ঘণ্টা।

একটি বিকেলে একই সতর্কবার্তার পাঁচটি কপি মানে উইন্ডোটি ধরে রাখছিল না। আরও খারাপ, সেগুলো জোড়ায় জোড়ায় আসছিল, প্রায় ১১ মিনিট ব্যবধানে।

কেন এমন হলো

আমাদের alerts প্যাকেজ তার ডুপ্লিকেট-রোধ মেমরিতে রাখত: একটি টেবিল, "সতর্কবার্তার কী → শেষবার কখন পাঠানো হয়েছিল", চলমান প্রসেসের ভেতরে। একটি প্রসেস যা কখনো রিস্টার্ট হয় না, সেখানে এটি কাজ করে। প্রোডাকশনে দুটির কোনোটিই নেই:

  • দুটি API রেপ্লিকা। প্রোডাকশন API-র দুটি কপি চালায়। প্রতিটির নিজস্ব টেবিল ছিল, তাই প্রতিটি সতর্কবার্তা একবার পাঠিয়েছে। এটাই জোড়াগুলো।
  • ডিপ্লয়। প্রতিটি ডিপ্লয় দুটি রেপ্লিকাকেই নতুন প্রসেস ও খালি টেবিল দিয়ে প্রতিস্থাপন করে। ডিপ্লয়ের পর সতর্কবার্তা আবার গেছে, যেন কখনো পাঠানোই হয়নি।

দুটি সতর্কবার্তার মধ্যে প্রতি জোড়ার ~১১-মিনিটের ব্যবধান এসেছে সেই জব থেকে যা এই সতর্কবার্তা তৈরি করে। এটি দুটি রেপ্লিকাতেই চলে এবং একটি লক নেয়, তাই রেপ্লিকাগুলো পালাক্রমে সেটি জিতে নেয়, আর প্রতিটি তার পালায় সতর্কবার্তা তুলেছে।

এই একই কোডে একটি দ্বিতীয়, নীরব বাগও ছিল। টেবিল চিরকাল বড় হওয়া আটকাতে এটি ৫০০ কী হলে নিজেকে ছাঁটাই করত, যাতে ১৫ মিনিটের চেয়ে পুরোনো প্রতিটি এন্ট্রি মুছে যেত, তার উইন্ডো যা-ই হোক। ভারী লোডে একটি ২৪-ঘণ্টার ডুপ্লিকেট-রোধ মাত্র সিকি ঘণ্টা টিকতে পারত।

সমাধান

প্রতি সতর্কবার্তার জন্য একটি শেয়ার্ড রেকর্ড

API একটি সতর্কবার্তা পাঠানোর আগে এখন Redis-এ সেটির ডুপ্লিকেট-রোধ কী দাবি করে। Redis হলো একটি শেয়ার্ড ইন-মেমরি স্টোর, যার সাথে দুটি রেপ্লিকাই কথা বলে এবং API রিস্টার্ট হলেও যা থাকে। এই দাবিটি একটি একক অপারেশন: "এই কীটি সেট করো শুধু যদি না থাকে, এবং উইন্ডো শেষে এটির মেয়াদ শেষ করো।" যে রেপ্লিকা আগে দাবি করে সে সতর্কবার্তা পাঠায়; অন্যটি কীটি দখল দেখে চুপ থাকে। ডিপ্লয়ের পর একটি নতুন প্রসেস দেখে কীটি এখনো আছে।

কী ও উইন্ডো আসে alerts প্যাকেজের ব্যবহৃত একই নিয়ম থেকে, যা এখন দুটির মধ্যে শেয়ার করা হয়, তাই দুটি স্তর "একই সতর্কবার্তা" কী বোঝায় তা নিয়ে একমত না হয়ে পারে না।

ব্যর্থ হতে হবে খোলা দিকে, বন্ধ দিকে নয়

সবচেয়ে গুরুত্বপূর্ণ সিদ্ধান্ত ছিল Redis পৌঁছানো না গেলে কী করা হবে। আমরা সতর্কবার্তাটি পাঠানোই বেছে নিয়েছি। Redis ডাউন থাকলে, বা ১.৫ সেকেন্ডের মধ্যে সাড়া না দিলে, সতর্কবার্তা যায়। ডুপ্লিকেট সতর্কবার্তা শব্দদূষণ। বাদ পড়া সতর্কবার্তা মানে কাউকে জানানো হলো না।

সবচেয়ে গুরুতর সতর্কবার্তা, P0, ডুপ্লিকেট-রোধ দ্বারা একেবারেই আটকানো হয় না।

প্রতি এন্ট্রি তার নিজের উইন্ডো রাখে

alerts প্যাকেজের নিজস্ব ইন-মেমরি ডুপ্লিকেট-রোধে, প্রতিটি এন্ট্রি এখন সংরক্ষণ করে কখন তার উইন্ডো শেষ হয়, আর ছাঁটাইয়ে শুধু সেই এন্ট্রিগুলো মুছে যায় যাদের উইন্ডো শেষ। একটি ২৪-ঘণ্টার কী ২৪ ঘণ্টা টিকে থাকে, অন্য যত সতর্কবার্তাই আসুক।

একই বাগ, অন্য জায়গায়

একই প্যাটার্ন একটি ব্যাকগ্রাউন্ড কাজকেও দ্বিগুণ করেছিল: একটি রিকনসিলিয়েশন জব, যা প্রতিটি ওয়ার্কস্পেসের স্ট্যাটাসের আমাদের রেকর্ডকে আমাদের স্যান্ডবক্স প্রোভাইডারের সাথে মিলিয়ে রাখে। প্রতি পাসে অ্যাকাউন্টের প্রতিটি স্যান্ডবক্স তালিকাভুক্ত হয়, প্রোডাকশনে হাজার হাজার, প্রায় পাঁচ সেকেন্ড, পাশাপাশি চলমান বা বিরতিতে থাকা প্রতিটি প্রজেক্টও। দুটি রেপ্লিকাই প্রতি দুই মিনিটে এটি চালাত।

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

আমরা কীভাবে পরীক্ষা করেছি

টেস্টগুলো আসল সেটআপের মডেল। তারা alert মডিউলটি দুবার লোড করে, দুটি আলাদা "রেপ্লিকা" হিসেবে, দুটিকে একটি শেয়ার্ড স্টোরে নির্দেশ করে, প্রতিটি থেকে একই সতর্কবার্তা তোলে, তারপর "ডিপ্লয়ের পরে" স্বরূপ একটি তৃতীয় নতুন কপি লোড করে আবার তোলে। ঠিক একটি সতর্কবার্তা পাঠানো হয়। অন্য টেস্টগুলো যাচাই করে যে অন্য বিল্ডারের সতর্কবার্তা এখনো যায়, একটি P0 দুটি রেপ্লিকা থেকেই যায়, এবং স্টোর ডাউন বা টাইমআউটের বাইরে ঝুলে থাকলেও সতর্কবার্তা যায়। ছাঁটাই-ফিক্সের নিজস্ব টেস্ট আছে: ২০ মিনিট পরে আসা ৬০০ অন্য সতর্কবার্তার মধ্যেও একটি ২৪-ঘণ্টার কী টিকে থাকে।

রিকনসিলিয়েশন জবের জন্য, দুটি রেপ্লিকা একই সময়ে টিক দেয়, সাথে একই উইন্ডোতে তৃতীয় একটি টিক, এবং তা একটিমাত্র তালিকা তৈরি করে।

আমরা যা শিখেছি

  • ইন-মেমরি স্টেট প্রতি প্রসেসের। সার্ভারগুলোর মধ্যে যা সত্য হতে হবে, যেমন "একবার পাঠানো" বা "একবার চালানো", তাকে এমন কোথাও থাকতে হবে যা তারা শেয়ার করে।
  • ডিপ্লয় মানেই রিস্টার্ট। যে স্টেট পরবর্তী রিস্টার্ট পর্যন্তই টিকে থাকে, সে একটি স্বাভাবিক কর্মদিবসও টেকে না।
  • কোন দিকে ব্যর্থ হবে সেটি ঠিক করুন। সতর্কবার্তার জন্য, শেয়ার্ড স্টোর ডাউন থাকার মানে আরও সতর্কবার্তা হওয়া উচিত, কম নয়।
  • শুধু উদাহরণ নয়, প্যাটার্ন খুঁজুন। সতর্কবার্তাটি ছিল সবচেয়ে সরব ঘটনা; দ্বিগুণ হওয়া রিকনসিলিয়েশন জবটি ছিল একই বাগ, যা নীরবে কাজের খরচ বাড়াচ্ছিল।

Mythex-এর ভেতর থেকে এর কিছুই দেখা যায় না। প্ল্যাটফর্মকে কীভাবে স্থিতিশীল রাখি তার আরও জানতে দেখুন কীভাবে ডিপ্লয়ে শূন্য 502 ত্রুটিতে নামিয়েছি এবং সোয়াপ ফাইল না থাকার সমস্যা। একটি সার্ভিসের একাধিক কপি চালানোর ধারণায় আপনি নতুন হলে, আমাদের সার্ভার কী গাইডটি মৌলিক বিষয়গুলো ব্যাখ্যা করে।

Mythex · Pricing · AI দিয়ে যা খুশি বানান · ওয়েবসাইট ও অ্যাপের টেমপ্লেট · Mythex-এর তুলনা · AI অ্যাপ তৈরির শব্দকোষ · AI অ্যাপ তৈরির বিনামূল্যের টুল · English

English አማርኛ العربية Български Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)