
النسخ المتماثل لقاعدة البيانات هو عملية نسخ بيانات قاعدة البيانات والحفاظ عليها عبر خوادم متعددة. إنه أساس التوفر العالي (HA)، والتعافي من الكوارث (DR)، وقياس القراءة، والتوزيع الجغرافي.
النسخ المتماثل لقاعدة البيانات هو عملية نسخ بيانات قاعدة البيانات والحفاظ عليها عبر خوادم متعددة. إنه أساس التوفر العالي (HA)، والتعافي من الكوارث (DR)، وقياس القراءة، والتوزيع الجغرافي.
لا توجد قاعدة بيانات "معملة دائمًا" حقًا - فشل الأجهزة، وتقسيم الشبكات، وتعطل البرامج. يضمن النسخ المتماثل أنه عند فشل مثيل قاعدة بيانات، يمكن لمثيل آخر أن يتولى المهمة بأقل وقت توقف أو بدونه.
| الهدف | الوصف | نهج النسخ المتماثل |
|---|---|---|
| توفر عالي | يظل النظام متاحًا بعد الفشل | تجاوز الفشل التلقائي للنسخ المتماثل |
| ** التعافي من الكوارث ** | البقاء على قيد الحياة انقطاع التيار الكهربائي على مستوى المنطقة | النسخ المتماثلة الجغرافية الزائدة عن الحاجة |
| ** قراءة القياس ** | التعامل مع المزيد من استعلامات القراءة | توزيع القراءات على النسخ المتماثلة |
| ** النسخ الاحتياطي ** | نقطة في الوقت المناسب الانتعاش دون تحميل | نسخة طبق الأصل تستخدم للنسخ الاحتياطية |
| ** التوزيع الجغرافي ** | الكمون المنخفض للمستخدمين العالميين | النسخ المتماثلة المحلية في كل منطقة |
| الصيانة | ترقيات التوقف صفر | فشل أثناء الصيانة |
┌──────────────────┐
│ Master Node │
│ (reads + writes)│
└────────┬─────────┘
│ write-ahead log (WAL)
│
┌───────────────────┼───────────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│Replica 1│ │Replica 2│ │Replica 3│
│(read │ │(read │ │(read │
│ only) │ │ only) │ │ only) │
└─────────┘ └─────────┘ └─────────┘
الايجابيات:
سلبيات:
-- PostgreSQL streaming replication setup
-- Primary: postgresql.conf
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1024 -- MB
-- Replica: postgresql.conf
primary_conninfo = 'host=primary.example.com port=5432 user=replicator'
-- Create replication slot on primary
SELECT pg_create_physical_replication_slot('replica_1');
┌──────────────┐ ┌──────────────┐
│ Leader A │◄───────────►│ Leader B │
│ (US-East) │ sync WAL │ (EU-West) │
└──────┬───────┘ └──────┬───────┘
│ │
┌────▼────┐ ┌────▼────┐
│Replica A│ │Replica B│
└─────────┘ └─────────┘
الايجابيات:
سلبيات:
# Multi-leader with conflict resolution (CouchDB, PostgreSQL BDR)
conflict_resolution:
strategy: "last_writer_wins" # Default — may lose data
# or: "application_merge" # Application handles conflicts
# or: "crdt" # Automatic conflict-free merging
Client ──► Write to all 3 nodes (W=2, R=2)
┌────────┐ ┌────────┐ ┌────────┐
│ Node 1 │ │ Node 2 │ │ Node 3 │
└────────┘ └────────┘ └────────┘
│ │ │
└─────────────┼─────────────┘
│
Client ◄────── Read from 2 nodes, compare versions (R=2)
نموذج أمازون DynamoDB/كاساندرا:
الايجابيات:
سلبيات:
| الجانب | متزامن | غير متزامن |
|---|---|---|
| ** فقدان البيانات عند تجاوز الفشل ** | صفر (RPO = 0) | فقدان بعض البيانات (RPO > 0) |
| اكتب الكمون | أعلى (انتظر النسخة المتماثلة ACK) | أقل (الاعتراف على الفور) |
| ** اتساق القراءة بعد الكتابة ** | مضمون | ربما قديمة يقرأ من النسخة المتماثلة |
| ** متطلبات الشبكة ** | الكمون المنخفض، موثوقة | يتحمل الكمون العالي |
| تأثير النسخ | يكتب كتل فشل النسخة المتماثلة | فشل النسخة المتماثلة ليس له أي تأثير |
-- PostgreSQL: synchronous replication
-- primary.conf
synchronous_standby_names = 'FIRST 1 (replica_1, replica_2)'
-- Now every write waits for at least one synchronous replica
-- Acknowledgment before returning COMMIT to client
# PostgreSQL manual failover
# On replica:
pg_ctl promote -D /var/lib/postgresql/data
# Update application connection string
# point at new primary
وقت التوقف عن العمل: من دقائق إلى ساعات (زمن الاستجابة البشرية).
# Patroni — PostgreSQL HA
scope: production
namespace: /db/
consul:
host: consul.example.com:8500
postgresql:
use_pg_rewind: true
parameters:
max_connections: 200
# On primary failure:
# 1. Patroni detects primary is down
# 2. Promotes most up-to-date replica
# 3. Updates Consul with new primary address
# 4. All clients automatically reconnect
| أداة | قاعدة البيانات | آلية | وقت تجاوز الفشل |
|---|---|---|---|
| ** باتروني ** | PostgreSQL | القنصل/etcd + REST API | 10-30 ثانية |
| المنسق | ماي إس كيو إل | على أساس الطوافة | 5-15 ثانية |
| ** ريديس الحارس ** | ريديس | بروتوكول القيل والقال | 10-30 ثانية |
| ** مجموعة النسخ المتماثلة MongoDB ** | MongoDB | الانتخابات الداخلية | <10 ثانية |
| ** مشغل Kubernetes ** | مختلف | K8s-native | يعتمد على التحقيق |
# Keepalived — Virtual IP failover
vrrp_instance VI_1 {
interface eth0
state BACKUP
virtual_router_id 51
priority 100
advert_int 1
virtual_ipaddress {
10.0.0.100/24 # Floating IP
}
track_script {
chk_postgres
}
}
| السبب | الوصف | التخفيف |
|---|---|---|
| كمون الشبكة | المسافة بين العقد | تحديد موقع أو استخدام تحسين WAN |
| المعاملات الكبيرة | بطيء في التطبيق على النسخة المتماثلة | اقتحام المعاملات الصغيرة |
| ** تشبع وحدة المعالجة المركزية ** | النسخة المتماثلة لا يمكن مواكبة | مقياس الأجهزة المتماثلة |
| ** استعلامات طويلة الأمد ** | أقفال على النسخة المتماثلة | قم بتعيين البيان_timeout |
| عمليات DDL | يغير المخطط جداول القفل | استخدم DDL المتزامن |
-- PostgreSQL lag monitoring
SELECT application_name,
pg_size_pretty(pg_wal_lsn_diff(
pg_current_wal_lsn(), replay_lsn
)) as lag_bytes,
ROUND(EXTRACT(EPOCH FROM NOW() - pg_last_xact_replay_timestamp()))
as lag_seconds
FROM pg_stat_replication;
-- Expected: < 1 second (async), < 10ms (sync)
# Application pattern: "read-your-writes" consistency
class ConsistentDBClient:
def __init__(self, master, replica):
self.master = master
self.replica = replica
def write(self, key, value):
# Write to master, record timestamp
result = self.master.execute("INSERT ...")
self._last_write_timestamp = time.time()
return result
def read(self, key):
# Read from replica, but verify freshness
data = self.replica.execute(f"SELECT * FROM ... WHERE id='{key}'")
# Check if we just wrote this record
stale_time = time.time() - self._last_write_timestamp
if stale_time < 1.0: # Within last second
# This is a recent write — read from master for consistency
if data is None:
data = self.master.execute(f"SELECT ... WHERE id='{key}'")
return data
| استراتيجية | RPO | RTO | التخزين | التكلفة |
|---|---|---|---|---|
| ** النسخ الاحتياطي الكامل اليومي ** | 24 ساعة | ساعات | عالية | منخفض |
| ** أرشفة وول ** | دقائق | متغير | متوسط | منخفض |
| ** أرشفة مستمرة ** | < 1 دقيقة | دقائق | عالية | متوسط |
| نسخة احتياطية | ثواني | سريع | عالية | متوسط |
| Multi-region replica | < 1 ثانية | الأسرع | عالية جدا | عالية |
# PostgreSQL continuous archiving
archive_mode = on
archive_command = 'pgbackrest --stanza=prod archive-push %p'
# Point-in-time recovery
pgbackrest --stanza=prod --type=time \
--target="2026-05-24 14:30:00+00" \
--target-action=promote restore
RPO: Recovery Point Objective (how much data can you lose)
RTO: Recovery Time Objective (how fast must you recover)
Tier 1 (Mission Critical): RPO < 1 minute, RTO < 5 minutes
Multi-region synchronous replication
Automatic failover
Regularly tested
Tier 2 (Business Critical): RPO < 1 hour, RTO < 30 minutes
Async replication to DR region
Semi-automated failover
Quarterly tests
Tier 3 (Standard): RPO < 24 hours, RTO < 4 hours
Daily backups + WAL archiving
Manual restore
Annual tests
import random
from itertools import cycle
class ReadLoadBalancer:
def __init__(self, replicas: list[str]):
self.replicas = cycle(replicas)
def get_reader(self) -> str:
return next(self.replicas)
def execute_query(self, query: str, is_read: bool = True):
if is_read:
conn = self.get_reader()
else:
conn = "master"
return execute_on(conn, query)
# PgBouncer or HAProxy configuration
# Routes reads to replicas, writes to master
listen pg_cluster
bind *:5432
mode tcp
acl is_write method POST
acl is_write query ^(INSERT|UPDATE|DELETE)
use_backend master if is_write
default_backend replicas
backend master
server pg-master 10.0.0.1:5432 check
backend replicas
server pg-replica1 10.0.0.2:5432 check
server pg-replica2 10.0.0.3:5432 check
server pg-replica3 10.0.0.4:5432 check
| ميزة | الوصف |
|---|---|
| ** تدفق النسخ المتماثل ** | تدفق WAL الفعلي إلى النسخ المتماثلة |
| النسخ المنطقي | النسخ المتماثل على مستوى الجدول (PostgreSQL 10+) |
| ** النسخ المتماثل ** | يمكن أن تخدم النسخة المتماثلة النسخ المتماثلة الأخرى |
| ** النسخ المتزامن ** | مزامنة قابلة للتكوين لكل معاملة |
| صفحة_ترجيع | إعادة المزامنة السريعة بعد انقسام الدماغ |
| ميزة | الوصف |
|---|---|
| ** النسخ المتماثل للمجموعة ** | متعددة الماجستير، وعضوية المجموعة المضمنة |
| ** مجموعة InnoDB ** | حل HA كامل مع MySQL Router |
| ** النسخ المتماثل شبه المتزامن ** | تعترف نسخة واحدة على الأقل |
| ** النسخ المتماثل المستند إلى GTID ** | معرفات المعاملات العالمية للسلامة |
| ميزة | الوصف |
|---|---|
| ** مجموعة النسخ ** | انتخاب تلقائي، يصل إلى 50 عضوا |
| اكتب القلق | مستوى الاعتراف شكلي |
| قراءة التفضيل | يقرأ الطريق إلى أقرب نسخة متماثلة |
| ** تغيير التدفقات ** | في الوقت الحقيقي CDC من oplog |
يحدث انقسام الدماغ عندما يتسبب قسم الشبكة في اعتقاد كلا العقدتين بأنهما العقدة الرئيسية:
Before partition:
Master A ◄──► Replica B
After partition:
Master A |X| Replica B (promoted to master)
(believes it |X| (believes it is master)
is master) |X|
When partition heals: two masters, inconsistent data
الوقاية:
يعد النسخ المتماثل لقاعدة البيانات أمرًا ضروريًا لأنظمة الإنتاج التي تتطلب التوفر والمتانة والأداء:
| مقياس | النهج |
|---|---|
| صغيرة (عقدة واحدة) | النسخ الاحتياطي اليومي إلى S3 |
| متوسط (من 1 إلى 10 ملايين مستخدم) | رئيسي واحد + 1-2 نسخ متماثلة، تجاوز الفشل تلقائيًا |
| كبير (10-100 مليون مستخدم) | متعدد القادة أو مجزأ وموزع جغرافيًا |
| عالمي (أكثر من 100 مليون مستخدم) | نشط متعدد المناطق، أو CRDTs أو فوز الكاتب الأخير |
المبادئ الأساسية:
لا يعد النسخ المتماثل ميزة الضبط والنسيان، بل يتطلب مراقبة واختبارًا وتحسينًا مستمرًا.
لا توجد تعليقات معتمدة بعد. قد تنتظر الردود الجديدة المراجعة.