Initializing...
Initializing...

জনপ্রিয়তার সাথে সাথে অ্যাপ্লিকেশন ইউজার ও কনটেন বাড়তে লাগলো। ধরা যাক, মিলিয়ন ইউজার ছাড়িয়ে গেল অ্যাপ্লিকেশনটা। যার ফলে ডাটাবেস কুয়েরি টাইম বেড়ে গেল। ফলে দেখা দিল ইউজার 𝐃𝐢𝐬𝐬𝐚𝐭𝐢𝐬𝐟𝐚𝐜𝐭𝐢𝐨𝐧। ইউজার চলে যাওয়া শুরু করলো অন্য কোন প্লাটফর্মে।
এই সমস্যা সমাধানের জন্য জানতে হবে ডাটাবেস কী করে কাজ করে?
ধরা যাক '𝐗' এসে আমার প্লাটফর্মে তার ইনফরমেশন দেখতে চায়। আমার অ্যাপ্লিকেশনে '𝐍' নম্বর অফ ইউজার আছে। ডাটাবেস '𝐗' এর ইনফরমেশন দেখানোর জন্য প্রতেক রোতে গিয়ে দেখবে '𝐗' এর ইনফরমেশন আছে কী না ওই রোতে বা বলা যায় পুরো টেবিলে '𝐗' কে খোঁজার চেষ্টা করবে। ধরা যাক '𝐍' নম্বর রোতে গিয়ে ডাটাবেস '𝐗' এর ইনফরমেশন পেল। যাকে এলগরিদমিক ভাষায় লিনিয়ার সার্চ বলা হয়।
কিন্তু এখন যদি আমার ইউজার ১ মিলিয়ন হয়! তখন '𝐍' অফ রো তে খুঁজতে গেলে কী পরিমান সময় লাগবে! যদি এলগরিদমিক ভাবে বলি, তাহলে সময় লাগবে 𝐎(𝐧) টাইম যেখানে 𝐧-এর মান হবে কতগুলো রোতে গিয়ে খুঁজ হচ্ছে। '𝐍' এর মান সবচেয়ে বেশি হবে যখন সর্বশেষ রোতে গিয়ে খুঁজা লাগবে।
তাহলে সমাধান?
খুবই সহজ। যে '𝐊𝐞𝐲' দিয়ে আমরা ডাটা খুঁজার চেষ্টা করে তাকে ইনডেক্স করে দিয়া।
ইনডেক্স আবার কী জিনিস?
ছোটবেলায় আমরা কীভাবে ডিকশনারি থেকে শব্দ খুঁজতাম মনে আছে? প্রতিটি পৃষ্ঠা না খুলে, সরাসরি প্রথম অক্ষর দেখে নির্দিষ্ট শব্দ খুঁজে বের করতাম। ঠিক একইভাবে যখন কোন '𝐊𝐞𝐲', ধরা যাক '_𝐢𝐝' বা কারো নাম এর '𝐊𝐞𝐲' এর উপরে ইনডেক্স করা হয় তখন ডাটাবেসও একইভাবে '𝐗' নামের ব্যক্তিকে খুঁজার চেষ্টা করে। এলগরিদমিক ভাষায় যাকে বাইনারি সার্চ বলা হয়।
আমাদের ভাষায় যখন কোন কিছু দেখতে যত সহজ মনে হবে, ভিতরে গেলে দেখা যাবে এত সহজও না।
ডাটাবেস ইনডেক্স করা কলামকে দূরত্ব তথ্য খুঁজে বের করার জন্য নিজস্বভাবে সাজিয়ে রাখে। বলা যেতে পারে, ডিকশনারির মতো, যেখানে শব্দগুলো অক্ষরের ক্রমে সাজানো থাকে। 𝐁 𝐓𝐫𝐞𝐞 বা 𝐁+ 𝐓𝐫𝐞𝐞 হলো ডাটাবেসে ইনডেক্সের জন্য ব্যবহৃত 𝐝𝐚𝐭𝐚 𝐬𝐭𝐫𝐮𝐜𝐭𝐮𝐫𝐞। 𝐌𝐲𝐒𝐐𝐋, 𝐏𝐨𝐬𝐭𝐠𝐫𝐞𝐒𝐐𝐋, 𝐎𝐫𝐚𝐜𝐥𝐞, 𝐌𝐚𝐫𝐢𝐚𝐃𝐁 ইত্যাদি এই 𝐁+ 𝐓𝐫𝐞𝐞 ডাটা স্ট্রাকচার ব্যবহার করে।
সমস্যার সমাধান এখানে হলে ভালোই হতো। কিন্তু না, সমস্যার সমাধান করতে গিয়ে নতুন সমস্যা দেখা দেয়।
ডাটাবেস যখন 𝐁+ 𝐓𝐫𝐞𝐞 ডাটা স্ট্রাকচারের ব্যবহার করে, তখন নতুন ইনসার্ট বা আপডেটের সময় প্রাসঙ্গিক লিফ নোড এবং কিছু ইন্টারনাল নোড আপডেট বা স্প্লিট হয়। যত বড় ডাটাবেস, তত বেশি নোডের সংখ্যা, 𝐓𝐫𝐞𝐞 এর সাইজও তত বড়। যার ফলে বড় ডাটাবেসে এই প্রক্রিয়া ধীর হতে পারে। এর ধীরতার কারণ সাধারণত 𝐝𝐢𝐬𝐤 𝐈/𝐎, 𝐜𝐚𝐜𝐡𝐞 𝐦𝐢𝐬𝐬𝐞𝐬 বা 𝐧𝐨𝐝𝐞 𝐬𝐩𝐥𝐢𝐭 অপারেশন।
তাহলে এর সমাধান আমরা কিভাবে করতে পারি?
ডাটাবেসকে 𝐋𝐨𝐠𝐢𝐜𝐚𝐥 𝐏𝐚𝐫𝐭𝐢𝐭𝐢𝐨𝐧𝐢𝐧𝐠 করে। একক্ষেত্রে আমাদের ডাটাবেস একটাই থাকবে, কিন্তু নির্দিষ্ট কিছু কন্ডিশনের ভিত্তিতে আমরা টেবিলকে লজিক্যালভাবে পার্টিশন করতে পারি। যেমন ধরা যেতে পারে ইউজার টেবিলে আমার ডাটা আছে ১ মিলিয়ন। ইউজারগুলো বিভিন্ন বিভাগে বাস করে। উক্ত শহরের উপরে ভিত্তি করে আমরা পারটিসন করে পারি ইউজার টেবিলকে। ফলে দেখা যেতে কোন বিভাগে ব্যবহারকারি সংখ্যা কম বেশি হতে পারে।যেই বিভাগে ব্যবহারকারী বেশি, সেটাকে আবার সাব-পার্টিশন করা যেতে পারে।যেহেতু এখন কম ডাটা একটা টেবিলে, কুয়েরি টাইম আর পারফরমেন্সও উন্নতি হবার কথা।
সমস্যা তেরি হয় তখন যখন ডাটাবেসে '𝐉𝐨𝐢𝐧𝐢𝐧𝐠' বা '𝐀𝐠𝐠𝐫𝐞𝐠𝐚𝐭𝐢𝐨𝐧' এর মতো কাজগুলো করা লাগে। যেহেতু টেবিল ভিন্ন, সেহেতু অন্য টেবিল থেকে ডাটা '𝐉𝐨𝐢𝐧𝐢𝐧𝐠' বা '𝐀𝐠𝐠𝐫𝐞𝐠𝐚𝐭𝐢𝐨𝐧' এ আগের থেকে ধীর গতি চলে আসে।
তাহলে উপায়?
ডাটাবেসকে 𝐇𝐨𝐫𝐢𝐳𝐨𝐧𝐭𝐚𝐥 স্কেলিং করে। 𝐇𝐨𝐫𝐢𝐳𝐨𝐧𝐭𝐚𝐥 স্কেলিং বলতে বুঝায়, একটা ডাটাবেসকে মাল্টিপল সার্ভারে রাখা। এখান থেকেই শুরু হয় ডাটাবেস স্কেল করা।
𝐌𝐚𝐬𝐭𝐞𝐫 𝐒𝐥𝐚𝐯𝐞 𝐑𝐞𝐩𝐥𝐢𝐜𝐚𝐭𝐢𝐨𝐧 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞
ডাটাবেসে সবরাচর ২ ধরণের রিকোয়েস্ট হয়ে থাকে।
১। রিড ( 𝐆𝐄𝐓 )
২। রাইট ( 𝐏𝐎𝐒𝐓, 𝐏𝐀𝐓𝐂𝐇, 𝐃𝐄𝐋𝐄𝐓𝐄 )
এবং আমাদের অ্যাপ্লিকেশনগুলি সাধারণত রিড হ্যাভি অ্যাপ্লিকেশন হয়ে থাকে। যার মানে ধারায়, ডাটাবেস রিড রিকোয়েস্ট অনেক বেশি আসে রাইট রিকোয়েস্টের তুলনায়।
এই সমস্যা সমাধানের জন্য আমরা রিড রিকোয়েস্ট এর অনেকগুলো সার্ভারে রাখতে পারে। যার ফলে ওই সার্ভার শুধু রিড রিকোয়েস্ট সারভ করা হবে।
আর একটা থাকবে 𝐌𝐚𝐬𝐭𝐞𝐫 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞। যেখানে সব রাইট অপারেশন ঘটবে। আগে যেখানে একটা সার্ভার রিড ও রাইট দুইটাই করতো, এখন রিড রিকোয়েস্টের চাপ অনেকটা ভাগ হয়ে গেছে। তার সাথে ডাটাবেসও স্কেল হয়ে গেল। কারন এখন রিড রিকোয়েস্ট এর জন্য আছে মাল্টিপল সার্ভার।
কিন্তু সমস্যা আসে তখন যখন 𝐌𝐚𝐬𝐭𝐞𝐫 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞-এ যখন কোন কিছু রাইট হয়। যেহেতু, রাইট অপারেশনের ডাটাবেস অনেকগুলো আমার 𝐌𝐚𝐬𝐭𝐞𝐫 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞-এর মডিফাইড/ আপডেটেড রিড রেপ্লিকাতে পপুলেট করতে হয়। কিন্তু দেখা যায়, এই পপুলেট করতেও কিছু সময় ডিলে হয়ে যায়। হতে পারে তা মিলি সেকেন্ড বা তার বেশি। এই সময়ের মধ্যে যদি ইউজার তার আপডেটেড ডাটা দেখতে যায় এবং তা যদি পপুলেট না হয়ে থাকে!
তাহলে সমাধান?
ডাটাবেসে একটা 'লগ' ফাইল থাকে। যেখা প্রত্যেকটা ডাটার লগ রাখা হয়। 𝐌𝐲𝐒𝐐𝐋-এ যাকে '𝐁𝐢𝐧 𝐋𝐨𝐠' এবং 𝐏𝐨𝐬𝐭𝐠𝐫𝐞𝐒𝐐𝐋-এ যাকে 𝐖𝐫𝐢𝐭𝐞-𝐀𝐡𝐞𝐚𝐝 𝐋𝐨𝐠𝐠𝐢𝐧𝐠 বা 𝐖𝐀𝐋 বলা হয়। লগ ফাইলে যখন কোন কিছু আপডেট হয় তখন দেখতে এমন দেখায় “𝐑𝐨𝐰 𝐚𝐝𝐝𝐞𝐝 𝐭𝐨 𝐮𝐬𝐞𝐫𝐬 𝐭𝐚𝐛𝐥𝐞”।
ডাটাবেসের ভেতরে একটা মেকানিজম আছে, যা সবসময় 'লগ' ফাইল পর্যবেক্ষণ করে থাকে। যাকে '𝐅𝐢𝐥𝐞 𝐂𝐡𝐚𝐧𝐠𝐞 𝐓𝐫𝐚𝐜𝐤𝐞𝐫'। এর কাজ হলো 'লগ' ফাইলকে মনিটর করা। 'লগ' ফাইলের নতুন কিছু আসলেই তা একটা '𝐄𝐯𝐞𝐧𝐭' ক্রিয়েট করে। 𝐌𝐲𝐒𝐐𝐋-এ যাকে '𝐆𝐓𝐈𝐃 𝐄𝐯𝐞𝐧𝐭' এবং 𝐏𝐨𝐬𝐭𝐠𝐫𝐞𝐒𝐐𝐋-এ যাকে 𝐋𝐨𝐠 𝐒𝐞𝐪𝐮𝐞𝐧𝐜𝐞 𝐍𝐮𝐦𝐛𝐞𝐫 বা 𝐋𝐒𝐍 বলা হয়। এই ইভেন্ট 𝐌𝐚𝐬𝐭𝐞𝐫 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞-এর পরিবর্তনগুলো 𝐒𝐥𝐚𝐯𝐞 বা 𝐑𝐞𝐚𝐝 𝐑𝐞𝐩𝐥𝐢𝐜𝐚 তে আপডেট করে দেয়।
𝐒𝐥𝐚𝐯𝐞 বা 𝐑𝐞𝐚𝐝 𝐑𝐞𝐩𝐥𝐢𝐜𝐚 তো বারানো হলো কিন্তু ডাটাবেসের সাইজ তো এখনো আগের মতোই আছে। এইটাকে কি আরো অপটিমাইজ করা যায় না ?
অবশ্যই যায়। সেই জায়গাতেই আসে 𝐃𝐚𝐭𝐚𝐛𝐚𝐬𝐞 𝐒𝐡𝐚𝐫𝐝𝐢𝐧𝐠। 𝐒𝐡𝐚𝐫𝐝𝐢𝐧𝐠 মানে হচ্ছে ডাটাকে ছোট ছোট অংশে ভাগ করে আলাদা সার্ভারে রাখা — কিন্তু এটিই ডাটাবেস স্কেলিংয়ের সবচেয়ে জটিল ধাপ।
ধরা যাক আমার ইউজার টেবিলে ১ মিলিয়ন ডাটা আছে। এর মধ্যে ৫ লাখ ডাটা আমরা একটি 𝐒𝐡𝐚𝐫𝐝-এ রাখলাম, আর বাকি ৫ লাখ অন্য একটি 𝐒𝐡𝐚𝐫𝐝-এ। যেহেতু ডাটার পরিমাণ কমে গেছে, সেহেতু কুয়েরি টাইমও কম লাগবে। এক্ষেত্রে আমরা দুইটার জায়গাতে আরো 𝐒𝐡𝐚𝐫𝐝 তেরি করতে পারে।
কিন্তু এক্ষেত্রেও '𝐉𝐨𝐢𝐧𝐢𝐧𝐠' বা '𝐀𝐠𝐠𝐫𝐞𝐠𝐚𝐭𝐢𝐨𝐧' করা কঠিন হয়ে উঠে। কারণ 𝐒𝐡𝐚𝐫𝐝 ভিন্ন বলে।
বিভিন্ন বড় বড় কোম্পানি এইভাবে ডাটাবেসকে স্কেল করে থাকে। তার একটা খুদ্র ধরণা যা আমি কিছুদিনের এক্সপ্লোরে জানতে পারেছি তা শেয়ার করার চেষ্টা করলাম।
আমি পুরো জিনিসটা প্র্যাকটিকালি করতে পারিনি, কিন্তু যতটুকু বুঝেছি — সেটা শেয়ার করলাম যাতে কেউ চাইলে আমার মতো নিজে এক্সপ্লোর করে আরো জানতে পারে।
𝐇𝐞𝐫𝐞 𝐢𝐬 𝐭𝐡𝐞 𝐜𝐨𝐦𝐩𝐥𝐞𝐭𝐞 𝐫𝐞𝐬𝐨𝐮𝐫𝐜𝐞 𝐢𝐟 𝐲𝐨𝐮 𝐰𝐚𝐧𝐭 𝐭𝐨 𝐝𝐞𝐞𝐩 𝐝𝐢𝐯𝐞:
- 𝐇𝐨𝐰 𝐅𝐢𝐠𝐦𝐚’𝐬 𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞𝐬 𝐭𝐞𝐚𝐦 𝐥𝐢𝐯𝐞𝐝 𝐭𝐨 𝐭𝐞𝐥𝐥 𝐭𝐡𝐞 𝐬𝐜𝐚𝐥𝐞: 𝐡𝐭𝐭𝐩𝐬://𝐰𝐰𝐰.𝐟𝐢𝐠𝐦𝐚.𝐜𝐨𝐦/𝐛𝐥𝐨𝐠/𝐡𝐨𝐰-𝐟𝐢𝐠𝐦𝐚𝐬-𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞𝐬-𝐭𝐞𝐚𝐦-𝐥𝐢𝐯𝐞𝐝-𝐭𝐨-𝐭𝐞𝐥𝐥-𝐭𝐡𝐞-𝐬𝐜𝐚𝐥𝐞
- 𝐏𝐚𝐫𝐭𝐢𝐭𝐢𝐨𝐧𝐢𝐧𝐠 𝐆𝐢𝐭𝐇𝐮𝐛’𝐬 𝐫𝐞𝐥𝐚𝐭𝐢𝐨𝐧𝐚𝐥 𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞𝐬 𝐭𝐨 𝐡𝐚𝐧𝐝𝐥𝐞 𝐬𝐜𝐚𝐥𝐞: 𝐡𝐭𝐭𝐩𝐬://𝐠𝐢𝐭𝐡𝐮𝐛.𝐛𝐥𝐨𝐠/𝐞𝐧𝐠𝐢𝐧𝐞𝐞𝐫𝐢𝐧𝐠/𝐢𝐧𝐟𝐫𝐚𝐬𝐭𝐫𝐮𝐜𝐭𝐮𝐫𝐞/𝐩𝐚𝐫𝐭𝐢𝐭𝐢𝐨𝐧𝐢𝐧𝐠-𝐠𝐢𝐭𝐡𝐮𝐛𝐬-𝐫𝐞𝐥𝐚𝐭𝐢𝐨𝐧𝐚𝐥-𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞𝐬-𝐬𝐜𝐚𝐥𝐞/
- 𝐓𝐡𝐞 𝐆𝐫𝐞𝐚𝐭 𝐑𝐞-𝐬𝐡𝐚𝐫𝐝: 𝐚𝐝𝐝𝐢𝐧𝐠 𝐏𝐨𝐬𝐭𝐠𝐫𝐞𝐬 𝐜𝐚𝐩𝐚𝐜𝐢𝐭𝐲 (𝐚𝐠𝐚𝐢𝐧) 𝐰𝐢𝐭𝐡 𝐳𝐞𝐫𝐨 𝐝𝐨𝐰𝐧𝐭𝐢𝐦𝐞: 𝐡𝐭𝐭𝐩𝐬://𝐰𝐰𝐰.𝐧𝐨𝐭𝐢𝐨𝐧.𝐜𝐨𝐦/𝐛𝐥𝐨𝐠/𝐭𝐡𝐞-𝐠𝐫𝐞𝐚𝐭-𝐫𝐞-𝐬𝐡𝐚𝐫𝐝
- 𝐌𝐲𝐒𝐐𝐋 𝐀𝐭 𝐔𝐛𝐞𝐫: 𝐡𝐭𝐭𝐩𝐬://𝐰𝐰𝐰.𝐮𝐛𝐞𝐫.𝐜𝐨𝐦/𝐞𝐧-𝐁𝐃/𝐛𝐥𝐨𝐠/𝐦𝐲𝐬𝐪𝐥-𝐚𝐭-𝐮𝐛𝐞𝐫/
- 𝐓𝐡𝐞 𝐚𝐫𝐭 𝐚𝐧𝐝 𝐬𝐜𝐢𝐞𝐧𝐜𝐞 𝐨𝐟 𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞 𝐬𝐡𝐚𝐫𝐝𝐢𝐧𝐠: 𝐡𝐭𝐭𝐩𝐬://𝐩𝐥𝐚𝐧𝐞𝐭𝐬𝐜𝐚𝐥𝐞.𝐜𝐨𝐦/𝐛𝐥𝐨𝐠/𝐭𝐡𝐞-𝐚𝐫𝐭-𝐚𝐧𝐝-𝐬𝐜𝐢𝐞𝐧𝐜𝐞-𝐨𝐟-𝐝𝐚𝐭𝐚𝐛𝐚𝐬𝐞-𝐬𝐡𝐚𝐫𝐝𝐢𝐧𝐠