Loading
Alireza Shokrani

Digital Architect

AI Solutions Engineer

Founder @ CoreBiz ERP

GenAI & RAG Specialist

Full-Stack Systems Developer

Alireza Shokrani

Digital Architect

AI Solutions Engineer

Founder @ CoreBiz ERP

GenAI & RAG Specialist

Full-Stack Systems Developer

Solution

بهینه‌سازی پایگاه داده پرهمزمانی: ایندکس‌گذاری پرس‌وجو، کش شیء Redis و تنظیم کرنل فراتر از افزونه‌ها

سپتامبر 11, 2026 مهندسی عملکرد
بهینه‌سازی پایگاه داده پرهمزمانی: ایندکس‌گذاری پرس‌وجو، کش شیء Redis و تنظیم کرنل فراتر از افزونه‌ها

پلتفرم‌های سازمانی به تأخیر زندگی می‌کنند یا می‌میرند. افزایش ۵۰ میلی‌ثانیه‌ای در زمان پاسخ، درآمد را هزینه می‌دهد. یک رگرسیون ۲۰۰ میلی‌ثانیه‌ای، کاربران را هزینه می‌دهد. در مقیاس، هر میلی‌ثانیه در هزاران تراکنش همزمان انباشته می‌شود.

اکثر تلاش‌های بهینه‌سازی در لایه افزونه متوقف می‌شوند: نصب کش شیء Redis، فعال‌سازی کش صفحه، تمام. این کار می‌کند — تا زمانی که نمی‌کند. وقتی ترافیک جهش می‌کند، وقتی پایگاه داده از یک میلیون سطر رشد می‌کند، وقتی اتصالات همزمان استخر اتصال را اشباع می‌کنند، لایه افزونه نمی‌تواند شما را نجات دهد.

این مقاله لایه‌های زیرین را بررسی می‌کند:

پلن‌های اجرای پرس‌وجو، Connection Pooling، توپولوژی‌های کش Redis، تنظیم FastCGI و بهینه‌سازی پارامترهای کرنل — دیسیپلین‌های مهندسی که پلتفرم‌هایی که ترافیک بالا را زنده می‌مانند از آن‌هایی که فرو می‌ریزند جدا می‌کنند.

هدف “سریع‌تر” نیست. هدف اجرای زیر-میلی‌ثانیه‌ای قابل پیش‌بینی تحت بار پایدار است — نوع عملکردی که یک کسب‌وکار می‌تواند روی آن ساخته شود.

بخش ۱ — استک بهینه‌سازی: عملکرد واقعاً کجا زندگی می‌کند

قبل از بهینه‌سازی هر چیزی، معماری باید صریح باشد. عملکرد پرهمزمانی یک مسئله لایه‌ای است:

┌─────────────────────────────────────────────────────────────────┐
│                    لایه ۷: اپلیکیشن                             │
│         (الگوهای پرس‌وجو، رفتار ORM، حذف N+1)                   │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۶: کش                                   │
│         (کش شیء Redis، کش صفحه، کش Fragment)                    │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۵: پایگاه داده                          │
│         (ایندکس‌ها، پلن‌های اجرا، طراحی اسکیما)                 │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۴: مدیریت اتصال                         │
│         (Pooling، اتصالات پایدار، چرخه عمر اتصال)               │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۳: وب‌سرور                              │
│         (کش FastCGI، ارائه دارایی استاتیک، مسیریابی)            │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۲: مدیریت فرآیند                        │
│         (کارگران PHP-FPM، تخصیص حافظه، بازیافت درخواست)         │
├─────────────────────────────────────────────────────────────────┤
│                    لایه ۱: کرنل                                 │
│         (بافر شبکه، توصیف‌گرهای فایل، زمان‌بند I/O)             │
└─────────────────────────────────────────────────────────────────┘

اصل مهندسی: بهینه‌سازی یک لایه بالاتر در حالی که یک لایه پایین‌تر اشباع شده، تلاش هدر رفته است. گلوگاه باید شناسایی شود — نه فرض.

بخش ۲ — ایندکس‌گذاری پرس‌وجو: پلن اجرا حقیقت است

قوی‌ترین اهرم بهینه‌سازی پلن اجرای پایگاه داده است. نه شهود. نه “بهترین شیوه‌ها”. پلن.

EXPLAIN ANALYZE: خواندن پلن

EXPLAIN ANALYZE در PostgreSQL پرس‌وجو را اجرا می‌کند و آمار اجرای واقعی را گزارش می‌دهد — نه تخمین:

EXPLAIN (ANALYZE, BUFFERS, TIMING, FORMAT TEXT)
SELECT o.id, o.total, c.name
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'pending'
  AND o.created_at > NOW() - INTERVAL '7 days';

آنچه باید جستجو شود:

سیگنالمعنااقدام
Seq Scan روی جدول بزرگاسکن کامل جدول — ایندکس گم‌شده یا استفاده نشدهایندکس مناسب اضافه کنید
سطرهای واقعی زیاد در برابر تخمینیآمار منقضی — Planner اشتباه هدایت شدهANALYZE را روی جدول اجرا کنید
Nested Loop با تعداد سطر بالااستراتژی Join اشتباه برای حجم دادهایندکس‌های Join را بررسی کنید
Buffers: read >> hitWorking Set در حافظه نیستافزایش shared_buffers را در نظر بگیرید
Sort Method: external mergeمرتب‌سازی به دیسک منتقل شدهایندکس اضافه کنید تا از Sort اجتناب شود

تأثیر واقعی: یک ایندکس گم‌شده روی یک ستون کلید خارجی می‌تواند یک پرس‌وجوی ۲ میلی‌ثانیه‌ای را به یک اسکن ۲ ثانیه‌ای تبدیل کند. در ۱۰۰ پرس‌وجو در هر بارگذاری صفحه، این تفاوت بین ۲۰۰ میلی‌ثانیه و ۲۰۰ ثانیه است.

طراحی ایندکس برای بارهای کاری پرهمزمانی

ایندکس‌ها رایگان نیستند. هر نوشتن هزینه هر ایندکس را می‌پردازد. دیسیپلین مهندسی ایندکس‌گذاری انتخابی است — پوشش پرس‌وجوهایی که مهم هستند، نادیده گرفتن بقیه.

الگوی پرس‌وجواستراتژی ایندکسسینتکس PostgreSQL
پرس‌وجوهای بازه‌ای (زمان، محدوده ID)B-tree ترکیبیCREATE INDEX ON orders (status, created_at DESC)
فیلتر وضعیتایندکس جزئیCREATE INDEX ON orders (id) WHERE status = 'pending'
جستجوهای نقطه‌ایUnique یا Primary KeyCREATE UNIQUE INDEX ON customers (email)
پرس‌وجوهای JSONBایندکس GINCREATE INDEX ON events USING GIN (payload)
جستجوی Full-TextGIN با tsvectorCREATE INDEX ON articles USING GIN (to_tsvector(...))

قانون حیاتی: اگر یک ستون کلید خارجی در WHERE، JOIN یا عملیات آبشاری استفاده می‌شود، آن را ایندکس کنید. PostgreSQL این کار را به صورت خودکار انجام نمی‌دهد.

پایش سلامت ایندکس

-- ایندکس‌های بدون استفاده (کاندیدهای حذف)
SELECT indexrelname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
WHERE idx_scan = 0
  AND indexrelname NOT LIKE '%_pkey';

-- اندازه ایندکس در برابر اندازه جدول
SELECT
  tablename,
  pg_size_pretty(pg_total_relation_size(tablename::regclass)) AS total_size,
  pg_size_pretty(pg_indexes_size(tablename::regclass)) AS index_size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(tablename::regclass) DESC;

دیسیپلین نگهداری: بهینه‌سازی ایندکس مداوم است. ایندکس‌های بدون استفاده سربار خالص نوشتن هستند. ایندکس‌های گم‌شده درد خالص خواندن هستند.

بخش ۳ — Connection Pooling: گلوگاه پنهان

PostgreSQL برای هر اتصال یک فرآیند Backend اختصاصی ایجاد می‌کند. در ۲۰۰ اتصال، این ۲۰۰ فرآیند است که حافظه و CPU مصرف می‌کنند.

مشکل انفجار اتصال

سنتی (بدون Pooling):
  کارگران PHP-FPM: ۲۰
  × اتصالات به ازای هر کارگر: ۲-۳
  = اتصالات پایدار: ۴۰-۶۰
  × حافظه به ازای هر اتصال: ~۱۰MB
  = ۴۰۰-۶۰۰MB فقط برای اتصالات

  در ۱۰۰ کارگر PHP-FPM: ۲۰۰-۳۰۰ اتصال → ۲-۳GB سربار
  PostgreSQL max_connections: ۲۰۰ (پیش‌فرض) → اتصال رد شد

PgBouncer: استخر اتصال مشترک

PgBouncer بین اپلیکیشن و PostgreSQL قرار می‌گیرد و یک استخر اتصال را بین تمام کارگران به اشتراک می‌گذارد:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ PHP-FPM     │     │             │     │             │
│ کارگر ۱     │────▶│             │     │             │
├─────────────┤     │   PgBouncer │     │  PostgreSQL │
│ PHP-FPM     │     │   (استخر)   │────▶│  (Backend   │
│ کارگر ۲     │────▶│             │     │   محدود)    │
├─────────────┤     │             │     │             │
│ PHP-FPM     │     │             │     │             │
│ کارگر N     │────▶│             │     │             │
└─────────────┘     └─────────────┘     └─────────────┘

اتصالات کارگر: ۶۰        Backendهای PostgreSQL: ۲۰
سربار حافظه: ۶۰۰MB       سربار حافظه: ۲۰۰MB

پیکربندی PgBouncer

# /etc/pgbouncer/pgbouncer.ini
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt

# Transaction Pooling: اتصال بعد از هر تراکنش برگردانده می‌شود
pool_mode = transaction

# اندازه استخر
max_client_conn = 500
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5
reserve_pool_timeout = 3

# سلامت اتصال
server_idle_timeout = 600
server_lifetime = 3600

تصمیم حالت استخر:

حالترفتارچه زمانی استفاده شود
Sessionاتصال برای کل نشست نگه داشته می‌شودتراکنش‌های طولانی، LISTEN/NOTIFY
Transactionاتصال بعد از هر تراکنش آزاد می‌شوداکثر اپلیکیشن‌های وب
Statementاتصال بعد از هر دستور آزاد می‌شودبه ندرت استفاده می‌شود، بدون تراکنش چند-دستوری

نکته مهندسی: LISTEN/NOTIFY (که توسط برخی ORMها برای ویژگی‌های Real-time استفاده می‌شود) نیازمند حالت Session یا اتصال مستقیم است. حالت Transaction آن را می‌شکند.

بخش ۴ — کش شیء Redis: توپولوژی‌ها و حالت‌های شکست

Redis به عنوان کش شیء WordPress به خوبی مستند شده است. آنچه کمتر بحث می‌شود توپولوژی است — نحوه استقرار Redis تعیین می‌کند که آیا پلتفرم را تسریع می‌کند یا بی‌ثبات.

توپولوژی ۱: نمونه Redis واحد (مشترک)

┌─────────────────────────────────────────────────────────────┐
│                    نمونه Redis واحد                         │
│                     (سیاست allkeys-lru)                     │
│  ┌───────────────────────────────────────────────────────┐  │
│  │ پیشوند کلید: site1:* │ site2:* │ ...                  │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

ویژگی‌ها:

  • مشترک بین تمام سایت‌های روی هاست

  • جداسازی دقیق پیشوند کلید به ازای هر سایت

  • Eviction allkeys-lru تحت فشار حافظه

  • نقطه شکست واحد — اما ایمن شکست می‌خورد (WordPress به کش هر-درخواست برمی‌گردد)

بهترین برای: میزبانی چند-مستأجری، محیط‌های مشترک.

توپولوژی ۲: Redis اختصاصی به ازای هر اپلیکیشن

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Redis ۱       │     │   Redis ۲       │     │   Redis N       │
│   (اپ A)        │     │   (اپ B)        │     │   (اپ N)        │
└─────────────────┘     └─────────────────┘     └─────────────────┘

ویژگی‌ها:

  • جداسازی کامل — بدون Eviction بین-اپلیکیشنی

  • تخصیص حافظه مستقل

  • سربار عملیاتی بالاتر

بهترین برای: اپلیکیشن‌های با ارزش بالا، زیرساخت اختصاصی.

توپولوژی ۳: Redis با Unix Socket

# پیکربندی استخر PHP-FPM
env[REDIS_SOCKET] = /run/redis/redis.sock

چرا این مهم است: Unix Socketها استک TCP/IP را کاملاً دور می‌زنند. برای اتصالات محلی Redis، این تأخیر را کاهش می‌دهد و فشار بافر شبکه را حذف می‌کند.

اصل Failsafe

کش هرگز نباید یک سایت را از کار بیندازد. رفتار صحیح تحت شکست Redis:

Redis غیرقابل دسترس → WordPress با کش هر-درخواست ادامه می‌دهد
                     → سایت کار می‌کند، فقط کندتر
                     → ادمین از وضعیت کش مطلع می‌شود
                     → بدون خطا، بدون توقف

اصل مهندسی: کشی که سخت شکست می‌خورد، بدتر از هیچ کشی است.

بخش ۵ — کش FastCGI Nginx: ارائه صفحات بدون PHP

برای ترافیک ناشناس — که اکثریت ترافیک در سایت‌های محتوایی است — سریع‌ترین درخواست PHP، درخواستی است که هرگز PHP را شروع نمی‌کند.

دلتای عملکرد

مسیر درخواستتأخیربار سرور
FastCGI HIT~۱msحداقلی — ارائه فایل استاتیک
FastCGI MISS~۸۰msاجرای کامل PHP + پایگاه داده

در ۱,۰۰۰ درخواست/دقیقه:

  • بدون کش: ۱,۰۰۰ × ۸۰ms = ۸۰ ثانیه زمان CPU PHP

  • با ۹۰٪ Hit کش: ۱۰۰ × ۸۰ms + ۹۰۰ × ۱ms = ۸.۹ ثانیه زمان CPU PHP

تأثیر مهندسی: کش FastCGI بار PHP را تا ۹۰٪ برای ترافیک ناشناس کاهش می‌دهد.

پیکربندی Nginx

http {
    # منطقه کش: ۲۵۶MB فضا، منطقه کلید ۱۰۰MB
    fastcgi_cache_path /var/cache/nginx/wordpress
        levels=1:2 keys_zone=wp_cache:100m
        max_size=256m inactive=60m use_temp_path=off;

    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_lock on;
    fastcgi_cache_lock_timeout 5s;
    fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503;
    fastcgi_cache_background_update on;
}

منطق Bypass کش

set $skip_cache 0;

# درخواست‌های POST را هرگز کش نکن
if ($request_method = POST) { set $skip_cache 1; }

# Query-Stringها را هرگز کش نکن (جستجو، صفحه‌بندی)
if ($query_string != "") { set $skip_cache 1; }

# کاربران احراز هویت شده یا صفحات سبد خرید را هرگز کش نکن
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash") {
    set $skip_cache 1;
}

# ادمین، ورود، API، سبد، تسویه را هرگز کش نکن
if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|/wp-json/|/cart/|/checkout/|/my-account/") {
    set $skip_cache 1;
}

تأیید

curl -I https://example.com/
# درخواست اول: X-FastCGI-Cache: MISS
# درخواست دوم: X-FastCGI-Cache: HIT

نکته مهندسی: دو بار کش نکنید. اگر کش FastCGI Nginx فعال است، کش صفحه سطح WordPress را غیرفعال کنید. لایه FastCGI سریع‌تر و نزدیک‌تر به کاربر است.

بخش ۶ — تنظیم PHP-FPM: کارگران، حافظه و OOM Killer

PHP-FPM مدیر فرآیندی است که PHP را اجرا می‌کند. پیکربندی اشتباه در اینجا شایع‌ترین علت توقف “تصادفی” تحت بار است.

تله pm.max_children

خیلی بالا: جهش ترافیک → کارگران بیشتری از RAM موجود Spawn می‌شود
          → OOM Killer کرنل کارگران را در میانه درخواست خاتمه می‌دهد
          → کاربران خطا می‌بینند

خیلی پایین: درخواست‌ها در صف می‌مانند در حالی که حافظه بیکار است
          → تأخیر بالا، توان عملیاتی ضعیف

فرمول اندازه‌گذاری

RAM موجود = RAM کل - (Nginx + Redis + سربار OS)
حداکثر کارگران = RAM موجود / RSS متوسط فرآیند PHP

مثال (VPS ۲GB):

RAM موجود = ۲۰۴۸MB - ۴۰۰MB (سربار) = ۱۶۴۸MB
RSS متوسط PHP = ~۸۰MB
حداکثر کارگران = ۱۶۴۸ / ۸۰ ≈ ۲۰

پیکربندی استخر PHP-FPM تولیدی

; /etc/php/8.4/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data

; Unix Socket (سریع‌تر از TCP برای اتصالات محلی)
listen = /run/php/php8.4-fpm.sock
listen.owner = www-data
listen.group = www-data

; مدیریت فرآیند پویا
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8

; بازیافت کارگران برای جلوگیری از نشت حافظه
pm.max_requests = 500

; گزارش درخواست‌های کند
slowlog = /var/log/php/www-slow.log
request_slowlog_timeout = 5s

; تنظیمات PHP برای پرهمزمانی
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 120
php_admin_flag[log_errors] = on

پارامترهای کلیدی:

پارامترهدفنکته تنظیم
pm.max_childrenحداکثر فرآیندهای همزمان PHPحیاتی‌ترین — به RAM اندازه دهید
pm.max_requestsبازیافت کارگران بعد از N درخواست۵۰۰-۱۰۰۰ از انباشت نشت حافظه جلوگیری می‌کند
request_slowlog_timeoutثبت درخواست‌های فراتر از آستانهبرای دید ۲-۵s تنظیم کنید
memory_limitحداکثر حافظه به ازای هر فرآیند PHP۲۵۶M برای WordPress، بیشتر برای افزونه‌های سنگین

بخش ۷ — تنظیم کرنل: لایه‌ای که همه فراموش می‌کنند

کرنل لینوکس پایه است. پارامترهای پیش‌فرض کرنل برای محاسبات عمومی بهینه شده‌اند، نه برای بارهای کاری پایگاه داده پرهمزمانی.

تنظیم استک شبکه

اپلیکیشن‌های پرهمزمانی اغلب محدود به شبکه هستند قبل از اینکه محدود به CPU باشند. بافرهای شبکه کرنل و صف‌های Backlog تعیین می‌کنند که چند اتصال می‌تواند به طور همزمان مدیریت شود.

# /etc/sysctl.conf

# حداکثر اتصالات در صف Accept
net.core.somaxconn = 262144

# Backlog دستگاه شبکه
net.core.netdev_max_backlog = 262144

# اندازه بافر TCP (min، default، max) به بایت
net.ipv4.tcp_rmem = 8192 87380 134217728
net.ipv4.tcp_wmem = 8192 87380 134217728

# محدودیت‌های حافظه Socket
net.core.wmem_max = 134217728
net.core.rmem_max = 134217728

# حافظه TCP (پایین، فشار، بالا) در صفحات
net.ipv4.tcp_mem = 6093984 8125312 32777216

چرا این مهم است: تحت همزمانی بالا، کرنل باید اتصالات و داده‌های ورودی را بافر کند. مقادیر پیش‌فرض (اغلب ۱۲۸ یا ۱۰۲۴ برای somaxconnقطع اتصال ایجاد می‌کنند قبل از اینکه اپلیکیشن حتی درخواست را ببیند.

محدودیت‌های توصیف‌گر فایل

یک سرور پایگاه داده با ۱,۰۰۰ اتصال همزمان حداقل به ۱,۰۰۰ توصیف‌گر فایل نیاز دارد — به علاوه فایل‌ها، سوکت‌ها و پایپ‌ها. محدودیت پیش‌فرض ۱۰۲۴ ناکافی است.

# /etc/security/limits.conf
mysql soft nofile 65535
mysql hard nofile 65535
www-data soft nofile 65535
www-data hard nofile 65535

زمان‌بند I/O برای SSD/NVMe

برای ذخیره‌سازی مدرن (SSD، NVMe)، زمان‌بند I/O سربار غیرضروری اضافه می‌کند. none (یا noop) I/O را مستقیماً به دستگاه می‌فرستد.

# بررسی زمان‌بند فعلی
cat /sys/block/nvme0n1/queue/scheduler
# [none] mq-deadline kyber bfq

# تنظیم روی none برای NVMe
echo none > /sys/block/nvme0n1/queue/scheduler

نکته مهندسی: mq-deadline جایگزین توصیه‌شده است اگر none مشکلاتی ایجاد کند. برای دیسک‌های چرخشی، mq-deadline به none ترجیح داده می‌شود.

حافظه مجازی و NUMA

# افزایش نواحی نقشه حافظه برای پایگاه‌های داده بزرگ
vm.max_map_count = 1600000

# غیرفعال کردن تعادل NUMA در سیستم‌های چند-Node
kernel.numa_balancing = 0

چرا: vm.max_map_count خیلی پایین باعث خطاهای mmap تحت تعداد اتصال بالا می‌شود. تعادل NUMA سربار روی بارهای کاری پایگاه داده که برای Nodeهای حافظه خاص بهینه شده‌اند اضافه می‌کند.

بخش ۸ — همه را کنار هم: جریان کاری بهینه‌سازی

تنظیم عملکرد یک فرآیند است، نه یک چک‌لیست. جریان کاری:

۱. اندازه‌گیری
   ├─ پایه: تأخیر، توان عملیاتی، نرخ خطا
   ├─ شناسایی لایه گلوگاه (اپلیکیشن، کش، DB، شبکه)
   └─ پروفایل: EXPLAIN ANALYZE، لاگ‌های کند، معیارهای سیستم

۲. بهینه‌سازی گلوگاه
   ├─ اگر محدود به DB: ایندکس‌ها، بازنویسی پرس‌وجو، Connection Pooling
   ├─ اگر محدود به کش: توپولوژی Redis، سیاست Eviction، Socket
   ├─ اگر محدود به PHP: کارگران FPM، max_requests، حافظه
   └─ اگر محدود به شبکه: بافرهای کرنل، somaxconn

۳. تأیید
   ├─ اندازه‌گیری مجدد تحت همان بار
   ├─ تأیید بهبود، بدون رگرسیون
   └─ مستندسازی تغییر و تأثیر

۴. تکرار
   └─ گلوگاه بعدی اکنون قابل مشاهده است

اصل حیاتی: هرگز دو لایه را همزمان بهینه نکنید. نخواهید دانست کدام تغییر کار کرد — یا کدام یک چیزی را شکست.

بخش ۹ — چه زمانی از این استک بهینه‌سازی استفاده کنیم (و چه زمانی نه)

این استک را اعمال کنید وقتی:

  • ✅ پلتفرم ترافیک همزمان بالا (۱۰۰+ کاربر همزمان) را سرو می‌کند

  • ✅ پرس‌وجوهای پایگاه داده قابل اندازه‌گیری کند هستند (EXPLAIN ANALYZE Seq Scan نشان می‌دهد)

  • ✅ کارگران PHP-FPM تحت بار تمام شده‌اند

  • ✅ Redis مستقر است اما برای بار کاری تنظیم نشده

  • ✅ زیرساخت خود-مدیریت است (نه میزبانی مشترک)

اعمال نکنید وقتی:

  • ❌ ترافیک پایین است — تلاش بهینه‌سازی از فایده فراتر می‌رود

  • ❌ گلوگاه منطق اپلیکیشن است (پرس‌وجوهای N+1، کد ناکارآمد)

  • ❌ زیرساخت توسط یک ارائه‌دهنده مدیریت می‌شود بدون دسترسی به کرنل

  • ❌ تیم فاقد ظرفیت عملیاتی برای نگهداری سیستم‌های تنظیم‌شده است

تنظیم کرنل بدون پایش، حدس زدن است. ایندکس‌گذاری بدون EXPLAIN، امیدواری است. بهینه‌سازی بدون اندازه‌گیری، خرافه است.

نتیجه‌گیری — عملکرد یک دیسیپلین است، نه یک افزونه

لایه افزونه بردهای آسان ارائه می‌دهد. اما وقتی همزمانی بالا می‌رسد — و همیشه می‌رسد — لایه افزونه کافی نیست.

اجرای زیر-میلی‌ثانیه‌ای تحت بار نیازمند این است:

  • پلن‌های اجرا خوانده و درک شده — نه فرض

  • Connection Pooling معماری‌شده — نه رها شده به پیش‌فرض

  • توپولوژی‌های Redis طراحی‌شده — نه فقط نصب شده

  • کش FastCGI پیکربندی‌شده — نه فقط فعال شده

  • PHP-FPM به سخت‌افزار اندازه‌دهی‌شده — نه به امیدها

  • پارامترهای کرنل تنظیم‌شده — نه رها شده به پیش‌فرض‌های همه‌منظوره

این دیسیپلین مهندسی است که پلتفرم‌هایی که ترافیک را زنده می‌مانند از پلتفرم‌هایی که محدودیت‌هایشان را تعریف می‌کنند جدا می‌کند.

پایگاه داده کند نیست. استک اطراف آن تنظیم‌نشده است.

یادداشت نویسنده

این مقاله الگوهای بهینه‌سازی توسعه‌یافته در هنگام مهندسی Barman News (۱۰۰,۰۰۰+ مقاله تحت همزمانی بالا) و CoreBiz ERP (پردازش تراکنش‌های سازمانی) را بازتاب می‌دهد. برای همکاری در معماری پایگاه داده پرعملکرد، از طریق صفحه تماس با من در ارتباط باشید.

Tags:
Write a comment