Database partitioning

Tecognize Training
May 16 at 7:00 PM  ·

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

প্রাথমিকভাবে আপনাকে ডাটাবেইজ স্কেল দুটি কারণে করতে হতে পারে। এর একটি কারণ হলো অনেক বেশি পরিমাণ লোড। আমার ডাটাবেজে প্রতিদিন মিলিয়নস অথবা বিলিয়নস অফ হিট পড়ে। সে ক্ষেত্রে আমরা যে কাজটা করতে পারি সেটা হচ্ছে ডাটাবেজের Replication করতে পারি। Replication এর ক্ষেত্রে আমরা একটা Master ডাটাবেজ রাখি এবং Master ডাটাবেজ থেকে Data বিভিন্ন Slave ডাটাবেজে রেপ্লিকেট করে ফেলি। Master ডাটাবেজে আমরা write করি এবং Slave গুলো থেকে আমরা শুধুমাত্র Read করি। সাধারণত যে সিস্টেমগুলোতে খুব বেশি পরিমাণ Read রিকোয়েস্ট পরে Write request এর তুলনায় সেক্ষেত্রে আমরা এই ধরনের Replication বা master-slave আর্কিটেকচার ব্যবহার করতে পারি। এখানে মাল্টিপল Master ডাটাবেইজ এনে আমরা জিনিসটাকে আরো কমপ্লেক্স করে ফেলতে পারি যদিও এতে আমাদের উপকারই হয়ে যায়।তবে এই ডাটাবেজ রেপ্লিকেশন এর কয়েকটা ডাউনসাইড আছে। এর একটা হল এটা মোটেও Write speed বাড়ায় না এবং আর একটা হচ্ছে Replication lag। Master এর মধ্যে যে Write request আসে সেটা Slave এর মধ্যে রেপ্লিকেট করার আগেই যদি Slave এর মধ্যে Read Request আসে তবে আমরা আপডেটের ডাটাটা পাইনা। একে বলা হয় Replication lag

 

আচ্ছা এবার আমরা চলে আসি আরেকটা সিনারিওতে যেখানে আমাদেরকে ডাটাবেজকে স্কেল করার প্রয়োজন পড়ে। সেটা হচ্ছে যখন আমাদের খুব বেশি পরিমাণ ডাটা সিস্টেমে চলে আসে বা থাকে। সেই ক্ষেত্রে Database partitioning বা Sharding করা যায়।
Partitioning বলতে বোঝায় আমরা একটা ডাটাবেজের একটা টেবিলের ডাটা গুলোকে ভিন্ন ভিন্ন টেবিলে ভাগ করে করে রাখবো। এখানে আমরা কুইরি করার সময় যদি জানি যে আমাদের কাঙ্খিত ডাটা কোন টেবিলটাতে আছে তাহলে শুধুমাত্র ওই টেবিলে হিট করলেই আমাদের চলবে। অন্যান্য পার্টিশন করা ডাটাবেজ গুলোতে আমাদেরকে হিট না করলেও চলবে। ডাটাবেজ পার্টিশনিং সাধারণত দুই প্রকার একটা হচ্ছে Vertical partitioning এবং আরেকটা Horizontal Partitioning.

 

প্রথমে বলি Vertical partitioning নিয়ে। এর মানে হচ্ছে আমাদের ডাটাবেজের কলাম গুলোকে ভাগ করে ফেলা। আচ্ছা একটা ইউজকেস বলি। ধরে নিই আমার একটা টেবিলে Customer ID, Customer name এবং আরেকটা Blob field আছে। Blob field এ কাস্টমারের ছবি বা ডকুমেন্ট ইত্যাদি থাকতে পারে যেটা কিনা খুব খুব বেশি কুইরী করা হয় না বা ব্যবহার করা হয় না। সাধারণত Blob field এ যে আইটেমগুলো থাকে সেগুলোর সাইজ অনেক বেশি হয় যেহেতু এগুলো ইমেজ বা ডকুমেন্ট টাইপের হয়। সেজন্য এই ফাইলগুলো আমার ডাটাবেজের যে টেবিল স্পেইস আছে বা জায়গা আছে সেটাকে খুব বেশি কনজিউম করে ফেলে। আমি দ্রুত ডাটাবেজ কুয়েরি করার জন্য যদি একটা SSD ব্যবহার করি সে ক্ষেত্রে তার বেশিরভাগ জায়গায় আমার ওই Blob file গুলো খেয়ে ফেলবে। যেহেতু আমার Blob file খুব ঘনঘন দরকার হয় না সেটা আমরা অন্যান্য যে মেকানিক্যাল হার্ডডিস্ক গুলো আছে সেটাতে রাখতে পারি । যেগুলো কিনা টেরাবাইটের পর টেরাবাইট পাওয়া যায় এবং খরচ অনেক কম। তাই আমরা Customer ID, Customer name এই দুটোকে একটা টেবিলে রাখবো এবং Blob Field টাকে আরেকটা টেবিলে পাঠিয়ে দিব যেটা কিনা একটা মেকানিক্যাল হার্ডডিস্কে থাকবে। এটাকে বলে Vertical partitioning করা।

 

আরেকটা পার্টিশনিং হলো Horizontal partitioning। Horizontal মানে হচ্ছে আমরা Row গুলোকে ভাগ করে ফেলি। ধরি আমাদের ১২ মিলিয়ন row রয়েছে। তো সেই জায়গায় আমরা এক থেকে চার মিলিয়ন,৪ থেকে ৮ মিলিয়ন এবং ৮ থেকে ১২ মিলিয়ন এরকম করে করে তিনটে ভাগের মধ্যে টেবিলটাকে ভাগ করে ফেলব। তবে এই জায়গায় ভাগ করার পর আমাদের টেবিলগুলোকে যদি আলাদা একটা Instance বা আলাদা সার্ভারে নিয়ে যেতে চাই সেটা কিন্তু আবার Sharding. তাকে তখন আর পার্টিশনিং বলা যাবে না। Partitioning এর ক্ষেত্রে আমরা Partitioning key ব্যবহার করি। সাধারণত আমাদের যে Unique primary key থাকে, ধরলাম এখানে Customer ID, তাকে আমরা Partitioning key হিসেবে ধরে নেই। তো যখন আমাদের একটা কুয়েরি আসবে আমরা যদি জানি যে আমাদের এই আইডিটা আমাদের কোন পার্টিশন করা টেবিলে আছে তাহলে শুধু ওই স্পেসিফিক টেবিলে হিট করলেই কিন্তু আমরা আমাদের কুয়েরির রেজাল্ট পেয়ে যাচ্ছি। তবে এই ডাটাবেজ পার্টিশনিং এর অনেকগুলো Downside আছে । তার একটা হলো গিয়ে Complex query আমাদের কে লিখতে হয়। যদি Query একটা Range of data তুলে আনে ডাটাবেজ থেকে এবং এই রেঞ্জের মধ্যে যে ডাটা গুলো আছে সেগুলো আমাদের সবগুলো পার্টিশন করা টেবিলেই ছড়িয়ে ছিটিয়ে আছে।তাই আলটিমেটলি আমাকে সবগুলো টেবিলেই কুয়েরি করতে হবে। তার ওপরে আবার Complex query লেখা লাগছে।

 

আরেকটা হলো গিয়ে Join operation টা খুব বেশী ডিফিকাল্ট হয়ে যায় এবং অসম্ভব হয়ে পড়ে। তবে এই সবকিছুর মাঝে ট্রেড অফ করে আমাদেরকে আমাদের ইউজারের Requirements এবং Use case অনুসারে সবচেয়ে বেস্ট সলিউশন টা বেছে নিতে হবে। এগুলোর মধ্যে ফিউশন করাও যেতে পারে। এ বিষয়ে বিস্তারিত জানতে আমি এর আগের ব্লগেও অবশ্য একটা বই সাজেস্ট করেছিলাম যেটা কিনা আমার ব্যক্তিগত পছন্দ সেই বইটা পড়তে পারেন (”Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems By Martin Kleppmann”)

REF: https://www.facebook.com/tecognizetraining/posts/543152304092050

Leave a Reply

Your email address will not be published.