شاردینگ و تکثیر پایگاه داده
شاردینگ و تکثیر پایگاه داده
1) چرا شما به آن نیاز دارید
هنگامی که ارتقاء عمودی پایگاه داده در برابر CPU/IO/RAM یا یک خوشه تبدیل به SPOF می شود، تکرار (برای خواندن/HA) و sharding (برای نوشتن/توزیع داده) می آید. اهداف:- توان (نوشتن رشد افقی QPS).
- در دسترس بودن (شکست سریع، هیچ نقطه ای از شکست).
- محلی سازی داده ها (چند منطقه، تاخیر کم).
- جداسازی همسایگان پر سر و صدا (مستاجران داغ/کلید های داغ).
2) شرایط اساسی و مدل های سازگاری
اصلی/رهبر ↔ کپی/پیرو: نوشتن در رهبر، خواندن در کپی.
تکرار همزمان: تایید تراکنش پس از نوشتن بر روی N گره (RPO کم، تاخیر بالاتر).
Asynchronous: رهبر مرتکب می شود و بعدا وارد سیستم می شود (RPO> 0، تاخیر کم).
Quorum (Raft/Paxos): نوشتن به اکثر گره ها ؛ يه گزارش، رهبر اتوماتيک.
خواندن پس از نوشتن: تضمین خواندن سوابق آن (نگاه کنید به § 5).
ما CAP را در فروش به این صورت می خوانیم: در صورت بروز مشکلات شبکه، شما سازگاری (CP) یا در دسترس بودن (AP) را برای عملیات بحرانی انتخاب می کنید، اغلب سطوح را در مسیرهای مختلف ترکیب می کنید.
3) تکرار: گزینه ها و شیوه ها
3. ۱ فیزیکی و منطقی
فیزیکی (WAL/redo/binlog): نزدیک به ورود به سیستم بلوک، ساده و سریع ؛ محدود به توپولوژی همگن/نسخه.
منطقی: جریان DML/DDL در سطح ردیف/جدول ؛ اجازه می دهد تا کپی جزئی، مهاجرت متقابل نسخه، CDC برای DWH/جریان.
3. ۲ راه اندازی و مدیریت
تاخیر مانیتور (زمان/بایت/LSN).
محدود کردن بازخورد گرم آماده به کار و درخواست های طولانی در کپی (به طوری که برای جلوگیری از VACUUM/تمیز کردن).
برای MySQL - GTID و ارکستر ؛ для PostgreSQL - اسلات Patroni/تکرار، synchronous_standby_names.
sql
-- на лидере
ALTER SYSTEM SET synchronous_commit = 'on';
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 1 (standby_a, standby_b)';
SELECT pg_reload_conf();
GTID MySQL (شناسه معامله):
sql
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = ON; -- перезапуск
CHANGE MASTER TO MASTER_AUTO_POSITION=1;
3. 3 توپولوژی ها
1 → N (رهبر → ماکت) + آبشار (ماکت ادغام بیشتر).
چند اصلی (فعال فعال) - در OLTP بدون مدیریت درگیری شدید اجتناب کنید.
خوشه Quorum (قایق) - افزودنی های سوسک/یوگا/PG-Raft.
4) خواندن/نوشتن تقسیم و مسیریابی
همیشه به عنوان یک رهبر بنویسید. از نشانه ها بخوانید، اما تاخیر را در نظر بگیرید.
استراتژی های خواندن پس از نوشتن:1. چسبندگی جلسه: پس از ضبط موفقیت آمیز، مشتری در طول «Δ T» از رهبر می خواند.
2. دروازه LSN/GTID: مشتری می گوید «من نمی خواهم قدیمی تر LSN = X»، روتر به ماکت می فرستد، که LSN ≥ X.
3. Stale-ok: برخی از queries اجازه می دهد داده های قدیمی (دایرکتوری ها/نوار ها).
ابزار: PgBouncer/Pgpool-II (Postgres)، ProxySQL/MaxScale (MySQL)، Vitess (مسیریابی shard).
نمونه ای از دروازه LSN (ایده): 'pg _ current _ wal _ lsn ()' را در هدر/کوکی HTTP ذخیره کنید و از روتر بخواهید با 'pg _ last _ wal _ replay _ lsn () ≥ LSN' ماکت کند.
5) استراتژی های شاردینگ
5. 1 انتخاب کلید
کلید باید یکنواختی و محل درخواست را تضمین کند:- هش توسط 'tenant _ id '/' user _ id' - به طور مساوی، اما اسکن محدوده را محروم می کند.
- محدوده زمانی/شناسه - عالی برای سری زمان/آرشیو، اما خطر hot-shard.
- هش کردن مداوم - اضافه کردن/حذف قطعات را آسان می کند.
- دایرکتوری/جدول جستجو - انعطاف پذیر (هر الگوریتم)، اما یک جدول/کش دیگر.
5. 2 الگو
Shared-nothing: هر shard یک پایگاه داده/خوشه جداگانه است، برنامه مسیریابی را می داند.
Middleware-sharding: Vitess (MySQL)، Citus (Postgres)، توپولوژی پنهان در سطح پروکسی.
فدراسیون: جداسازی دامنه های داده توسط خدمات (کاتالوگ، پرداخت، auth).
5. 3 کلید کامپوزیت
از فضای کلید استفاده کنید: «{tenant}: {entity}: {id}» و آن را در برنامه و حافظه پنهان ذخیره کنید. Для Postgres - پارتیشن هش + زیرمجموعه LIST/RANGE.
پارتیشن بندی PostgreSQL (قطعه):sql
CREATE TABLE orders (
tenant_id int,
id bigint,
created_at timestamptz,
...,
PRIMARY KEY (tenant_id, id)
) PARTITION BY HASH (tenant_id);
CREATE TABLE orders_t0 PARTITION OF orders FOR VALUES WITH (MODULUS 16, REMAINDER 0);
--... t1..t15
6) تولید شناسه
اجتناب از «داغ» افزایش خودکار یکنواخت در sharding.
از شناسه 64 بیتی Snowflake مانند (زمان + منطقه + shard + seq) یا ULID/KSUID (یکنواختی و توزیع) استفاده کنید.
Для Postgres - دنباله در هر شارد ؛ برای MySQL - auto_increment_increment/offset (آفست های مختلف در رهبران shard).
7) اشتراک گذاری آنلاین و مهاجرت
اصول کلیدی: نوشتن دوگانه، idempotency، مسیریابی دو موقت.
مراحل (عمومی):1. یک shard/cluster جدید اضافه کنید.
2. فعال کردن خواندن دوگانه (بررسی سازگاری).
3. شامل دو نوشتن (در هر دو بخش)، اختلاف رکورد.
4. داده های تاریخی Backfill (دسته، منطقی/تکرار CDC).
5. تغییر «منبع حقیقت» به یک شارد جدید ؛ ترک «دم» هماهنگ سازی.
6. قدیمی را حذف کنید.
ابزار: Vitess Resharding، Citus shards، pg_logical/pgoutput، Debezium (CDC)، gh-ost/pt-online-schema-change (DDL بدون قفل).
8) چند منطقه و جغرافیایی توزیع
رهبر پیرو در هر منطقه: خواندن محلی، نوشتن - از طریق رهبر جهانی (مدل ساده، اما RTT متقابل منطقه).
چند رهبر: ضبط در هر دو منطقه - شما نیاز به درگیری (زمان بندی/نسخه/CRDT).
(True distributed SQL (Raft: CockroachDB/Yugabyte - داده ها به منطقه «چسبانده می شوند»، پرس و جو ها به حد نصاب محلی می روند.
- پول/سفارشات - CP (حد نصاب/رهبر)، دایرکتوری ها/نوار - AP (کش، نهایی).
- همیشه نوشتن شمشیربازی (کلید منحصر به فرد/نسخه) را با یک تقسیم مغز ممکن برنامه ریزی کنید.
9) ثبات در عمل
دفعات بازدید: خود را می نویسد: رهبر و یا نشانه که «گرفتار» با LSN/GTID.
مونوتونیک می خواند: «هیچ قدیمی تر» از آخرین LSN خوانده شده است.
کنترل Write-conflict: "انتخاب کنید... برای UPDATE '، نسخه (' xmin '/' rowversion ')، UPSERT با بررسی نسخه.
Idempotence: کلیدهای idemotence در پرداخت/رویدادها.
10) قابلیت مشاهده، SLO و هشدارها
تاخیر ماکت: زمان (ثانیه)، فاصله LSN (بایت)، seconds_behind_master (MySQL).
rollbacks مجبور/درگیری، خطاهای تکرار.
مسیر по تاخیر p95/p99 (خواندن رهبر در مقابل ماکت، نوشتن).
توان عملیاتی: TPS/قفل/ردیف جداول contended.
Bloat/Vacuum (PG)، نسبت ضربه بافر InnoDB (MySQL).
داشبورد: بار در هر شارد، قطعات «داغ»، توزیع کلید.
11) پشتیبان گیری، PITR و DR
پشتیبان گیری کامل + WAL/binlog برای PITR (بازیابی نقطه در زمان).
ذخیره در یک منطقه/ابر دیگر، انجام آزمون بازگرداندن به طور منظم.
برای قطعات، یک «برش» سازگار (هماهنگی زمان/LSN) یا idemotence کاربردی در بازیابی.
RPO ها/RTO ها در روزهای بازی نوشته و آزمایش می شوند.
bash pg_basebackup -D /backups/base -X stream -C -S slot_replica_1 архивация WAL через archive_command или pgBackRest/Barman
12) امنیت و دسترسی
تقسیم بندی توسط VPC/ACL، mTLS توسط پروکسی.
نقش ها/کمک های مالی بر اساس اصل حداقل حقوق ؛ کاربران فردی در هر شارد/نقش.
حسابرسی DDL/DCL، محدودیت در درخواست های «سنگین» در کپی.
رمزگذاری در حالت استراحت (KMS) و در حمل و نقل (TLS).
دکمه وحشت: جهانی «فقط بخوانید» برای مدت زمان حادثه/تحقیقات.
13) ابزار و آجر
PostgreSQL: Patroni (HA), PgBouncer (pooling/RO-routing), repmgr, pgBackRest/Barman (бэкап), Citus (шардинг), pglogical/Logical Replication, pgbadger/pg_stat_statements.
MySQL: Orchestrator (توپولوژی/خودکار شکست)، ProxySQL/MaxScale (مسیریابی)، Percona XtraBackup (پشتیبان گیری)، Group Replication/InnoDB Cluster، Vitess (sharding/resharding).
توزیع SQL: سوسک، YugabyteDB (حد نصاب، ساخته شده در sharding/موقعیت جغرافیایی).
CDC: Debezium + Kafka/Pulsar برای رویدادها/ETL.
14) ضد الگوهای
تک اولیه بدون شکست خودکار و بدون آزمایش DR.
«سحر و جادو» خواندن تقسیم به استثنای تاخیر → خطاهای فانتوم/اشکالات مشکوک.
شاردینگ «به خاطر شاردینگ»: عوارض زودرس به جای مقیاس عمودی/شاخص/کش.
محدوده داغ (محدوده زمانی) بدون زمان سطل/هش نمک → یک شارد ذوب می شود.
معامله جهانی 2PC در بالای ده ها تن از قطعات در OLTP - دم P99 بالا و قفل مکرر.
فقدان dual-write/dual-read در طول مهاجرت → از دست دادن/عدم همگام سازی.
DDL در تولید بدون ابزار آنلاین و بدون پرچم ویژگی های سازگاری.
15) چک لیست پیاده سازی (0-60 روز)
0-15 روز
تعریف DB SLO، RPO/RTO.
فعال کردن تکرار، نظارت بر تاخیر، پشتیبان گیری اساسی + PITR.
روتر (PgBouncer/ProxySQL) و سیاست خواندن پس از نوشتن را وارد کنید.
16-30 روز
یک استراتژی sharding را انتخاب کنید، کلید ها و طرح ها را توصیف کنید.
ابزارهای بیش از حد شارژ (Vitess/Citus/CDC) را آماده کنید.
دایرکتوری خدمات/جداول مشخص شده «read-stale-ok» در مقابل «سخت».
31-60 روز
pilot-shard، dual-read و backfill را اجرا کنید.
روز بازی: رهبر شکست خورده، بازیابی از PITR، سوئیچ منطقه.
خودکار گزارش کلید شارد داغ و ناهمواری.
16) معیارهای بلوغ
تکرار تاخیر p95 <هدف (به عنوان مثال 500 میلی ثانیه) برای خواندن انتقادی.
آزمایش های موفقیت آمیز DR ≥ 1/سه ماهه (بازگرداندن ≤ RTO، از دست دادن ≤ RPO).
توزیع بار توسط قطعات: عدم تعادل <20٪ توسط QPS/ذخیره سازی.
درصد درخواست هایی که به درستی مسیریابی شده اند = 100%
صفر از دست دادن داده ها در حوادث نیاز به تضمین CP (پول/سفارشات).
DDL آنلاین/مهاجرت بدون خرابی، با پرچم سازگاری.
17) نمونه دستور العمل
Hash-salt برای محدوده زمانی (به طوری که یک شارد را گرم نکنید):sql
-- вычисляйте bucket = hash(user_id) % 16, храните (bucket, created_at)
PARTITION BY LIST (bucket) SUBPARTITION BY RANGE (created_at)
میانافزار Read-my-writes) pseudocode):
python lsn = db.leader_query("SELECT pg_current_wal_lsn()")
ctx.sticky_until = now()+5s ctx.min_lsn = lsn в роутере чтений: выбираем реплику с last_lsn >= ctx.min_lsn, иначе лидер
Vitess VSchema (قطعه):
json
{
"tables": {
"orders": { "column_vindexes": [{ "column": "tenant_id", "name": "hash" }] }
}
}
18) نتیجه گیری
Sharding و replication نه تنها یک تکنیک هستند، بلکه فرایندها را نیز شامل می شوند: مسیریابی آگاه از سازگاری، رشته مهاجرت (نوشتن/خواندن دوگانه، backfill)، آزمون های منظم DR و قابلیت مشاهده تاخیر/hot shard. با یک ماکت ساده + read-after-write شروع کنید، سپس sharding را در جایی که مشخصات بار واقعاً به آن نیاز دارد اضافه کنید. استفاده از سیستم عامل های آماده (Vitess/Citus/Distributed SQL) و نگه داشتن داده های حیاتی کسب و کار در حالت CP - به این ترتیب پایه متوقف خواهد شد یک تنگنا و تبدیل شدن به یک پایه قابل پیش بینی و الاستیک از پلت فرم.