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 چلائے بغیر اسے دوبارہ فراہم کرتی ہے۔ یہ 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 کو دوبارہ چلنے سے روکتی ہے جو پہلے ہی چل چکی ہو۔ Miss کے بعد پہلی request پوری لاگت ادا کرتی ہے، اس لیے unindexed query چلانے والا plugin ہر cache lifetime میں اسے ایک بار ضرور چلاتا ہے۔
پہلے درکار چیزیں
- ایک Linux VPS جس میں shell اور
sudoموجود ہو۔ کسی control panel کی ضرورت نہیں۔ - PHP-FPM کے ذریعے چلنے والا WordPress، مثلاً Ubuntu 24.04 پر LAMP stack۔
- اسی سرور پر WP-CLI۔ یہاں ہر مرحلے کا admin screen متبادل موجود ہے، لیکن shell والا طریقہ زیادہ تیز ہے۔
- PHP والی اسی مشین پر Redis۔ کم latency ہی اس کا بنیادی مقصد ہے، اور network hop یہ فائدہ ختم کر دیتا ہے۔
ذیل کے commands Ubuntu 24.04، PHP 8.3 اور www-data web user کے لیے لکھے گئے ہیں۔ اپنے سرور کے مطابق 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 pingredis-cli ping کو PONG کا جواب دینا چاہیے۔ اگر یہ Could not connect to Redis at 127.0.0.1:6379: Connection refused دکھائے تو server چل نہیں رہا، اس لیے آگے بڑھنے سے پہلے 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آخری check میں احتیاط کریں: php -m صرف command line PHP کے modules کی فہرست دکھاتا ہے، جبکہ FPM مختلف modules load کر سکتا ہے۔ فیصلہ کن check 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 چلا سکتا ہے۔ انٹرنیٹ پر exposed instances کو scanners چند گھنٹوں میں تلاش کر لیتے ہیں، اس لیے tuning سے پہلے network setting درست کریں۔
/etc/redis/redis.conf کھولیں اور ان lines کی تصدیق کریں:
bind 127.0.0.1 -::1
protected-mode yesپھر دیکھیں کہ حقیقت میں کون سا process listening کر رہا ہے، کیونکہ config 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 ایک ہی machine پر ہوں تو 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 start کے وقت موجود groups برقرار رکھتا ہے۔ اسی لیے فہرست میں restart شامل ہے۔ Socket کی تصدیق ہونے تک TCP enabled رکھیں، ورنہ ایک typo دونوں راستے بیک وقت بند کر سکتا ہے۔
Redis کو کتنی memory دینی چاہیے؟
یہ عدد اپنے server کی اصل صورتِ حال سے اخذ کریں۔ maxmemory کے بغیر Redis اس وقت تک بڑھتا رہتا ہے جب تک kernel کی memory ختم نہیں ہو جاتی اور OOM killer کسی process کو ختم نہیں کر دیتا۔ عموماً سب سے بڑا process ختم ہوتا ہے، اور WordPress server پر یہ اکثر MySQL ہوتا ہے۔ journalctl -k | grep -i "out of memory" اس واقعے کو بعد میں دکھاتا ہے، لیکن اس وقت site پہلے ہی down ہو چکی ہوتی ہے۔
کل RAM سے شروع کریں اور ضروری memory منہا کریں۔ MySQL یا MariaDB innodb_buffer_pool_size کے علاوہ ہر connection کے buffers کے لیے بھی memory reserve کرتا ہے۔ 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 چلانے کے لیے memory budget کی مثال
یہ مثال کے اعداد ہیں، آپ کے server کی پیمائش نہیں۔ ہر عدد کو اپنے server سے حاصل ہونے والی 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-lruredis-cli config set maxmemory 256mb یہ تبدیلی فوراً لاگو کرتا ہے، لیکن اگلے restart پر ختم ہو جاتی ہے۔ یہ وہی مسئلہ ہے جو صرف sysctl -w استعمال کرنے سے پیدا ہوتا ہے۔ file edit کریں، پھر sudo systemctl restart redis-server چلائیں، اور اس کے بعد value دوبارہ پڑھیں۔ ایک دوسری حد رکھنا بھی مفید ہے: systemd unit پر MemoryMax cap misconfigured Redis کو پورا server down کرنے سے روکتی ہے۔ اسے maxmemory سے زیادہ رکھیں، اس کے برابر کبھی نہ رکھیں، کیونکہ cgroup limit process کو ختم کرتی ہے، key کو evict نہیں کرتی۔ اگر Redis WordPress کے ساتھ ایک ہی container میں چلتا ہے تو یہی عدد آپ کی Compose file میں memory limits میں شامل کریں، اور یہی اصول database کو Docker میں یا host پر چلانے کے انتخاب پر بھی لاگو ہوتا ہے۔
اخراج کی پالیسی دانستہ طور پر منتخب کریں
نئی Redis تنصیب میں ڈیفالٹ پالیسی noeviction ہوتی ہے۔ اپنی پالیسی چیک کریں:
redis-cli config get maxmemory-policynoeviction کے تحت، مکمل instance مزید writes قبول نہیں کرتا اور یہ جواب دیتا ہے:
(error) OOM command not allowed when used memory > 'maxmemory'.یہ ایک سطری پیغام اس گائیڈ میں بیان کردہ بدترین failure mode ہے، کیونکہ site بند نہیں ہوتی۔ یہ سست ہو جاتی ہے۔ ہر cache write ناکام ہوتی ہے، اس لیے WordPress value کے لیے دوبارہ database سے رجوع کرتا ہے، پھر اگلی request پر اسے دوبارہ محفوظ کرنے کی کوشش کرتا ہے اور وہ بھی ناکام ہو جاتی ہے۔ اب site کو اپنے تمام اصل database کام کے علاوہ ہر key کے لیے Redis تک ایک round trip کی قیمت بھی ادا کرنا پڑتی ہے۔ WordPress admin میں کہیں یہ نہیں بتایا جاتا کہ ایسا ہو رہا ہے۔ یہ string PHP error log میں ظاہر ہوتی ہے، اس لیے جب cache شامل کرنے کے بعد site سست ہو جائے تو OOM command not allowed کے لیے grep کریں۔
allkeys-lru یہاں درست ڈیفالٹ ہے۔ memory کم ہونے پر Redis کم ترین حالیہ استعمال والی key خارج کر دیتا ہے۔ یہی object cache کی ضرورت ہے، کیونکہ اس میں موجود ہر value اس data کی copy ہوتی ہے جو اب بھی MySQL میں موجود ہے۔ ایک key ضائع ہونے سے ایک query کی لاگت آتی ہے۔ write سے انکار کرنے پر ہر request میں ہر query کی لاگت آتی ہے، جب تک کسی کو اس مسئلے کا علم نہ ہو جائے۔
اس کام کے لیے volatile-* policies سے گریز کریں۔ یہ صرف ان keys کو مدنظر رکھتی ہیں جن پر expiry مقرر ہو، اور Redis کی دستاویزات کے مطابق جب کسی key پر expiry نہ ہو تو یہ noeviction کی طرح عمل کرتی ہیں۔ WordPress زیادہ تر object cache entries کو TTL کے بغیر محفوظ کرتا ہے، اس لیے object cache پر volatile-lru بھر سکتا ہے اور writes سے انکار شروع کر سکتا ہے۔ اگر traffic بہت کم keys کو بار بار استعمال کرتا ہو تو allkeys-lfu ایک مناسب متبادل ہے، کیونکہ یہ حالیہ استعمال کے بجائے frequency کی بنیاد پر keys خارج کرتا ہے۔ ایک پالیسی دانستہ طور پر منتخب کریں اور اس کی وجہ تحریر کر دیں۔
پائیداری: وجہ موجود نہ ہو تو اسے بند رکھیں
پیکیج کے ساتھ آنے والا redis.conf، save 900 1 جیسی لائنوں کے ذریعے RDB snapshots فعال کرتا ہے اور append-only file کو بند رکھتا ہے۔ خالص object cache کے لیے snapshots کا کوئی فائدہ نہیں۔ تعریف کے مطابق یہ data دوبارہ تیار کیا جا سکتا ہے، اور بیس منٹ پرانی file سے restore کیا گیا cache پرانی 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 savePersistence صرف اسی وقت برقرار رکھیں جب اسی instance میں ایسی چیز موجود ہو جسے دوبارہ build نہیں کیا جا سکتا، مثلاً 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 میں لکھنے کی اجازت نہیں ہے۔ 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.phpPlugin remove کرنے سے drop-in remove نہیں ہوتا۔ پہلے 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 میں لازماً ختم کرتا ہے۔ allkeys-lru کے ساتھ اسے استعمال کرنے کی ضرورت نہیں۔ یہ اس وقت مفید ہے جب آپ یہ سخت حد مقرر کرنا چاہتے ہوں کہ cached value زیادہ سے زیادہ کتنی پرانی ہو سکتی ہے۔
ایک Redis، متعدد سائٹس: prefixes اور databases
Redis بطور ڈیفالٹ سولہ numbered databases فراہم کرتا ہے، اور ہر database کے اندر ایک flat keyspace ہوتا ہے۔ اگر دو WordPress installs کو بغیر prefix کے database 0 پر point کیا جائے تو وہ ایک ہی key names کو ایک ہی space میں لکھتے ہیں۔ اس طرح ایک site دوسری site کے options پڑھ کر انہیں serve کر سکتی ہے۔ ہر site کو اپنا prefix دیں۔
define( 'WP_REDIS_PREFIX', 'shopA_prod:' );
define( 'WP_REDIS_DATABASE', 1 );prefix key names کو الگ کرتا ہے۔ database index keyspaces کو الگ کرتا ہے، جو flush کے وقت اہم ہوتا ہے: ایک index خالی کرنے سے باقی index متاثر نہیں ہوتے۔ Plugin WP_REDIS_SELECTIVE_FLUSH کی دستاویز بھی فراہم کرتا ہے، جو پورے database کے بجائے صرف آپ کے prefix سے match کرنے والی keys delete کرتا ہے، لیکن اس کے لیے ان keys کو scan کرنا پڑتا ہے۔
prefixes اور indexes memory کو الگ نہیں کرتے۔ maxmemory اور eviction policy پورے instance پر لاگو ہوتے ہیں، اس لیے ایک مصروف site کسی خاموش site کی keys کو باہر نکال سکتی ہے، اور دونوں میں سے کوئی بھی اس کی اطلاع نہیں دیتا۔ جن sites کو ایک دوسرے پر اثرانداز نہیں ہونا چاہیے، ان کے لیے الگ Redis instances استعمال کریں۔ ہر instance کا اپنا socket اور اپنی limit ہونی چاہیے۔
production کے cache سے staging کو الگ رکھیں
Staging site عموماً production files اور database کی نقل ہوتی ہے۔ اس کا مطلب ہے کہ یہ wp-config.php کی بھی نقل ہے اور اسی prefix اور اسی database index کے ساتھ چلتی ہے۔ اگر اسے اسی Redis کی طرف point کیا جائے تو یہ staging values کے ساتھ production keys لکھتی ہے۔ Test price یا تبدیل شدہ option بغیر کسی deploy اور سراغ کے 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 سے تبدیل شدہ بتایا گیا ہے، اس لیے نیا نام استعمال کریں۔
اس پر بھروسا کرنے کے بجائے اس کی تصدیق کریں
plugin کی اپنی diagnostics سے آغاز کریں۔
wp redis statusسب سے اہم line 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:*' | headsite پر مختلف صفحات کھولتے وقت dbsize کا بڑھنا اس کا ثبوت ہے۔ valid drop-in کے باوجود صفر keys کا مطلب ہے کہ connection خاموشی سے ناکام ہو رہا ہے، یا prefix وہ نہیں ہے جو آپ سمجھ رہے ہیں۔
آخر میں دیکھیں کہ Redis آپ کے لیے کیا measure کرتا ہے۔
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 فراہم کرتی ہے۔ اسے دو احتیاطوں کے ساتھ سمجھیں۔ counters پورے instance کا احاطہ کرتے ہیں اور آخری restart کے بعد سے جمع ہوتے ہیں، اس لیے ان میں ہر وہ site اور application شامل ہوتی ہے جو اسے share کر رہی ہے۔ اس کے علاوہ، flush یا restart کے فوراً بعد ratio کا کوئی مطلب نہیں ہوتا، کیونکہ cache ابھی بھر رہی ہوتی ہے۔ اسے معمول کے traffic والے ایک دن تک چلنے دیں۔
اپنے number کا موازنہ کسی hosting company کی شائع کردہ hit rate یا query count سے نہ کریں۔ وہ ان کی sites اور ان کے plugin set کی عکاسی کرتے ہیں۔ اہم figure آپ کا اپنا ہے، جسے page cache کے ذریعے serve نہ ہونے والے کسی page پر پہلے اور بعد میں measure کیا جائے۔
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 کو سست کر دیتا ہے
غلط پالیسی کے ساتھ مکمل 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 لگے، تو آدھا سیکنڈ انتظار میں صرف ہوتا ہے، جو local socket کے ساتھ نہیں ہوتا۔ Redis کو اسی box پر رکھیں، یا sub-millisecond latency والے private network پر رکھیں۔
بہت بڑا 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 کے بعد کے چند منٹوں میں تمام requests misses ہوتی ہیں اور database پر مکمل کام دوبارہ ہوتا ہے۔ Traffic کم ہونے پر restart کریں۔ Object cache visitor page loads کے دوران wp-cron.php کو چلنے سے نہیں روکتا، اور یہ slow requests کا الگ سبب ہے: اسی موقع پر WP-Cron کو حقیقی system cron job پر منتقل کریں۔
صفائی
ایسی deploy کے بعد جس میں options یا theme code تبدیل ہوا ہو، wp cache flush چلائیں۔ اگر plugin update کے بعد drop-in خود update نہ ہوا ہو تو wp redis update-dropin چلائیں، کیونکہ نئے plugin کے ساتھ پرانے plugin version کا drop-in عجیب رویے کی حقیقی وجہ بن سکتا ہے۔ Live server کو redis-cli --stat کے ساتھ monitor کریں؛ یہ ہر سیکنڈ ایک سطر دکھاتا ہے۔ redis-cli monitor ہر command دکھاتا ہے اور مصروف instance پر CPU کے حقیقی وسائل استعمال کرتا ہے، اس لیے کسی مسئلے کو دوبارہ پیدا کرتے وقت اسے چند سیکنڈ کے لیے چلائیں، پھر روک دیں۔
ایک آخری اہم عدد redis-cli info clients کے ذریعے معلوم ہوتا ہے: یہ connected_clients رپورٹ کرتا ہے۔ PHP-FPM ہر worker کے لیے ایک connection برقرار رکھتا ہے، اس لیے یہ عدد آپ کے pm.max_children کے مطابق ہونا چاہیے، نہ کہ اس سے بہت زیادہ۔ اگر ایسا ہو تو کوئی چیز connections کھول رہی ہے اور انہیں بند نہیں کر رہی۔
FAQ
کیا Redis object cache چلانے کے بعد بھی page cache کی ضرورت ہے؟
ہاں، anonymous traffic کے لیے۔ page cache محفوظ شدہ HTML فراہم کرتا ہے اور PHP نہیں چلاتا، جو warm object cache کے ساتھ بھی WordPress چلانے سے ہمیشہ کم وسائل لیتا ہے۔ object cache ان requests کو سنبھالتا ہے جنہیں page cache کو skip کرنا پڑتا ہے: logged-in users، carts، checkout، اور wp-admin۔ shop یا membership site پر دونوں چلانا مفید ہے۔ ایسی site پر جہاں visitors کبھی log in نہیں کرتے، تقریباً سارا کام page cache ہی کرتا ہے۔
WordPress کے لیے Redis کو کتنی memory دینی چاہیے؟
کسی مقررہ عدد کی نقل کرنے کے بجائے اپنے server کی بنیاد پر مقدار نکالیں۔ کل 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. report کرتا ہے۔ اگر Redis down ہو یا غلط برتاؤ کر رہا ہو اور آپ admin تک رسائی حاصل نہ کر سکیں، تو اسے دستی طور پر حذف کرنا مناسب ہنگامی اقدام ہے۔