SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-29

VPS پر WordPress کے لیے Redis object cache سیٹ اپ

اپنے VPS پر WordPress کے لیے Redis object cache فعال کریں، اسے localhost تک محدود رکھیں، maxmemory اور eviction policy منتخب کریں، اور تصدیق کریں کہ cache واقعی کام کر رہی ہے۔

WordPress کے لیے Redis object cache کیا کرتا ہے

WordPress کے لیے Redis object cache database queries کے نتائج memory میں محفوظ کرتا ہے، تاکہ اگلی request انہیں دوبارہ MySQL سے حاصل کرنے کے بجائے Redis سے پڑھ لے۔ WordPress کے core میں پہلے ہی object cache موجود ہے، WP_Object_Cache، لیکن یہ PHP memory میں رہتا ہے اور request ختم ہوتے ہی ضائع ہو جاتا ہے۔ ایک drop-in file اسے ایسی cache سے بدل دیتی ہے جو Redis سے رابطہ کرتی ہے، اس لیے cache ایک request سے اگلی request تک برقرار رہتی ہے۔

Object caching، page caching نہیں ہے، اور اس فرق سے طے ہوتا ہے کہ یہ guide آپ کے وقت کے قابل ہے یا نہیں۔ Page cache کسی URL کی مکمل HTML محفوظ کرتی ہے اور PHP چلائے بغیر اسے دوبارہ serve کرتی ہے۔ یہ Redis کی کسی بھی کارروائی سے زیادہ تیز ہوتی ہے اور ان visitors کے لیے کام کرتی ہے جو logged in نہیں ہیں۔ جیسے ہی کوئی شخص login کرتا ہے، cart میں item شامل کرتا ہے، یا admin کھولتا ہے، page cache الگ ہو جاتی ہے اور WordPress پوری request چلاتا ہے: bootstrap، plugins، queries۔ Object cache اسی request کی لاگت کم کرتی ہے۔ یہ اس traffic کے لیے ہے جسے page cache handle نہیں کر سکتی: logged-in sessions، carts، checkout، wp-admin۔ WooCommerce shop پر یہی زیادہ تر مہنگا traffic ہوتا ہے۔

دونوں ایک ساتھ کام کرتے ہیں، اور مصروف site پر دونوں ضروری ہوتے ہیں۔ واضح طور پر طے کریں کہ آپ کون سا مسئلہ حل کر رہے ہیں۔ Anonymous readers والی brochure site اپنی تقریباً تمام رفتار page cache سے حاصل کرتی ہے، اور اس میں Redis شامل کرنے سے بہت کم فرق پڑتا ہے۔

شروع کرنے سے پہلے ایک اہم حد سمجھ لیں۔ Object cache کسی slow query کو fast نہیں بناتی۔ یہ صرف ایسی query کو دوبارہ چلنے سے روکتی ہے جو پہلے ہی چل چکی ہو۔ Cache miss کے بعد پہلی request پوری لاگت ادا کرتی ہے، اس لیے unindexed query چلانے والا plugin ہر cache lifetime میں اسے کم از کم ایک بار ضرور چلاتا ہے۔

آپ کو پہلے یہ چیزیں درکار ہوں گی

  • ایک Linux VPS، جس پر shell اور sudo دستیاب ہوں۔ کسی control panel کی ضرورت نہیں۔
  • PHP-FPM کے ذریعے چلنے والا WordPress، مثلاً Ubuntu 24.04 پر LAMP stack۔
  • اسی server پر WP-CLI۔ یہاں ہر مرحلے کا admin screen متبادل موجود ہے، لیکن shell والا طریقہ زیادہ تیز ہے۔
  • PHP والی اسی machine پر Redis۔ کم latency ہی اصل مقصد ہے، اور network hop اس فائدے کو ختم کر دیتا ہے۔

ذیل کے commands Ubuntu 24.04، PHP 8.3 اور www-data web user کے لیے لکھی گئی ہیں۔ اپنے server کے مطابق PHP version اور user تبدیل کریں۔ wp commands اپنی WordPress directory سے چلائیں، یعنی اس directory سے جس میں wp-config.php موجود ہو۔

Redis اور PHP extension انسٹال کریں

sudo apt update
sudo apt install -y redis-server php-redis
sudo systemctl enable --now redis-server
redis-cli ping

redis-cli ping کا جواب PONG ہونا چاہیے۔ اگر یہ Could not connect to Redis at 127.0.0.1:6379: Connection refused دکھائے تو سرور چل نہیں رہا، اس لیے آگے بڑھنے سے پہلے systemctl status redis-server پڑھیں۔

php-redis PhpRedis ہے، جو PECL کی C extension ہے۔ یہ خالص PHP میں لکھی گئی Predis سے تیز ہے، اور plugin موجود ہونے پر اسے خودکار طور پر استعمال کرتا ہے۔ PHP-FPM extensions کو start کے وقت load کرتا ہے، اس لیے نئی extension اس وقت تک نظر نہیں آئے گی جب تک آپ pool کو restart نہ کریں۔

sudo systemctl restart php8.3-fpm
php -m | grep redis

اس آخری جانچ میں محتاط رہیں: php -m صرف command line PHP کے modules دکھاتا ہے، جبکہ FPM مختلف modules load کر سکتا ہے۔ فیصلہ کن جانچ plugin کی اپنی diagnostics ہے، جو آگے دی گئی ہے۔

August 2026 تک Ubuntu 24.04 میں Redis 7.0.15 package شامل ہے، جو object cache کے لیے موزوں ہے۔ اگر آپ اس کے بجائے موجودہ release چاہتے ہیں تو Redis اپنا APT repository فراہم کرتا ہے۔

sudo apt install -y lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update
sudo apt install -y redis

اگر آپ کی distribution Valkey فراہم کرتی ہے، جو 2024 کی licence تبدیلی کے بعد شروع ہونے والا fork ہے، تو یہ وہی protocol استعمال کرتا ہے اور ذیل کی تمام ہدایات بغیر کسی تبدیلی کے لاگو ہوتی ہیں۔

Redis کو اس طرح bind کریں کہ کوئی اور اس تک رسائی نہ حاصل کر سکے

Redis میں بطور ڈیفالٹ password نہیں ہوتا۔ جو بھی port 6379 پر connection کھول سکتا ہے، وہ ہر cached value پڑھ سکتا ہے اور FLUSHALL چلا سکتا ہے۔ Internet پر exposed instances کو scanners چند گھنٹوں میں تلاش کر لیتے ہیں، اس لیے tuning سے پہلے network setting درست کریں۔

/etc/redis/redis.conf کھولیں اور ان lines کی تصدیق کریں:

bind 127.0.0.1 -::1
protected-mode yes

پھر یہ بھی دیکھیں کہ حقیقت میں کون سا process listening کر رہا ہے، کیونکہ configuration file صرف دعویٰ ہے اور ss ثبوت ہے۔

sudo ss -lntp | grep 6379

127.0.0.1:6379 مطلوبہ حالت ہے۔ 0.0.0.0:6379 کا مطلب ہے کہ Redis public interface پر جواب دے رہا ہے: bind line درست کریں اور restart کریں۔

جب PHP اور Redis ایک ہی box پر ہوں تو loopback TCP کے بجائے Unix socket بہتر ہے۔ اس راستے میں TCP stack شامل نہیں ہوتا، اور access کا فیصلہ file permissions سے ہوتا ہے، نہ کہ ایسی firewall rule سے جسے آپ بعد میں تبدیل کر سکتے ہیں۔

unixsocket /run/redis/redis-server.sock
unixsocketperm 770

socket کا مالک redis user اور group ہے، اس لیے web user کو اس group میں شامل کرنا ہوگا۔

sudo systemctl restart redis-server
sudo usermod -aG redis www-data
sudo systemctl restart php8.3-fpm
redis-cli -s /run/redis/redis-server.sock ping

اس command کا output PONG بھی دکھانا چاہیے۔ Could not connect to Redis at /run/redis/redis-server.sock: Permission denied کا مطلب ہے کہ group مؤثر نہیں ہوا۔ id www-data چیک کریں، اور یاد رکھیں کہ چلتا ہوا PHP-FPM شروع ہوتے وقت موجود groups ہی برقرار رکھتا ہے، اسی لیے list میں restart شامل ہے۔ Socket کی تصدیق ہونے تک TCP enabled رکھیں، ورنہ ایک typo دونوں راستے بیک وقت بند کر سکتا ہے۔

Redis کو کتنی memory دینی چاہیے؟

یہ عدد اپنے سرور سے اخذ کریں۔ maxmemory کے بغیر Redis اس وقت تک بڑھتا رہتا ہے جب تک kernel کی memory ختم نہیں ہو جاتی اور OOM killer کسی process کو ختم نہیں کر دیتا۔ عموماً سب سے بڑا process ختم ہوتا ہے، اور WordPress سرور پر یہ اکثر MySQL ہوتا ہے۔ journalctl -k | grep -i "out of memory" اس termination کو بعد میں دکھاتا ہے، لیکن تب تک site down ہو چکی ہوتی ہے۔

کل RAM سے آغاز کریں اور دیگر استعمال منہا کریں۔ MySQL یا MariaDB innodb_buffer_pool_size کے علاوہ ہر connection کے buffers کے لیے بھی memory محفوظ کرتا ہے۔ PHP-FPM کی لاگت pm.max_children کو ایک worker کے حقیقی resident size سے ضرب دینے کے برابر ہے۔ Plugin-heavy site پر یہ عموماً 64 MB سے 128 MB ہوتی ہے۔ kernel اور web server کو چند سو megabytes درکار ہوتے ہیں۔ جو memory بچ جائے وہ آپ کی حد ہے، اور Redis کو اسی کا ایک حصہ ملنا چاہیے۔

4 GB VPS پر ایک shop چلانے کے لیے نمونہ budget

یہ مثالی اعداد ہیں، آپ کے سرور کی پیمائش نہیں۔ ہر عدد کو اپنے سرور کی رپورٹ کردہ value سے تبدیل کریں۔

  • 1 GB buffer pool کے ساتھ MariaDB: 1024 MB
  • PHP-FPM، 96 MB کے 10 workers: 960 MB
  • kernel، nginx یا Apache، sshd، logging: 512 MB
  • باقی memory: تقریباً 1.5 GB

ایسی صورت میں maxmemory کی 256 MB حد ایک مناسب ابتدائی قدر ہے۔ اس سے مناسب headroom باقی رہتی ہے، اور ایک عام WordPress site کو عموماً اس سے زیادہ memory درکار نہیں ہوتی۔

اب اندازہ لگانے کے بجائے پیمائش کریں۔ حقیقی traffic کے ایک دن کے بعد:

redis-cli info memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli dbsize

اگر used_memory_human آپ کی limit سے کافی کم رہے تو limit کم کریں اور RAM MySQL کو واپس دیں، کیونکہ وہ اسے زیادہ مؤثر طور پر استعمال کرے گا۔ اگر یہ limit پر قائم رہے اور evicted_keys پورا دن بڑھتا رہے تو limit بڑھائیں۔ value /etc/redis/redis.conf میں set کریں۔

maxmemory 256mb
maxmemory-policy allkeys-lru

redis-cli config set maxmemory 256mb یہ تبدیلی فوراً نافذ کرتا ہے، لیکن اگلے restart پر ختم ہو جاتی ہے۔ یہ وہی مسئلہ ہے جو صرف sysctl -w استعمال کرنے سے پیدا ہوتا ہے۔ file edit کریں، پھر sudo systemctl restart redis-server چلائیں، اور اس کے بعد value دوبارہ پڑھیں۔ ایک دوسری حد رکھنا بھی مفید ہے: systemd unit پر MemoryMax cap misconfigured Redis کو پورا سرور down کرنے سے روک سکتی ہے۔ اسے maxmemory سے زیادہ set کریں، کبھی اس کے برابر نہ کریں، کیونکہ cgroup limit key کو evict کرنے کے بجائے process کو ختم کرتی ہے۔ اگر Redis WordPress کے ساتھ ایک container میں چلتا ہے تو یہی figure آپ کی Compose file میں memory limits میں شامل ہونی چاہیے، اور یہی reasoning database کو Docker میں چلانے یا host پر رکھنے کے انتخاب پر بھی لاگو ہوتی ہے۔

Eviction policy کا انتخاب سوچ سمجھ کر کریں

نیا Redis، بطور default، noeviction استعمال کرتا ہے۔ اپنی configuration چیک کریں:

redis-cli config get maxmemory-policy

noeviction کے تحت، مکمل instance نئی writes قبول کرنا بند کر دیتا ہے اور یہ جواب دیتا ہے:

(error) OOM command not allowed when used memory > 'maxmemory'.

یہ ایک سطر اس guide میں بیان کردہ بدترین failure mode ہے، کیونکہ site بند نہیں ہوتی۔ اس کی رفتار کم ہو جاتی ہے۔ ہر cache write ناکام ہو جاتی ہے، اس لیے WordPress value کے لیے دوبارہ database سے رجوع کرتا ہے، پھر اگلی request پر اسے دوبارہ store کرنے کی کوشش کرتا ہے اور دوبارہ ناکام ہو جاتا ہے۔ اب site اپنے تمام اصل database کام کے ساتھ ساتھ ہر key کے لیے Redis تک ایک اضافی round trip بھی کرتی ہے۔ WordPress admin میں کوئی چیز آپ کو نہیں بتاتی کہ یہ ہو رہا ہے۔ یہ string PHP error log میں ظاہر ہوتی ہے، اس لیے جب cache شامل کرنے کے بعد site سست ہو جائے تو OOM command not allowed کے لیے grep کریں۔

allkeys-lru یہاں درست default ہے۔ Memory کم پڑنے پر Redis وہ key حذف کر دیتا ہے جو سب سے طویل عرصے سے استعمال نہیں ہوئی، اور object cache کے لیے یہی مطلوب ہے، کیونکہ اس میں موجود ہر value اس data کی copy ہے جو اب بھی MySQL میں موجود ہے۔ ایک key ضائع ہونے کی قیمت ایک query ہے۔ Write مسترد ہونے کی قیمت ہر request پر ہر query ہے، جب تک کوئی اس مسئلے کو محسوس نہ کر لے۔

اس کام کے لیے volatile-* policies سے گریز کریں۔ یہ صرف ان keys کو مدنظر رکھتی ہیں جن کے ساتھ expiry موجود ہو، اور Redis کی documentation کے مطابق جب کسی key کے ساتھ expiry نہ ہو تو یہ noeviction جیسا برتاؤ کرتی ہیں۔ WordPress زیادہ تر object cache entries بغیر TTL کے محفوظ کرتا ہے، اس لیے object cache میں volatile-lru بھر سکتا ہے اور writes مسترد کرنا شروع کر سکتا ہے۔ اگر آپ کی traffic اکثر keys کے ایک چھوٹے مجموعے پر آتی ہے تو allkeys-lfu ایک مناسب متبادل ہے، کیونکہ یہ recency کے بجائے frequency کی بنیاد پر eviction کرتی ہے۔ ایک policy کا جان بوجھ کر انتخاب کریں اور اس کی وجہ تحریر میں درج کریں۔

Persistence: ضرورت نہ ہو تو اسے بند رکھیں

پیکیج کے ساتھ آنے والا redis.conf، save 900 1 جیسی سطروں کے ذریعے RDB snapshots فعال کرتا ہے اور append-only file کو بند رکھتا ہے۔ خالص object cache کے لیے snapshots کا کوئی فائدہ نہیں۔ تعریف کے مطابق یہ data دوبارہ بنایا جا سکتا ہے، جبکہ بیس منٹ پرانی file سے بحال کیا گیا cache stale values کا مجموعہ ہوتا ہے، جن پر WordPress اعتماد کرے گا۔

Snapshots کی لاگت بھی ہوتی ہے۔ BGSAVE process کا fork بناتا ہے، اور copy-on-write کی وجہ سے child کے لکھنے کے دوران memory کا استعمال تیزی سے بڑھ سکتا ہے۔ چھوٹے VPS پر یہ Redis log میں یوں ظاہر ہوتا ہے:

Can't save in background: fork: Cannot allocate memory

اور startup کے وقت اکثر یہ warning بھی آتی ہے۔ اس کا مطلب ہے کہ Redis بتا رہا ہے کہ بعد میں fork ناکام ہو سکتا ہے:

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.

Snapshots بند کرنے کے لیے /etc/redis/redis.conf میں خالی save schedule مقرر کریں، restart کریں، اور تصدیق کریں کہ value دوبارہ خالی ہو گئی ہے۔

save ""
sudo systemctl restart redis-server
redis-cli config get save

Persistence صرف اسی وقت برقرار رکھیں جب اسی instance میں ایسی چیز موجود ہو جسے دوبارہ نہیں بنایا جا سکتا، مثلاً job queue یا rate-limit counters۔ ایسی صورت میں دونوں کو الگ کریں۔ Cache میں keys کو evict کیا جانا چاہیے، جبکہ durable data کی keys محفوظ رہنی چاہییں۔ maxmemory اور eviction پورے instance پر لاگو ہوتے ہیں، کسی ایک database index پر نہیں۔ دو sockets پر دو instances چلانا صاف اور درست حل ہے۔

پلگ اِن انسٹال کریں اور drop-in کو سمجھیں

wp plugin install redis-cache --activate
wp redis enable
wp redis status

کامیابی پر wp redis enable، Object cache enabled. پرنٹ کرتا ہے۔ یہ دراصل wp-content/plugins/redis-cache/includes/object-cache.php کو wp-content/object-cache.php میں copy کرتا ہے۔ یہی copy drop-in ہے، اور کام drop-in ہی انجام دیتا ہے۔ WordPress wp-content/object-cache.php کو بہت ابتدائی مرحلے میں load کرتا ہے، یعنی کسی بھی plugin code کے چلنے سے پہلے۔ اسی طرح پوری request کے لیے cache دستیاب رہتا ہے۔ اگر plugin فعال ہو لیکن drop-in موجود نہ ہو تو کچھ بھی cache نہیں ہوتا۔

Failure messages بتاتے ہیں کہ کون سا حصہ ناکام ہوا۔ Object cache could not be enabled. کا مطلب ہے کہ copy ناکام ہوئی، اس لیے WP-CLI چلانے والے user کے لیے wp-content writable نہیں ہے۔ A foreign object cache drop-in was found. کا مطلب ہے کہ کوئی دوسرا caching plugin پہلے ہی اس filename کو استعمال کر رہا ہے، اور اس کا حل wp redis update-dropin ہے۔ اگر message Redis server is unreachable: پر ختم ہو اور اس کے بعد client error آئے تو connection settings غلط ہیں۔ ایسی صورت میں redis-cli ping کی طرف واپس جائیں۔

اگر permissions کی وجہ سے copy ناکام ہوئی ہو تو اسے دستی طور پر رکھیں اور web user کو اس کا مالک بنائیں۔

cp wp-content/plugins/redis-cache/includes/object-cache.php wp-content/object-cache.php
sudo chown www-data:www-data wp-content/object-cache.php

Plugin ہٹانے سے drop-in نہیں ہٹتا۔ پہلے wp redis disable چلائیں۔ یہ Object cache disabled. پرنٹ کرتا ہے اور file delete کر دیتا ہے۔ اگر drop-in موجود رہنے کے دوران plugin directory delete کر دیں تو site پرانا cache code چلاتی رہے گی، لیکن اسے update کرنے کے لیے کوئی plugin موجود نہیں ہوگا۔

wp-config.php میں کنکشن کی ترتیبات

ان ترتیبات کو /* That's all, stop editing! */ والی سطر سے پہلے شامل کریں، کیونکہ اس کے بعد متعین کیے گئے constants بہت دیر سے متعین ہوتے ہیں۔

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );
define( 'WP_REDIS_PREFIX', 'shop_prod:' );

Unix socket کے لیے scheme اور path متعین کریں۔ اس کے بعد host اور port کو نظر انداز کیا جاتا ہے۔

define( 'WP_REDIS_SCHEME', 'unix' );
define( 'WP_REDIS_PATH', '/run/redis/redis-server.sock' );
define( 'WP_REDIS_PREFIX', 'shop_prod:' );

WP_REDIS_MAXTTL ہر key کے لیے seconds میں expiry نافذ کرتا ہے۔ allkeys-lru کے ساتھ اسے استعمال کرنے کی ضرورت نہیں۔ اگر آپ cached value کے زیادہ سے زیادہ stale رہنے کی مدت کی سخت حد مقرر کرنا چاہتے ہیں تو یہ مفید ہے۔

ایک Redis، متعدد سائٹس: prefixes اور databases

Redis بطور ڈیفالٹ سولہ numbered databases فراہم کرتا ہے، اور ہر database کے اندر ایک flat keyspace ہوتا ہے۔ اگر دو WordPress installations بغیر prefix کے database 0 کو استعمال کریں تو وہ اسی keyspace میں ایک ہی key names لکھیں گی۔ نتیجتاً ایک سائٹ دوسری سائٹ کے options پڑھ کر انہیں serve کر سکتی ہے۔ ہر سائٹ کے لیے الگ prefix مقرر کریں۔

define( 'WP_REDIS_PREFIX', 'shopA_prod:' );
define( 'WP_REDIS_DATABASE', 1 );

prefix key names کو الگ کرتا ہے۔ database index keyspaces کو الگ کرتا ہے، جو flush کے وقت اہم ہوتا ہے: ایک index خالی کرنے سے باقی indexes متاثر نہیں ہوتے۔ plugin WP_REDIS_SELECTIVE_FLUSH کو بھی document کرتا ہے۔ یہ پورے database کے بجائے صرف آپ کے prefix سے match ہونے والی keys delete کرتا ہے، لیکن اس کے لیے ان keys کو scan کرنا پڑتا ہے۔

prefixes اور indexes memory کو الگ نہیں کرتے۔ maxmemory اور eviction policy پوری instance پر لاگو ہوتے ہیں۔ اس لیے ایک مصروف سائٹ کسی کم مصروف سائٹ کی keys کو evict کر سکتی ہے، اور دونوں میں سے کوئی بھی اس کی اطلاع نہیں دیتا۔ جن سائٹس کو ایک دوسرے پر اثر انداز نہیں ہونا چاہیے، ان کے لیے الگ Redis instances درکار ہیں۔ ہر instance کا اپنا socket اور اپنی limit ہونی چاہیے۔

پیداواری ماحول کے cache کو staging سے الگ رکھیں

Staging site عموماً production files اور database کی نقل ہوتی ہے۔ اس کا مطلب ہے کہ یہ wp-config.php کی بھی نقل ہے اور اسی prefix اور اسی database index کا استعمال کرتی ہے۔ اگر اسے اسی Redis کی طرف point کیا جائے تو یہ staging values کے ساتھ production keys لکھتی ہے۔ Test price یا تبدیل شدہ option پھر بغیر کسی deploy اور trace کے live site پر ظاہر ہو جاتی ہے۔

ہر environment کے لیے salt دستی طور پر الگ مقرر کریں۔ Staging کے wp-config.php میں:

define( 'WP_REDIS_PREFIX', 'shop_staging:' );
define( 'WP_REDIS_DATABASE', 5 );

اس سے بہتر ہے کہ staging کو اپنی Redis instance دیں، یا اسے object cache بالکل نہ دیں۔ define( 'WP_REDIS_DISABLED', true ); runtime پر cache بند کر دیتا ہے اور drop-in کو موجود رکھتا ہے۔ یہ ثابت کرنے کا تیز ترین طریقہ بھی ہے کہ bug cache کی وجہ سے ہے یا نہیں۔

پرانے tutorials اس مقصد کے لیے WP_CACHE_KEY_SALT مقرر کرتے تھے۔ Plugin کے readme میں اس constant کو deprecated قرار دے کر WP_REDIS_PREFIX سے replace کیا گیا ہے، اس لیے نیا نام استعمال کریں۔

اس پر بھروسا کرنے کے بجائے اس کی تصدیق کریں

ابتدا plugin کی اپنی diagnostics سے کریں۔

wp redis status

سب سے اہم سطر Drop-in ہے۔ Drop-in: Valid کا مطلب ہے کہ WordPress اس plugin کی file load کر رہا ہے۔ Drop-in: Not installed کا مطلب ہے کہ copy کبھی نہیں ہوئی اور site کے پاس persistent cache موجود نہیں، چاہے admin screen کتنی ہی درست دکھائی دے۔ Status connection کی رپورٹ دیتا ہے، جبکہ Client زیرِ استعمال extension کا نام بتاتا ہے۔ اسی جگہ PhpRedis کی تصدیق Predis کے بجائے کریں۔

پھر WordPress core سے براہِ راست پوچھیں، کیونکہ اسے اس بات سے کوئی فرق نہیں پڑتا کہ plugin کیا سمجھتا ہے۔

wp eval 'var_dump( wp_using_ext_object_cache() );'

bool(true) کا مطلب ہے کہ core کسی external object cache سے رابطہ کر رہا ہے۔

اب configured prefix کے ساتھ keys کے پہنچنے کا ثبوت حاصل کریں۔

redis-cli -n 0 dbsize
redis-cli -n 0 --scan --pattern 'shop_prod:*' | head

Site پر مختلف صفحات کھولتے وقت dbsize کا بڑھنا اس کا ثبوت ہے۔ Valid drop-in کے باوجود صفر keys کا مطلب ہے کہ connection خاموشی سے ناکام ہو رہا ہے، یا prefix وہ نہیں ہے جسے آپ درست سمجھ رہے ہیں۔

آخر میں دیکھیں کہ Redis آپ کے لیے کیا پیمائش کرتا ہے۔

redis-cli info stats | grep -E 'keyspace_hits|keyspace_misses|evicted_keys|expired_keys'

Hit ratio keyspace_hits / (keyspace_hits + keyspace_misses) ہے، اور Redis کی documentation میں یہی formula دیا گیا ہے۔ اسے 2 احتیاطوں کے ساتھ سمجھیں۔ Counters پورے instance کے لیے اس کے آخری restart سے اب تک کا ڈیٹا رکھتے ہیں، اس لیے ان میں ہر وہ site اور application شامل ہوتی ہے جو اسے share کرتی ہے۔ نیز flush یا restart کے فوراً بعد ratio کا کوئی مفہوم نہیں ہوتا، کیونکہ cache ابھی بھر رہا ہوتا ہے۔ اسے معمول کے network traffic والے پورے دن تک چلنے دیں۔

اپنے number کا موازنہ کسی hosting company کی شائع کردہ hit rate یا query count سے نہ کریں۔ وہ ان کی sites اور ان کے plugin set کی عکاسی کرتے ہیں۔ اہم figure آپ کا اپنا ہے، جسے ایسی page پر پہلے اور بعد میں measure کیا جائے جسے page cache serve نہیں کر سکتا۔

curl -o /dev/null -s -w '%{time_starttransfer}\n' -b cookies.txt https://example.com/my-account/

یہ عمل logged-in cookie jar کے ساتھ کئی بار چلائیں، پہلے cache بند رکھ کر (WP_REDIS_DISABLED) اور پھر اسے فعال کر کے۔ دونوں نتائج کا فرق ہی آپ کا result ہے۔

جب Redis، WordPress کو سست کر دیتا ہے

غلط policy کے ساتھ بھرا ہوا instance سب سے بڑی وجہ ہے، جس کا اوپر ذکر ہو چکا ہے: log میں OOM command not allowed when used memory > 'maxmemory'.، جبکہ site database اور cache دونوں کے لیے ادائیگی کر رہی ہوتی ہے۔

دوسری وجہ کسی دوسرے host پر Redis چلانا ہے۔ WordPress ایک request کے دوران object cache کو سینکڑوں مرتبہ call کرتا ہے۔ اگر ایک request میں 500 calls ہوں اور ہر round trip میں 1 ms لگے، تو نصف second انتظار میں صرف ہو جاتا ہے، جو local socket کے ساتھ نہیں ہوتا۔ Redis کو اسی box پر رکھیں، یا sub-millisecond latency والے private network پر چلائیں۔ Same-box صورتِ حال میں kernel سے حاصل ہونے والا فائدہ کتنا ہے، یہ الگ سوال ہے: Linux 7.2 میں شامل cache-aware scheduling PHP-FPM اور Redis جیسے کثرت سے باہمی رابطہ کرنے والے processes کو ایسے cores پر رکھنے کی کوشش کرتی ہے جو ایک cache شیئر کرتے ہوں، اور VPS guest کو bare metal کے مقابلے میں اس کا کم فائدہ ملتا ہے۔

تیسری وجہ بہت بڑا autoloaded options table ہے، جو پرانی sites میں عام ہے۔ WordPress تمام autoloaded options کو ایک key کے طور پر cache کرتا ہے، اس لیے ہر request پر ان کا ایک megabyte connection کے ذریعے منتقل ہوتا ہے۔ اس کی پیمائش کریں:

wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS kb FROM wp_options WHERE autoload IN ('yes','on','auto','auto-on');"

WordPress 6.6 نے نئے autoload values شامل کیے، اس لیے جدید install پر صرف 'yes' سے match کرنے والی پرانی query اصل مقدار کم دکھاتی ہے۔ ایک megabyte سے زیادہ مقدار options table میں درست کرنے کا مسئلہ ہے، Redis میں نہیں۔

Restart ہر چیز خالی کر دیتا ہے، اس لیے systemctl restart redis-server کے بعد کے چند minutes میں تمام requests cache misses ہوتی ہیں اور database پر سارا کام دوبارہ ہوتا ہے۔ Traffic کم ہونے پر restart کریں۔ Object cache visitor page loads پر wp-cron.php کو fire ہونے سے نہیں روکتا، اور یہ slow requests کی اپنی ایک وجہ ہے: اس دوران WP-Cron کو حقیقی system cron job پر منتقل کریں۔

ہاؤس کیپنگ

ایسے deploy کے بعد wp cache flush کے ذریعے cache صاف کریں جس میں options یا theme code تبدیل ہوا ہو۔ اگر plugin update کے بعد drop-in خودکار طور پر update نہ ہوا ہو تو wp redis update-dropin چلائیں، کیونکہ نئے plugin کے ساتھ پرانے plugin version کا drop-in غیر متوقع رویے کی حقیقی وجہ بن سکتا ہے۔ live server کی نگرانی redis-cli --stat سے کریں؛ یہ ہر سیکنڈ ایک سطر دکھاتا ہے۔ redis-cli monitor ہر command پرنٹ کرتا ہے اور مصروف instance پر حقیقی CPU استعمال کرتا ہے، اس لیے کسی مسئلے کو reproduce کرتے وقت اسے چند سیکنڈ کے لیے استعمال کریں، پھر روک دیں۔

ایک آخری اہم number یہ ہے: redis-cli info clients، connected_clients کی رپورٹ کرتا ہے۔ PHP-FPM ہر worker کے لیے ایک connection برقرار رکھتا ہے، اس لیے یہ figure آپ کے pm.max_children کے مطابق ہونی چاہیے، نہ کہ اس سے ایک order of magnitude زیادہ۔ اگر ایسا ہو تو کوئی چیز connections کھول رہی ہے اور انہیں بند نہیں کر رہی۔

FAQ

اگر میں Redis object cache استعمال کر رہا ہوں تو کیا مجھے پھر بھی page cache درکار ہے؟

ہاں، anonymous traffic کے لیے۔ page cache ذخیرہ شدہ HTML کو PHP چلائے بغیر فراہم کرتا ہے، جو warm object cache کے ساتھ بھی WordPress چلانے سے ہمیشہ کم وسائل لیتا ہے۔ object cache ان requests کو سنبھالتا ہے جنہیں page cache کو نظرانداز کرنا پڑتا ہے: logged-in users، carts، checkout اور wp-admin۔ shop یا membership site پر دونوں چلانا مفید ہے۔ ایسی site پر جہاں visitors کبھی login نہیں کرتے، تقریباً سارا کام page cache کر دیتا ہے۔

WordPress کے لیے Redis کو کتنی memory دینی چاہیے؟

کسی اور کا عدد نقل کرنے کے بجائے اپنی machine کے وسائل سے مقدار اخذ کریں۔ کل RAM میں سے MySQL buffer pool اور per-connection buffers منہا کریں، پھر pm.max_children کو ایک PHP-FPM worker کے resident size سے ضرب دے کر حاصل ہونے والی مقدار منہا کریں، اور kernel اور web server کے لیے چند سو megabytes الگ رکھیں۔ باقی memory کا ایک حصہ Redis کو دیں، پھر ایک دن کے traffic کے بعد redis-cli info memory میں used_memory_human دیکھ کر مقدار درست کریں۔ ایک single WordPress site عموماً دسیوں megabytes پر مستحکم ہو جاتی ہے، اس لیے 4 GB server پر 256 MB maxmemory ایک فراخ ابتدا ہے۔

Redis object cache فعال کرنے کے بعد میری site سست کیوں ہو گئی؟

عام وجہ یہ ہوتی ہے کہ instance noeviction policy کے تحت مکمل بھر چکا ہے۔ Redis نئی writes مسترد کرتا ہے اور OOM command not allowed when used memory > 'maxmemory'. واپس کرتا ہے۔ اس کے نتیجے میں WordPress ہر value کے لیے database پر واپس جاتا ہے اور اس کے علاوہ Redis کا غیر ضروری round trip بھی برداشت کرتا ہے۔ redis-cli config get maxmemory-policy چیک کریں، allkeys-lru مقرر کریں، اور تصدیق کریں کہ maxmemory بہت کم نہیں ہے۔ دوسری عام وجوہات میں remote host پر موجود Redis server شامل ہے، جہاں ہر request کے سینکڑوں round trips کا مجموعی اثر نمایاں ہو جاتا ہے۔ ایک اور وجہ کئی megabytes پر مشتمل autoloaded options value ہے، جو ہر request پر connection کے ذریعے منتقل ہوتی ہے۔

کیا متعدد WordPress sites ایک Redis server شیئر کر سکتی ہیں؟

ہاں، لیکن احتیاط ضروری ہے۔ ہر site کو منفرد WP_REDIS_PREFIX دیں تاکہ key names آپس میں نہ ٹکرائیں، اور الگ WP_REDIS_DATABASE index استعمال کریں تاکہ ایک site کو flush کرنے سے دوسری site کا data خالی نہ ہو۔ تاہم memory مشترک رہتی ہے: maxmemory اور eviction پورے instance پر لاگو ہوتے ہیں، اس لیے مصروف site کسی کم استعمال ہونے والی site کی keys evict کر سکتی ہے۔ جن sites کو ایک دوسرے پر اثر انداز نہیں ہونا چاہیے، ان کے لیے اپنی limits کے ساتھ الگ Redis instances درکار ہیں۔

کیا wp-content/object-cache.php کو حذف کرنا محفوظ ہے؟

ہاں۔ یہ ایک drop-in ہے، WordPress core کا حصہ نہیں، اور اسے ہٹانے سے WordPress اپنے built-in per-request cache پر واپس آ جاتا ہے۔ site کام کرتی رہتی ہے، لیکن database queries زیادہ ہو جاتی ہیں۔ wp redis disable کو ترجیح دیں، کیونکہ یہ file کو صاف طریقے سے حذف کرتا ہے اور Object cache disabled. رپورٹ کرتا ہے۔ اگر Redis down ہو یا غلط رویہ دکھا رہا ہو اور آپ admin تک رسائی حاصل نہ کر سکیں، تو اسے دستی طور پر حذف کرنا درست ہنگامی اقدام ہے۔