استراتيجيات قياس قاعدة البيانات: قراءة النسخ المتماثلة والمشاركة وما بعدها
**يمثل أداء قاعدة البيانات عنق الزجاجة في 78% من مشكلات توسيع نطاق تطبيقات الويب. ** يمكن للتطبيقات التوسع أفقيًا بأقل جهد ممكن، لكن قواعد البيانات تقاوم التوسع الأفقي. تحدد الاستراتيجيات التي تختارها لقياس قاعدة البيانات ما إذا كان تطبيقك يخدم 100 مستخدم أو 100000 مستخدم بأداء مقبول.
يغطي هذا الدليل نطاقًا كاملاً من إستراتيجيات توسيع نطاق قاعدة البيانات، بدءًا من التحسينات البسيطة التي تؤخر الحاجة إلى التوسع وحتى التقنيات المتقدمة مثل التجزئة الأفقية.
الوجبات الرئيسية
- تحسين الاستعلامات وإضافة الفهارس قبل إضافة البنية الأساسية --- يؤدي هذا إلى حل 60% من مشكلات أداء قاعدة البيانات
- قراءة النسخ المتماثلة هي استراتيجية القياس الأقل خطورة وتتعامل مع 80% من أعباء العمل الثقيلة للقراءة
- يعد تجميع الاتصالات إلزاميًا بمجرد تشغيل التطبيق الخاص بك لأكثر من 10 حالات
- يعد التقسيم الأفقي هو الملاذ الأخير الذي يؤدي إلى تعقيد التطبيق بشكل كبير
سلم التدرج
مقياس بهذا الترتيب. كل خطوة أرخص وأقل خطورة من الخطوة التالية:
الخطوة 1: تحسين الاستعلام (مجانًا)
قبل إضافة البنية الأساسية، تأكد من أن قاعدة بياناتك الحالية تعمل على النحو الأمثل.
-- Find slow queries in PostgreSQL
SELECT
calls,
mean_exec_time::numeric(10,2) AS avg_ms,
total_exec_time::numeric(10,2) AS total_ms,
query
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 20;
التحسينات المشتركة:
- إضافة الفهارس المفقودة للأعمدة التي تتم تصفيتها بشكل متكرر
- استبدل
SELECT *بقوائم أعمدة محددة - استخدم
EXPLAIN ANALYZEلتحديد عمليات الفحص التسلسلية على الجداول الكبيرة - إضافة فهارس مركبة لجمل WHERE متعددة الأعمدة
- تنفيذ ترقيم الصفحات باستخدام ترقيم الصفحات لمجموعة المفاتيح بدلاً من
OFFSET
-- Bad: OFFSET pagination (scans all skipped rows)
SELECT * FROM orders ORDER BY created_at DESC LIMIT 20 OFFSET 10000;
-- Good: Keyset pagination (index-only scan)
SELECT * FROM orders
WHERE created_at < '2026-03-15T10:00:00Z'
ORDER BY created_at DESC
LIMIT 20;
الخطوة 2: القياس الرأسي ($)
قم بزيادة وحدة المعالجة المركزية وذاكرة الوصول العشوائي والتخزين على خادم قاعدة البيانات الحالي لديك. وهذا يشتري الوقت ولا يتطلب أي تغييرات في التطبيق.
| حجم المثيل | وحدة المعالجة المركزية الافتراضية | ذاكرة الوصول العشوائي | اتصالات | التكلفة الشهرية (RDS) |
|---|---|---|---|---|
| db.t3.medium | 2 | 4 جيجا | 100 | 65 دولارًا |
| db.r6g.large | 2 | 16 جيجا | 200 | 175 دولارًا |
| db.r6g.xlarge | 4 | 32 جيجا | 400 | 350 دولارًا |
| db.r6g.2xlarge | 8 | 64 جيجا | 800 | 700 دولار |
تصل معظم التطبيقات إلى الحد الأقصى عند 64 جيجابايت من ذاكرة الوصول العشوائي و8 وحدات معالجة مركزية افتراضية. أبعد من ذلك، يصبح التوسع الرأسي باهظ التكلفة.
الخطوة 3: تجميع الاتصالات ($)
Application (50 pods x 20 connections = 1,000 connections)
|
v
PgBouncer (25 database connections, transaction pooling)
|
v
PostgreSQL (25 active connections, manageable)
تكوين PgBouncer:
[databases]
app = host=db.example.com port=5432 dbname=production
[pgbouncer]
listen_port = 6432
listen_addr = 0.0.0.0
auth_type = md5
pool_mode = transaction
default_pool_size = 25
max_client_conn = 1000
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 3
الخطوة 4: قراءة النسخ المتماثلة ($$)
تتعامل النسخ المتماثلة المقروءة مع استعلامات SELECT، مما يؤدي إلى تفريغ 60-90% من تحميل قاعدة البيانات من الأساسي.
الهندسة المعمارية:
Write queries --> Primary database
|
Replication (async)
|
+----+----+
| |
Read queries --> Replica 1 Replica 2
** التوجيه على مستوى التطبيق ** (مثال Drizzle ORM):
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
const primaryPool = new Pool({ connectionString: process.env.DATABASE_URL });
const replicaPool = new Pool({ connectionString: process.env.DATABASE_REPLICA_URL });
export const primaryDb = drizzle(primaryPool);
export const replicaDb = drizzle(replicaPool);
// In service code:
// Write operations use primaryDb
async createOrder(data: OrderInput) {
return primaryDb.insert(orders).values(data).returning();
}
// Read operations use replicaDb
async getOrders(organizationId: string) {
return replicaDb.select().from(orders)
.where(eq(orders.organizationId, organizationId))
.orderBy(desc(orders.createdAt));
}
اعتبارات تأخر النسخ المتماثل: يؤدي النسخ المتماثل غير المتزامن إلى تأخير (عادةً من 10 إلى 100 مللي ثانية). مباشرة بعد الكتابة، قد تؤدي القراءة من النسخة المتماثلة إلى إرجاع بيانات قديمة. استخدم الأساسي للقراءات التي تتبع عمليات الكتابة في نفس تدفق المستخدم.
الخطوة 5: التخزين المؤقت ($$)
يؤدي التخزين المؤقت لـ Redis إلى التخلص من استعلامات قاعدة البيانات المتكررة تمامًا.
async getProduct(id: string): Promise<Product> {
const cacheKey = `product:${id}`;
// Check cache first
const cached = await this.redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// Cache miss: query database
const product = await this.db.select().from(products)
.where(eq(products.id, id))
.limit(1);
// Cache for 5 minutes
await this.redis.setex(cacheKey, 300, JSON.stringify(product[0]));
return product[0];
}
استراتيجية إبطال ذاكرة التخزين المؤقت: إبطال الكتابة. عندما يتم تحديث منتج، قم بحذف مفتاح ذاكرة التخزين المؤقت. استخدم نمط ذاكرة التخزين المؤقت جانبًا (يدير التطبيق ذاكرة التخزين المؤقت) بدلاً من الكتابة (تدير قاعدة البيانات ذاكرة التخزين المؤقت).
الخطوة 6: التقسيم الأفقي ($$$)
تقوم المشاركة بتوزيع البيانات عبر مثيلات قاعدة بيانات متعددة بناءً على مفتاح الجزء.
| استراتيجية المشاركة | الوصف | الأفضل لـ |
|---|---|---|
| على أساس التجزئة | قم بتجزئة مفتاح الجزء وتوزيعه بالتساوي | حتى توزيع البيانات |
| على أساس النطاق | تعيين النطاقات إلى الأجزاء (على سبيل المثال، A-M، N-Z) | السلاسل الزمنية والبيانات الجغرافية |
| على أساس المستأجر | جزء واحد لكل مستأجر/مؤسسة | SaaS متعدد المستأجرين |
متى التقسيم:
- قاعدة بيانات واحدة تتجاوز 1 تيرابايت ومتزايدة
- تتجاوز سرعة الكتابة ما يمكن أن يتعامل معه أساسي واحد
- تكاليف القياس الرأسي تتجاوز 2000 دولار شهريًا دون أي مساحة رأسية
متى لا تنقسم:
- لم تستنفد الخطوات من 1 إلى 5
- بياناتك تناسب قاعدة بيانات واحدة بسعة 500 جيجابايت
- الاستعلامات المتقاطعة شائعة في تطبيقك
تحسينات خاصة بـ PostgreSQL
التقسيم (قبل المشاركة)
يقوم تقسيم جدول PostgreSQL بتقسيم الجداول الكبيرة إلى جداول فعلية أصغر مع الحفاظ على جدول منطقي واحد:
-- Partition orders by month
CREATE TABLE orders (
id UUID PRIMARY KEY,
organization_id UUID NOT NULL,
created_at TIMESTAMP NOT NULL,
total DECIMAL(10,2)
) PARTITION BY RANGE (created_at);
CREATE TABLE orders_2026_01 PARTITION OF orders
FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
CREATE TABLE orders_2026_02 PARTITION OF orders
FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
CREATE TABLE orders_2026_03 PARTITION OF orders
FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');
يعمل التقسيم على تحسين أداء الاستعلام للاستعلامات ذات النطاق الزمني بمقدار 10-100x على الجداول الكبيرة لأن PostgreSQL يقوم فقط بفحص الأقسام ذات الصلة.
التنظيف والصيانة
-- Check table bloat
SELECT
schemaname,
relname,
n_live_tup,
n_dead_tup,
round(n_dead_tup::numeric / greatest(n_live_tup, 1) * 100, 2) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC;
قم بتكوين الفراغ التلقائي بقوة لجداول الكتابة العالية:
ALTER TABLE orders SET (
autovacuum_vacuum_threshold = 100,
autovacuum_vacuum_scale_factor = 0.05,
autovacuum_analyze_threshold = 50,
autovacuum_analyze_scale_factor = 0.02
);
مراقبة أداء قاعدة البيانات
تتبع هذه المقاييس لفهم متى وكيف يتم التوسع:
| متري | أداة | عتبة التنبيه |
|---|---|---|
| زمن الاستعلام (P95) | pg_stat_statements | >500 مللي ثانية |
| اتصالات نشطة | pg_stat_activity | > 80% من الحد الأقصى |
| نسبة إصابة ذاكرة التخزين المؤقت | pg_stat_database | <95% |
| تأخر النسخ المتماثل | pg_stat_replication | > ثانية واحدة |
| انتفاخ الجدول | pg_stat_user_tables | > 20% صفوف ميتة |
| إدخال/إخراج القرص انتظر | iostat / CloudWatch | >20 مللي ثانية |
تعد نسبة الوصول إلى ذاكرة التخزين المؤقت التي تقل عن 95% أقوى مؤشر على حاجتك إلى المزيد من الذاكرة. غالبًا ما تكون زيادة shared_buffers وeffective_cache_size أرخص وأسرع من إضافة النسخ المتماثلة المقروءة.
تتبع أداء الاستعلام
-- Enable pg_stat_statements (postgresql.conf)
-- shared_preload_libraries = 'pg_stat_statements'
-- Find the top 10 most time-consuming queries
SELECT
queryid,
calls,
mean_exec_time::numeric(10,2) AS avg_ms,
total_exec_time::numeric(10,2) AS total_ms,
rows,
query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
قم بمراجعة أهم 10 استفسارات أسبوعيًا. يمكن أن يؤدي تحسين استعلام واحد يتم تنفيذه بشكل متكرر إلى تقليل التحميل الإجمالي لقاعدة البيانات بنسبة 10-30%.
الأسئلة المتداولة
كيف نعرف متى يحين وقت التوسع؟
راقب ثلاثة مقاييس: زمن استجابة الاستعلام P95 (التنبيه عند 500 مللي ثانية)، واستخدام الاتصال (التنبيه عند 80%)، واستخدام وحدة المعالجة المركزية (التنبيه عند 70% مستدام). إذا كنت تصل إلى هذه العتبات بانتظام، فانتقل إلى الخطوة التالية على سلم القياس. لا تقم بالتحسين المسبق --- للقياس عندما تطلب منك البيانات ذلك.
قراءة النسخ المتماثلة أم التخزين المؤقت --- أيهما أول؟
ابدأ بالتخزين المؤقت. يعد التخزين المؤقت لـ Redis أسهل في التنفيذ، ويزيل المزيد من التحميل (تتخطى نتائج ذاكرة التخزين المؤقت قاعدة البيانات بالكامل)، وتكلف أقل. قم بإضافة نسخ متماثلة للقراءة عندما يكون معدل دخول ذاكرة التخزين المؤقت أعلى من 80% بالفعل ولكن قاعدة البيانات الأساسية لا تزال تحت ضغط من عمليات فقدان ذاكرة التخزين المؤقت وعمليات الكتابة.
كيف يعمل توسيع قاعدة البيانات مع Odoo؟
يستخدم Odoo PostgreSQL حصريًا. ابدأ بتحسين الاستعلام (يُنشئ Odoo استعلامات معقدة لإعداد التقارير). أضف PgBouncer لتجميع الاتصالات عندما تتجاوز 50 مستخدمًا متزامنًا. استخدم النسخ المتماثلة للقراءة لإعداد التقارير عن الاستعلامات (قم بتكوين خيار --db-replica الخاص بـ Odoo). يوفر ECOSIRE تحسين أداء Odoo بما في ذلك ضبط قاعدة البيانات.
هل تستحق قاعدة البيانات المُدارة (RDS/Cloud SQL) العلاوة؟
نعم، بالنسبة لمعظم الشركات. تتعامل قواعد البيانات المُدارة مع النسخ الاحتياطية التلقائية والتصحيح وتجاوز الفشل والمراقبة. يتم تعويض علاوة التكلفة بنسبة 30-40% مقارنة بـ PostgreSQL المُدارة ذاتيًا من خلال الوقت الهندسي الذي توفره. الاستثناء هو عمليات النشر واسعة النطاق حيث تتجاوز علاوة التكلفة على مثيل كبير تكلفة مسؤول قواعد البيانات بدوام جزئي.
ما يأتي بعد ذلك
يعد توسيع قاعدة البيانات أحد مكونات استراتيجية توسيع نطاق البنية التحتية الأوسع. ادمجها مع تحسين CDN للأصول الثابتة، والقياس التلقائي لـ Kubernetes لكبسولات التطبيقات، واختبار التحميل للتحقق من صحة قرارات القياس في ظل ظروف واقعية.
اتصل بـ ECOSIRE للحصول على استشارات بشأن تحسين قاعدة البيانات، أو راجع دليل DevOps للحصول على خريطة طريق البنية التحتية الكاملة.
تم النشر بواسطة ECOSIRE - مساعدة الشركات على توسيع نطاق البنية التحتية للبيانات بثقة.
بقلم
ECOSIRE Research and Development Team
بناء منتجات رقمية بمستوى المؤسسات في ECOSIRE. مشاركة رؤى حول تكاملات Odoo وأتمتة التجارة الإلكترونية وحلول الأعمال المدعومة بالذكاء الاصطناعي.
مقالات ذات صلة
أنماط بوابة API وأفضل الممارسات للتطبيقات الحديثة
قم بتنفيذ أنماط بوابة واجهة برمجة التطبيقات (API) بما في ذلك تحديد المعدل والمصادقة وتوجيه الطلب وقواطع الدائرة وإصدار واجهة برمجة التطبيقات (API) لبنيات الويب القابلة للتطوير.
تحسين أداء CDN: الدليل الكامل للتسليم العالمي الأسرع
قم بتحسين أداء CDN من خلال إستراتيجيات التخزين المؤقت وحوسبة الحافة وتحسين الصورة وبنيات CDN المتعددة لتوصيل المحتوى العالمي بشكل أسرع.
أفضل الممارسات لخط أنابيب CI/CD: أتمتة طريقك إلى عمليات نشر موثوقة
أنشئ خطوط أنابيب CI/CD موثوقة مع أفضل الممارسات للاختبار والتشغيل المرحلي وأتمتة النشر وإستراتيجيات التراجع والفحص الأمني في سير عمل الإنتاج.