কম্পিউটার টিউটোরিয়াল

ডাটাবেস বৃদ্ধি নিয়ন্ত্রণ: টেবিল আকার ছোট রাখার কৌশল এবং ডেটা ব্লোট এড়িয়ে চলুন

বেশিরভাগ ওয়েব অ্যাপ্লিকেশন কোনো ন কয়েক ধরনের ডেটা স্টোর ব্যবহার করে, প্রায়শই একটি রিলেশনাল ডাটাবেস। যখন একটি ওয়েব অ্যাপ সফল হয়, ডাটাবেসে ডেটা "হোয়ার্ডিং" (hoarding) বা জমা করে রাখা খুব সহজ হয়ে যায়। কিন্তু ডেটা হোয়ার্ডিং ডাটাবেস টেবিলের বাউন্ডलेস (unbounded) বৃদ্ধি করে (রো কাউন্ট এবং স্টোরড ডেটা সাইজ দুটোই)।

এটা একদম নির্দিষ্ট পয়েন্ট পর্যন্ত ঠিকমতো কাজ করে, কিন্তু কিছু ডেটা ব্লোট (data bloat) প্রতিরোধ করা — অথবা, আপনি যদি এটি প্রতিরোধ না করতে পারেন, তবেন আপনার ইনফ্রাস্ট্রাকচার আগে থেকে প্ল্যান করা বুদ্ধিমানের কাজ যাতে বৃদ্ধি যথাযথভাবে ম্যানেজ করা যায়।

ডুব মারার আগে, দেখি কীভাবে আমরা ব্লোটেড (bloated) অ্যাপ্লিকেশন নিয়ে পড়তে পারি।

আরো ডেটা সবসময় ভালো নয়

আমরা যেসব অ্যাপ্লিকেশনে কাজ করি, সেগুলো সময়ের সাথে বড় হয়ে যাওয়া টেন্ডেন্সি রাখে।

আপনি যদি আপনার ডাটাবেসের জন্য ক্লাউড প্রোভাইডার ব্যবহার করেন, আপনি আপনার অ্যালোকেটেড স্টোরেজ লিমিট হিট করতে পারেন। একবার সেটি হলে, আপনাকে একটি ভিন্ন ইনস্ট্যান্স টাইপে আপগ্রেড করতে হবে। Heroku PostgreSQL ডাটাবেসের লিমিট আছে, উদাহরণস্বরূপ, একটি "হবি" (hobby) টিয়ার ইনস্ট্যান্স ১GB ডেটা পর্যন্ত সীমাবদ্ধ।

আরো ডেটা থাকার কোয়েরি স্পিডের ওপর ইমপ্লিকেশনও আছে। যা раньше ইনডেক্স ছাড়া সম্ভব হতো, বড় টেবিলে অসম্ভব হয়ে যায়। কিছু রো রেঞ্জ স্ক্যান (row range scans) স্লো হয়ে যাবে। ডাটাবেস UPDATE এবং DELETE অপারেশন করার জন্য আরো লক (locks) অর্জন করা হবে।

ডাটাবেস টেবিল কীভাবে বড় হয়

ডেটা হোয়ার্ডিং ধীরে ধীরে হয়। আজ যা সমস্যা নয় সেটি সহজে এক মাস বা ছয় মাসে সমস্যা হয়ে যেতে পারে। ডেটা হোয়ার্ডিং সম্পর্কে সবচেয়ে ভয়ঙ্কর জিনিসটি হল এটি খুব সহজে মিস করা যায়। কিছু খুব ক্লাসিক সিনেরিও বিবেচনা করুন:

  • কমপ্লায়েন্স (compliance) কারণ/xhtml, আপনি paper_trail এর মতো একটি জেম আডপ্ট করেন এবং একটি audit_log_entries টেবিল পান। আপনার অ্যাপ্লিকেশনে যেকোনো সিগনিফিক্যান্ট মোডের অপারেশন audit_log_entries টেবিলে একটি রো তৈরি করে। সে অডিট লগ এন্ট্রিগুলো কখনো আর্কাইভ (archive) হয় না।
  • আপনি আপলোড এক্সেপ্ট করেন এবং ActiveStorage ব্যবহার করেন। আপনি আপলোডগুলো কখনো ডিলিট করেন না, তাই আপনার activestorage_blobs টেবিল বড় বড় হয়ে যাচ্ছে।
  • আপনি ওয়েবে পাবলিশ করার জন্য একটি শেয়ার্ড CMS (CMS) রান করেন, এবং আপনি আর্টিকেল সেগমেন্টস ডাটাবেসে স্টোর করার অনুমতি দেন। আপনার প্ল্যাটফর্ম সফল হয়, কিন্তু আপনার অধিকাংশ লেখক বই আকারের আর্টিকেল লিখে। pages টেবিল খুব সাইজেবল হয়ে যায় এমনকি যদি সেটি শুধু কয়েক হাজার পেজ ধারণ করে।
  • আপনি ইউজার-আপলোডেড কন্টেন্ট অনুমতি দেন, কিন্তু কমপ্লায়েন্স কারণ থেকে আপনি ডেটা ডিলিট করেন না, বরং paranoia এর মতো কিছু ব্যবহার করেন ফ্ল্যাগ দিয়ে ডিলিট করার জন্য। আপনার user_items টেবিল অনিশ্চিতকাল পর্যন্ত বড় হয়ে যায়, এবং আপনার জানা না জানে ১০ মিলিয়ন (10M) রো পার করে যায়।

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

প্রজেকশন (projections) বানানও অনেক সহজ হয়ে যায়। উদাহরণস্বরূপ:

  • আজ আমাদের events টেবিল মেমরিতে ফিট করে। বর্তমান গ্রোথ রেটে, সাত মাসে মেমরিতে ফিট করবে না।
  • আমাদের RDS ইনস্ট্যান্স টাইপের জন্য ৩০% স্টোরেজ ইউজে আছি। আমরা নেক্সট ইয়ার জানুয়ারি ৯০% হিট করব।
  • আমাদের payments টেবিলে একটি ফুল টেবিল স্ক্যান কোয়েরি আছে প্রতিটি রোয়ের ওপর একটি ফাংশন কম্পিউট করার জন্য যেখানে ইনপুট কোয়েরির ওপর ডিপেন্ড করে। আমরা জানি payments টেবিল তিন সপ্তাহে দুই মিলিয়ন রো এক্সিড করবে এবং নেক্সট ইয়ার জানুয়ারি ২০ মিলিয়ন।

এই সবই একটি ইন্সিডেন্ট বা আউটেজ (outage) হিসেবে উপস্থিত হতে পারে। কিন্তু আপনি যদি আগে আক্রমণ করুন, আপনি সহজে এই মিটিগেট (mitigate) করতে পারেন। উদাহরণস্বরূপ:

  • events টেবিলে ৩০ দিনের পুরনো সকল ডেটার জন্য আর্কাইভিং সেটআপ করুন।
  • চার মাসে আপনার RDS ইনস্ট্যান্স আপগ্রেড করুন।
  • ফুল টেবিল স্ক্যান লিমিট করতে, আমাদের কোয়েরিতে একটি অ্যাডিশনাল WHERE কন্ডিশন যোগ করুন ফাংশন কম্পিউট করার জন্য একটি ছোট সাবসেট রোয়ের ওপর।

আপনার ডাটাবেস বৃদ্ধির ওপর দৃষ্টি রাখুন (Gain Visibility Over Your Database Growth)

আপনার ডাটাবেস বৃদ্ধির ওপর চোখ রাখতে, আপনার দুটি সম্ভাবনা আছে:

  • স্পেশাল টুলিং ইনস্টল করুন (MySQL-এর জন্য stats 처럼) এবং আপনার মেট্রিক্স কলেকশন ইঞ্জিনের সাথে কানেক্ট করুন Prometheus, Telegraph, বা অন্যান্য টুলস দিয়ে।
  • AppSignal ব্যবহার করুন, বিশেষ করে আপনি যদি ইতিমধ্যে আপনার অ্যাপ্লিকেশনের জন্য এটি ব্যবহার করেন।

AppSignal বেশ কিছু মেট্রিক টাইপ স্টোর করতে পারে, এবং এগুলোর মধ্যে একটি মেট্রিক টাইপ হল gauge। একটি gauge হল একটি সিঙ্গেল টাইম সিরিজ পার এনভায়রনমেন্ট (যেমন production, staging, বা development) যা আপনি সময়ে সময় আপডেট করতে পারেন। AppSignal মেট্রিক্স ট্যাগসও সাপোর্ট করে, তাই আমরা অটোমেটিক্যালি কিছু ট্যাগড gauge মেট্রিক্স তৈরি করতে পারি আমাদের ডাটাবেস টেবিলসের জন্য। চলুন সেটি করি:

  • db.row_count আমাদের টেবিলগুলোর অনুমানিত রো সংখ্যা, পার টেবিল (আমরা অনুমানের কথা পরে বলব)
  • db.data_size_bytes একটি টেবিল কত বাইট ব্যবহার করছে সেটি
  • db.index_size_bytes একটি টেবিলের ইন্ডেক্সগুলো কত বাইট ব্যবহার করছে সেটি

দ্রষ্টব্য: আমি মেট্রিক নামের সাথে ভ্যালু টাইপ সাফিক্স (suffix) করছি — এটি পরে সাহায্য করে যখন আমরা ডিফাইন করব মেট্রিকটি কীভাবে ডিসপ্লে হবে। আলাদা "data" এবং "indices" মেট্রিক্সও গুরুত্বপূর্ণ। যদি একটি টেবিলে অনেক রো এবং একাধিক ইন্ডেক্স থাকে, সেই ইন্ডেক্সগুলোর সাইজ স্টোরড ডেটার সাইজের দু থেকে তিন গুণ হতে পারে (যেহেতু প্রতিটি ইন্ডেক্স নিজের জন্য ডেরাইভড ডেটা স্টোর করে, কিছু স্টোরেজ ওভারহেড সৃষ্টি করে)।

ডাটাবেস টেবিল রো দ্রুত কাউন্ট করা (Counting Database Table Rows Quickly)

"অনুমানিত" (approximate) পার্ট রো সংখ্যার অত্যন্ত গুরুত্বপূর্ণ। সাধারণত, আপনি যদি একটি টেবিলে সঠিক রো সংখ্যা চান, আপনি SELECT COUNT(1) FROM my_table এর মতো একটি কোয়েরি করতে পারেন। যেদবি, এটি আমাদের পছন্দের চেয়ে স্লোয়ার হতে পারে।

আপনি যখন COUNT করেন, ডাটাবেস নিশ্চিত করে টেবিলে রো সংখ্যা কোয়েরি চলার সময় পরিবর্তন হয় না — এবং সেটি টেবিল লক (lock) করে বা একটি ডাইভার্জেন্ট ট্রানজ্যাকশন তৈরি করে কোয়েরি চলার সময়। টেবিল যত বড়, কোয়েরিটি তত স্লো — বেশি রো স্ক্যান হবে, এবং বেশি লক জমা হবে।

তাই, যখন আমাদের শুধু একটি "ক্লোজ ইনাফ" (close enough) অনুমান চাই রো সংখ্যার (পারফরম্যান্স এস্টিমেশনের জন্য, ১০-৩০ হাজার রো কম বা বেশি প্রিসিশনかな ভালো), আমরা ইন্টারনাল ডাটাবেস ইঞ্জিন পরিসংখ্যান ব্যবহার করতে পারি এই টাইপের ডেটা কোয়েরি করার জন্য।

অধিকাংশ ডাটাবেসে টেবিল ডেটার অপ্টিমাইজড অ্যাক্সেস থাকে যেহেতু রোগুলো "পেজ" (pages) আকারে লেখা হয়। ডাটাবেস ইঞ্জিন ট্র্যাক রাখে কোন রো কোন পেজে অ্যাসাইন করা আছে, примерно ইনসারশন অর্ডার (insertion order) অনুযায়ী:

  • রো ১-১০০ পেজ ১-এ
  • রো ১০১-২০০ পেজ ২-এ
  • রো ২০১-৩০০ পেজ ৩-এ

এবং এভাবে।

যেহেতু ইঞ্জিন জানে টেবিল প্রতি কত পেজ আছে এবং প্রায় রো কাউন্ট পার পেজ, সেটি পেজ কাউন্ট করে যা এটিকে অ্যালোকেট করা আছে এবং তারপর পেজ সাইজ (রো পার পেজ) দিয়ে গুন করে সেই অনুমানটি দেয়। এর কিছু সুবিধা আছে: কাউন্ট খুব দ্রুত, এবং টেবিল লক করতে হয় না কোয়েরি চলার সময়।

MySQL-এ টেবিল সাইজ রেকর্ড করা (Record Table Sizes for MySQL)

আমরা যা করব সেটি ডাটাবেস অনুযায়ী ভিন্ন যেহেতু আমাদের ডাটাবেস ইঞ্জিন থেকে টেবিল পরিসংখ্যান কোয়েরি করতে হয়। MySQL-এ শুরু করি। এখানে আমাদের যা কোয়েরি চালাতে হবে:


তারপর আউটপুট থেকে কয়েকটি কলাম গ্র্যাব করুন। যেসব আমরা আগ্রহী সেগুলো হল Data_length, Index_length, এবং Rows। একটি টেবিলের সাইজ ডিফাইন করা হয় Data_length + Index_length-এর সমষ্টি হিসেবে, এবং পেজ-ভিত্তিক অনুমানিত রো কাউন্ট আছে Rows-এ।

এটি পুরো ডাটাবেসের জন্য ডেটা কালেক্ট করার একটি কোড ব্লকে প্যাকেজ করি। যেহেতু আমরা কোনো ActiveModel ক্লাসের সাথে কাজ করছি না, আমরা ActiveRecord দ্বারা সরাসরি প্রদত্ত কোয়েরি মেথডস ব্যবহার করব:



PostgreSQL-এ টেবিল সাইজ রেকর্ড করা (Record Table Sizes for PostgreSQL)

PostgreSQL-এর জন্য আমাদের একটি বেশি এলাবোরেট (elaborate) কোয়েরি দরকার যেহেতু SHOW TABLE STATUS এর মতো একটি শর্টকাট কোয়েরি আমাদের নেই। আমাদের ইন্টারন্যাল PostgreSQL টেবিলস কোয়েরি করতে হবে:


দ্রষ্টব্য: এটি শুধু public স্কিমা (ডিফল্ট যেটি আপনি সম্ভবত ব্যবহার করছেন) এর হিসাব করে। আপনি যদি অন্যান্য স্কিমা অন্তর্ভুক্ত করতে চান, আপনাকে WHERE t.table_schema = 'public' কন্ডিশনটি সরাতে হবে এবং table_info.fetch('name') কে table_info.fetch('full_table_name') দিয়ে রিপ্লেস করতে হবে।

নিশ্চিত করুন মেট্রিক্স নিয়মিত আপডেট হচ্ছে (Make Sure Metrics Update Regularly)

এই ব্লকে নিয়মিত ইন্টারভালে রান করতে হবে, তাই সেটিকে Sidekiq শিডিউলার (scheduler) বা একটি রেক টাস্ক যেটি cron থেকে চলে সেটিতে রাখা ভালো আইডিয়া। উদাহরণস্বরূপ, আপনি যদি good_job ব্যবহার করেন, আপনি আপনার "cron" সেকশনে এড করতে পারেন এরকম:



একটি ড্যাশবোর্ড তৈরি করুন (Create a Dashboard)

একবার ডেটা আসা শুরু হলে, একটি ড্যাশবোর্ড বানান। আপনি নিচের ড্যাশবোর্ড কপি করতে পারেন আপনার প্রয়োজনের জন্য:


Add dashboard এ ক্লিক করুন এবং তারপর মডাল ডায়লগে যেটি আসে সেখানে Import dashboard এ ক্লিক করুন। ড্যাশবোর্ড আপনাকে এমন গ্রাফ দেবে:

ডাটাবেস বৃদ্ধি নিয়ন্ত্রণ: টেবিল আকার ছোট রাখার কৌশল এবং ডেটা ব্লোট এড়িয়ে চলুন

এবং এই টেবিল সাইজ গ্রাফ:

ডাটাবেস বৃদ্ধি নিয়ন্ত্রণ: টেবিল আকার ছোট রাখার কৌশল এবং ডেটা ব্লোট এড়িয়ে চলুন

দ্রষ্টব্য: কীভাবে আমরা ওয়াইল্ডকার্ড ট্যাগস ব্যবহার করি অটোমেটিক্যালি ডাটাবেসের প্রতিটি টেবিলের জন্য গ্রাফ বানাতে।

ডেটা ইন্টারপ্রেট করা (Interpreting the Data)

আপনার ডেটা তাকানোর সময়, এক্সপোনেনশিয়াল (exponential) বা লিনিয়ার (linear) গ্রোথ খুঁজুন রো কাউন্ট বা সাইজে — অন্য কথায়, একটি টেবিল বড় বড় হয়ে যাচ্ছে।

আপনি যদি এটা দেখেন, আপনার কয়েকটি অপশন আছে। একটি হল এই আনবাউন্ডেড গ্রোথের জন্য আর্কিটেক্ট করা — জানা কবে আপগ্রেড করতে হবে, এবং কি আপনি নেক্সট বেস্ট সাইজে আপগ্রেড করতে পারেন। আরেকটি হল একটি রেগুলার ডিলিশন টাস্ক (deletion task) সেটআপ করা — আমার সাবেক সহকর্মী Ван্ডার হিলেন (Wander Hillen) এ টপিকের ওপর একটি চমৎকার আর্টিকেল লিখেছেন।

উদাহরণস্বরূপ, উপরের স্ক্রিনশটে, কিছু টেবিল নিয়মিত সঙ্কুচিত হয় — এটি হল যখন রেগুলার ক্লিনআপ টাস্কগুলো চলে। আপনি দেখতে পাচ্ছেন ডেটা এক নির্দিষ্ট পয়েন্ট পর্যন্ত জমা হয়, কিন্তু যেহেতু রো-এর ইনগ্রেস (ingress) আচ্ছাদকভাবে কনস্ট্যান্ট, সাইজ এবং রো কাউন্ট ড্রপ (drop) করে।

যতক্ষণ এই ড্রপগুলো থাকে এবং আপনার টেবিলগুলোর ডেটা মাত্রা একটি স্থির হারেই বৃদ্ধি পায়, আপনার ডাটাবেস আপনাকে হঠাৎ লিমিট বাস্ট (limit bust) দিয়ে চমকে দেবে না।

সমাপন: ডাটাবেস টেবিল থেকে ডেটা ব্লোট এড়িয়ে চলুন

এই পোস্টে, আমরা দেখেছি কীভাবে আপনি আপনার ডাটাবেসের বৃদ্ধির ওপর দৃষ্টি রাখতে পারেন এবং আপনার ডেটা ব্লোট কন্ট্রোলে রাখতে পারেন।

ডেটা ব্লোট বাজারে সফল হওয়া অ্যাপ্লিকেশনগুলোর জন্য একটি রিয়েল রিস্ক (real risk)। আপনার ডাটাবেস টেবিলসের জন্য মেট্রিক্স সেটআপ করে, আপনি ভালোভাবে অনুমান করতে পারেন কবে আপনার ডাটাবেস ভের্টিক্যালি স্কেল করতে হবে এবং কি আপনাকে রেগুলার স্টেল (stale) ডেটা ক্লিনআপ ইনস্টল করতে হবে। AppSignal গেজ (gauges) ট্যাগসহ, কিছু SQL-এর সাথে মিলিয়ে, আপনাকে এই ডেটা সুবিধাজনক এবং সুন্দর ফরম্যাটে দিতে পারে।

আপনার ডাটাবেস আপনাকে চমকাতে দিন না!

ডাটাবেস বৃদ্ধি নিয়ন্ত্রণ: টেবিল আকার ছোট রাখার কৌশল এবং ডেটা ব্লোট এড়িয়ে চলুন

জুলিক তারখানভ (Julik Tarkhanov)

অতিথি লেখক জুলিক তারখানভ চেডার পেমেন্টস (Cheddar Payments)-এ স্টাফ সফটওয়্যার ইঞ্জিনিয়ার এবং একাধিক রুবি ওপেন-সোর্স লাইব্রেরির লেখক।

জুলিক তারখানভ-এর সব আর্টিকেল


  1. Android-এ SD কার্ডে ফোল্ডার/ফাইলে লিখার অনুমতি সেট করার পদ্ধতি

  2. শীর্ষ প্রকল্পগুলির মাধ্যমে SQL শিখুন: দক্ষতা বাড়ান এবং একটি প্রভাবশালী পোর্টফোলিও তৈরি করুন

  3. L = {a(2m)c(4n)dn bm | m,n = 0} ভাষার জন্য পুশডাউন অটোমেটা নির্মাণ C++-এ

  4. জাভাতে JComboBox-এ আইটেমগুলো সর্ট করা