تحجيم قاعدة البيانات: تجنب عنق الزجاجة
قاعدة البيانات هي دائمًا نقطة الفشل الوحيدة في القياس. استراتيجيات تحسين Postgres، وقراءة النسخ المتماثلة، والمشاركة.
الحلقة الأضعف في مونوليث
يمكنك توسيع نطاق خوادم الواجهة الأمامية الخاصة بك بشكل لا نهائي (فقط قم بإضافة المزيد من العقد خلف Load Balancer). يمكنك توسيع نطاق خوادم API الخاصة بك بشكل لا نهائي (وظائف بدون خادم). لا يمكنك توسيع نطاق قاعدة بياناتك الأساسية بسهولة. يوجد (عادة) مصدر واحد فقط للحقيقة. قرص واحد. عملية رئيسية واحدة. عندما ترتفع حركة البيانات، تصل وحدة المعالجة المركزية إلى 100%، ويتراوح زمن استجابة الاستعلام من 10 مللي ثانية إلى 10000 مللي ثانية. الموقع يموت. يعد توسيع نطاق قاعدة البيانات أصعب مشكلة في هندسة الواجهة الخلفية.
لماذا يناقش Maison Code هذا الأمر
في Maison Code، نرى الشركات الناشئة الصالحة تموت بسبب لغة SQL.
يكتبون رمزًا مثل SELECT * FROM Orders.
أنه يعمل بشكل جيد مع 100 أمر.
إنه يعطل الخادم بـ 1,000,000 طلب.
نقوم بتحسين قواعد البيانات من أجل الترابط العالي والإنتاجية العالية.
نحن نعلم أن “إضافة الفهارس” ليست كافية. أنت بحاجة إلى تغييرات في البنية (التخزين المؤقت، والنسخ المتماثل، والتقسيم).
الإستراتيجية 1: الفهرسة (الثمرة المنخفضة)
معظم مشاكل الأداء تفتقد الفهارس.
السيناريو: البحث عن مستخدم عبر البريد الإلكتروني.
الاستعلام: “حدد * من المستخدمين حيث البريد الإلكتروني = ‘alex@example.com”.
بدون فهرس: تقوم قاعدة البيانات بمسح 1,000,000 صف (مسح تسلسلي). على).
باستخدام الفهرس (B-Tree): تنتقل قاعدة البيانات مباشرةً إلى البريد الإلكتروني. يا (سجل ن).
التكلفة: تعمل الفهارس على إبطاء عمليات الكتابة (INSERT/UPDATE)، لأنه يجب تحديث شجرة الفهرس.
القاعدة: أعمدة الفهرس المستخدمة في WHERE وJOIN وORDER BY.
الإستراتيجية الثانية: التخزين المؤقت (Redis)
أسرع استعلام هو الذي لا تقوم به. SQL بطيء (الإدخال/الإخراج على القرص، وحسابات وحدة المعالجة المركزية). Redis سريع (في الذاكرة، قيمة المفتاح). النمط: نظرة جانبية على ذاكرة التخزين المؤقت.
دالة غير متزامنة getProduct(id) {
// 1. تحقق من ذاكرة التخزين المؤقت
const مخبأ = انتظار redis.get(`product:${id}`);
إذا تم إرجاع (نسخة مخبأة) JSON.parse(cached);
// 2. قاعدة بيانات الاستعلام (بطيئة)
منتج const = انتظار db.query('SELECT * FROM Products WHERE id = ?', [id]);
// 3. حفظ في ذاكرة التخزين المؤقت (TTL 5 دقائق)
انتظار redis.set(`product:${id}`, JSON.stringify(product), 'EX', 300);
عودة المنتج؛
}
يؤدي هذا إلى إلغاء تحميل 90% من حركة مرور القراءة من قاعدة البيانات.
الإستراتيجية 3: قراءة النسخ المتماثلة
حتى مع التخزين المؤقت، يمكن أن تطغى عمليات القراءة على وحدة المعالجة المركزية. الحل: إنشاء نسخ من قاعدة البيانات (النسخ المتماثلة).
- العقدة الأساسية: تعالج عمليات الكتابة (إدراج، تحديث، حذف). مزامنة التغييرات مع النسخ المتماثلة (غير متزامن).
- العقد المتماثلة: التعامل مع القراءات (SELECT). المقايضة: تأخر النسخ المتماثل. يقوم المستخدم بتحديث ملفه الشخصي. يقومون بتحديث الصفحة على الفور. لقد وصلوا إلى نسخة طبق الأصل لم تتلق التحديث بعد. يرون الملف الشخصي القديم. الإصلاح: “اقرأ كتاباتك الخاصة”. بالنسبة للمستخدم الحالي، فرض القراءة من الأساسي. بالنسبة للبيانات العامة، اقرأ من النسخة المتماثلة.
الإستراتيجية 4: تجميع الاتصالات (PgBouncer)
لدى Postgres حد للاتصالات المتزامنة (على سبيل المثال، الحفاظ على 100). تنتج الوظائف بدون خادم (Lambda) 1000 حالة. إذا حاولت 1000 حالة فتح اتصال، فسيتعطل Postgres. الحل: وكيل (PgBouncer / Supabase Pooler). يحتوي الوكيل على 100 اتصال مفتوح بقاعدة البيانات. يتحدث الـ 1000 Lambda إلى الوكيل. يقوم الوكيل بوضع الاستعلامات في قائمة الانتظار وتنفيذها باستخدام 100 اتصال. يعد هذا أمرًا إلزاميًا للبنيات التي لا تحتوي على خادم.
الإستراتيجية 5: التقسيم الرأسي (تقسيم الجداول)
يحتوي جدول “المستخدمون” على “السيرة الذاتية” (نص، كبير) و”آخر_تسجيل دخول” (التاريخ، صغير).
إذا كنت تستعلم بشكل متكرر عن “last_login”، ولكن “bio” يجعل حجم الصف ضخمًا، فإن قاعدة البيانات تقرأ الكثير من البيانات من القرص.
تقسيمها:
جدول “User_Core” (المعرف، البريد الإلكتروني، كلمة المرور، Last_login).
جدول ملف تعريف_المستخدم (المعرف، والسيرة الذاتية، والصورة الرمزية).
الآن أصبح SELECT last_login FROM User_Core سريعًا للغاية بسبب احتواء المزيد من الصفوف في صفحات ذاكرة الوصول العشوائي (RAM).
6. وجهات النظر المتحققة: حساب النجاح مسبقًا
“أرني إجمالي الإيرادات لعام 2024.”
اختر المبلغ (المبلغ) من الطلبات حيث السنة = 2024.
يقوم هذا بمسح 10 ملايين صف. يستغرق 5 ثواني.
الحل: عرض ملموس.
إنشاء عرض مادي للإيرادات السنوية حسب التحديد ...
يقوم Postgres بحساب النتيجة وحفظها على القرص كجدول فعلي.
الاستعلام يستغرق 1 مللي ثانية.
المقايضة: البيانات قديمة. يجب عليك “تحديث العرض المادي” بشكل دوري (على سبيل المثال، كل ساعة).
مثالي للوحات المعلومات حيث لا يكون “الوقت الفعلي” مطلوبًا بشكل صارم.
7. القياس التلقائي لقاعدة البيانات (Aurora بدون خادم)
ماذا لو كنت لا تريد إدارة النسخ المتماثلة؟ Amazon Aurora Serverless v2. فهو يضيف وحدة المعالجة المركزية/ذاكرة الوصول العشوائي تلقائيًا عند ارتفاع حركة المرور، ويتقلص عندما تنخفض حركة المرور. يتم قياسه بـ زيادات كسرية (وحدات ACU). إنه يمنحك بشكل فعال وعد “القياس اللانهائي” لـ NoSQL، ولكن مع التوافق الكامل مع SQL. إنه مكلف، ولكنه أرخص من الاستعانة بمسؤول قواعد البيانات (DBA) لتوفير النسخ المتماثلة للقراءة يدويًا في الساعة 3 صباحًا.
9. بيانات السلاسل الزمنية (TimescaleDB)
“تسجيل كل عرض للصفحة.”
“سجل كل قراءة لمقياس الحرارة.”
يخنق Postgres القياسي إدراج 10000 صف/ثانية في جدول واحد.
تصبح الفهارس مجزأة.
الحل: TimescaleDB (امتداد Postgres).
يقوم تلقائيًا بتقسيم البيانات حسب الوقت (“Hypertables”).
الطلبات_2024_01، الطلبات_2024_02.
يمكنك الاستعلام عنه كجدول واحد “أوامر”، ولكنه فعليًا عبارة عن قطع صغيرة.
يتم إسقاط البيانات القديمة بشكل فوري (DROP TABLEorders_2020). الحذف من الطلبات التي يكون العام = 2020 يستغرق ساعات.
10. استراتيجيات التقسيم المتقدمة
التقسيم العمودي يقسم الأعمدة.
** التقسيم الأفقي ** يقسم الصفوف.
حسب المنطقة: users_eu، users_us.
وهذا يساعد في اللائحة العامة لحماية البيانات (مقر البيانات).
“البيانات الأوروبية لا تترك خادم الاتحاد الأوروبي أبدًا.”
التقسيم التعريفي لـ Postgres يجعل هذا الأمر قابلاً للإدارة.
هذه هي الطريقة التي نقوم بها بتوسيع نطاق تطبيقات SaaS لملايين المستأجرين دون شراء حاسب مركزي.
11. وجهة نظر المتشكك
“فقط استخدم DynamoDB / NoSQL. إنه يتوسع بشكل لا نهائي.” نقطة مضادة: تقوم NoSQL بقياس عملية الكتابة، ولكنها تفشل في البيانات العلائقية. “أرني جميع الطلبات المقدمة من المستخدمين في باريس الذين اشتروا أحذية حمراء.” في SQL: استعلام واحد. في NoSQL: كابوس من عمليات الانضمام من جانب التطبيق وعمليات الجلب المتعددة. معظم بيانات التجارة الإلكترونية علائقية. التزم بـ SQL (Postgres) حتى تصل إلى مقياس Google.
الأسئلة الشائعة
س: متى تستخدم المشاركة؟ ج: ** تقريبًا أبدًا **. تعد المشاركة (تقسيم البيانات عبر خوادم متعددة بناءً على معرف المستخدم) أمرًا معقدًا للغاية. ستفقد معاملات ACID عبر الأجزاء. لا تقم بالتقسيم حتى يكون لديك أكثر من 10 تيرابايت من البيانات. يعمل القياس الرأسي (الخادم الأكبر) جيدًا بشكل مدهش حتى هذه النقطة.
س: ORM مقابل Raw SQL؟ ج: Prisma/Drizzle (ORM) لزيادة الإنتاجية. Raw SQL للتقارير المعقدة أو الاستعلامات فائقة التحسين. تعتبر ORMs الحديثة جيدة بما يكفي لـ 99% من الاستعلامات.
الخلاصة
قاعدة البيانات هي قلب المكدس الخاص بك. إذا توقف عن النبض، يموت التطبيق. التعامل معها باحترام. فهرسة المفاتيح الخارجية الخاصة بك. قم بتخزين المسارات الساخنة الخاصة بك. ولا تقم مطلقًا بتشغيل “DROP TABLE” يوم الجمعة.
اختناق قاعدة البيانات؟
إذا انتهت مهلة استعلاماتك أو كانت وحدة المعالجة المركزية لديك في وضع أحمر، فيمكن لـ Maison Code تحسين مخططك. نقوم بتحليل خطط الاستعلام، وتنفيذ إستراتيجيات التخزين المؤقت، وتصميم مجموعات النسخ المتماثلة.
اتصل بنا لتوسيع نطاق بياناتك.
الاستعلامات بطيئة جدًا؟
نقوم بتحسين بنية قاعدة البيانات باستخدام الفهرسة والتخزين المؤقت وقراءة النسخ المتماثلة للتعامل مع النطاق الهائل. قم بتعيين مهندسينا المعماريين.