𝗗𝟭 𝗥𝗲𝗮𝗱 𝗥𝗲𝗽𝗹𝗶𝗰𝗮𝘀-এ ছিল ৬ সেকেন্ডের ল্যাগ
টোকিওতে থাকা একটি D1 read replica, উত্তর আমেরিকায় করা একটি write-এর তুলনায় ৬.১ সেকেন্ড পিছিয়ে ছিল।
ভুল ইমপ্রেশন থ্রটলিং (throttling) করা একটি ট্র্যাকার থেকে আমি এটি জানতে পারি। ডকুমেন্টেশনে eventual consistency-র কথা উল্লেখ করা আছে। তবে পরিকল্পনার জন্য এটি কোনো নির্দিষ্ট সময় দেয় না।
প্রকৃত সংখ্যাগুলো বের করার জন্য আমি একটি staleness probe তৈরি করেছি। এই probe-টি একটি UUID এবং একটি epoch সহ একটি row লিখে। যতক্ষণ না row-টি দেখা যাচ্ছে, ততক্ষণ এটি replica-টিকে পোল (poll) করতে থাকে। এরপর এটি বিলম্বটি রেকর্ড করে।
এশিয়ায় ২০০টি probe থেকে প্রাপ্ত ফলাফল:
- p50: 800ms
- p95: 3,400ms
- p99: 6,100ms
আপনার primary যদি উত্তর আমেরিকায় থাকে এবং ব্যবহারকারীরা এশিয়ায় থাকে, তবে ল্যাগ অনেক বেশি হয়।
আমি একটি schema error-ও ফেস করেছি। Primary-তে একটি migration চালানো হয়েছিল। একটি Worker রিস্টার্ট হয়েছিল। নতুন table-টি আসার আগেই প্রথম রিকোয়েস্টগুলো একটি replica-তে পৌঁছে গিয়েছিল। এরর মেসেজে বলা হয়েছিল যে table-টি নেই। আসলে table-টি ছিল, কিন্তু replica-টি পিছিয়ে ছিল।
আমি ল্যাগ এড়িয়ে রুট করার মাধ্যমে এটি সমাধান করেছি। আমি এর বিরুদ্ধে লড়াই করি না।
আমার ডিজাইনটি নিচে দেওয়া হলো:
- Writer row-টিতে একটি written_at epoch যোগ করে।
- Writer রেসপন্সে একটি X-D1-Written-At header যোগ করে।
- Reader সেই header-টিকে replica থেকে পাওয়া ডেটার সাথে তুলনা করে।
- যদি replica-র ডেটা header-এর চেয়ে পুরনো হয়, তবে reader KV-তে ফিরে যায় (falls back)।
একই রিজিয়নে KV ৫০০ms-এর নিচে চলে। এটি প্রতিদিন ১০ মিলিয়ন রিড পর্যন্ত ফ্রি। এটি গুরুত্বপূর্ণ ফ্ল্যাগগুলোর জন্য ফ্রেশ ডেটা পাওয়ার একটি সাশ্রয়ী উপায়।
আপনি শুধুমাত্র সেই অল্প সময়ের জন্য KV ব্যবহার করবেন যখন replica পিছিয়ে থাকে। replica যখন তাল মিলিয়ে নেয় (catches up), তখন বেশিরভাগ রিড স্বাভাবিকভাবেই D1-এ ঘটে।
আমি আমার বিস্তারিত পোস্টে সম্পূর্ণ স্ক্রিপ্ট এবং migration pattern শেয়ার করেছি।