ติดตั้ง Memcached บน VPS เร่งความเร็ว PHP และ Database
Memcached คือ in-memory key-value store ที่ใช้ cache ผลลัพธ์จาก database หรือ computation ที่ใช้เวลานาน ไว้ใน RAM แทน ครั้งถัดไปที่ request ข้อมูลเดิมจะตอบได้ในไม่กี่ microsecond แทนที่จะ query database อีกรอบ เหมาะกับ WordPress, Laravel, CodeIgniter และ app ที่มี read-heavy workload
ติดตั้ง Memcached บน Ubuntu/Debian
# ติดตั้ง Memcached daemon + PHP extension
apt update
apt install memcached libmemcached-tools -y
# ติดตั้ง PHP extension ตาม version ที่ใช้
apt install php8.2-memcached -y
# หรือ php8.1-memcached / php8.0-memcached
# เปิดใช้งาน
systemctl enable --now memcached
# ตรวจสอบสถานะ
systemctl status memcached
ตั้งค่า Memcached
nano /etc/memcached.conf
# ฟัง localhost เท่านั้น (ห้าม expose ออก internet)
-l 127.0.0.1
# จำนวน RAM ที่ให้ใช้ (MB) — แนะนำ 10-20% ของ RAM ทั้งหมด
-m 256
# Port เริ่มต้น
-p 11211
# จำนวน connection พร้อมกัน
-c 1024
# Thread
-t 4
systemctl restart memcached
# ทดสอบด้วย telnet
echo -e "stats\nquit" | nc 127.0.0.1 11211 | head -20
ใช้ Memcached ใน PHP
<?php
$mc = new Memcached();
$mc->addServer('127.0.0.1', 11211);
// บันทึกค่า (TTL = 3600 วินาที = 1 ชั่วโมง)
$mc->set('user_100', ['name' => 'Alice', 'email' => '[email protected]'], 3600);
// อ่านค่า
$user = $mc->get('user_100');
if ($user === false) {
// ไม่มีใน cache → query DB
$user = $db->query("SELECT * FROM users WHERE id = 100")->fetch();
$mc->set('user_100', $user, 3600);
}
// ลบ cache entry
$mc->delete('user_100');
// ล้างทั้งหมด (ระวัง!)
$mc->flush();
Cache DB Query Result แบบ Pattern ที่นิยม
<?php
function getCachedQuery(Memcached $mc, PDO $db, string $key, string $sql, array $params = [], int $ttl = 300): array
{
$result = $mc->get($key);
if ($mc->getResultCode() === Memcached::RES_NOTFOUND) {
$stmt = $db->prepare($sql);
$stmt->execute($params);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$mc->set($key, $result, $ttl);
}
return $result ?: [];
}
// ใช้งาน
$products = getCachedQuery(
$mc, $db,
'products_featured',
'SELECT * FROM products WHERE featured = 1 ORDER BY id DESC LIMIT 20',
[],
600 // cache 10 นาที
);
เปิดใช้ Memcached ใน WordPress
ติดตั้ง plugin W3 Total Cache หรือ WP Super Cache แล้วเลือก Object Cache = Memcached หรือใช้ drop-in ตรงเลย:
# วิธีที่ 1: ใช้ drop-in จาก WP (ฟรี ไม่ต้อง plugin)
# สร้าง wp-content/object-cache.php
# มีหลาย project ให้ใช้ เช่น memcached-redux
# วิธีที่ 2: ใน wp-config.php เพิ่ม
define('WP_CACHE', true);
define('MEMCACHE_HOST', '127.0.0.1');
define('MEMCACHE_PORT', 11211);
ดู Stats การใช้งาน
# Stats ทั่วไป
echo "stats" | nc 127.0.0.1 11211
# ดู hit rate — ควรสูงกว่า 80% จึงจะคุ้มค่า
echo "stats" | nc 127.0.0.1 11211 | grep -E "get_hits|get_misses"
# ด้วย memcstat tool
memcstat --servers=127.0.0.1:11211
Memcached vs Redis เลือกอะไร?
- Memcached: เร็วกว่าเล็กน้อยสำหรับ simple string cache, multi-threaded, ใช้ RAM น้อยกว่า
- Redis: รองรับ data structure หลากหลาย (list, hash, set), persistence, pub/sub, Lua scripting, cluster mode
- ถ้าต้องการแค่ object cache / query cache → Memcached เพียงพอ
- ถ้าต้องการ session store, queue, rate limiting → Redis ดีกว่า
Memcached ติดตั้งง่าย ทำงานเร็ว และลด load บน database ได้อย่างเห็นได้ชัด โดยเฉพาะเว็บ WordPress หรือ PHP app ที่ query ข้อมูลเดิมซ้ำๆ กุญแจสำคัญคือออกแบบ cache key ให้ดี และตั้ง TTL ที่เหมาะสมเพื่อไม่ให้ข้อมูลเก่าเกินไป
ตรวจสอบว่า Memcached ทำงานถูกต้อง
# ตรวจสอบสถานะ service
systemctl status memcached
# ทดสอบ connection และดู stats
echo "stats" | nc 127.0.0.1 11211 | head -20
# ดู hit rate (ควร > 80%)
echo "stats" | nc 127.0.0.1 11211 | grep -E "get_hits|get_misses"
# hit_rate = get_hits / (get_hits + get_misses) * 100
# ใช้ memcstat tool
memcstat --servers=127.0.0.1:11211
แก้ปัญหาที่พบบ่อย
Error: "Connection refused" เมื่อ connect port 11211
เกิดจาก Memcached ไม่ได้รัน หรือ bind ผิด address ตรวจสอบด้วย:
systemctl status memcached
# ถ้าไม่รัน ให้ start
systemctl start memcached
# ตรวจสอบว่า bind ที่ 127.0.0.1
grep "^-l" /etc/memcached.conf
# ควรแสดง: -l 127.0.0.1
Error: PHP ไม่เจอ Memcached extension ("Class 'Memcached' not found")
ต้องติดตั้ง PHP extension และ enable ให้ตรงกับ PHP version ที่ใช้งาน:
# ตรวจสอบ PHP version ปัจจุบัน
php -v
# ติดตั้ง extension ให้ตรง version
apt install php8.2-memcached -y # หรือ php8.1-memcached
# Reload PHP-FPM
systemctl reload php8.2-fpm
# ตรวจสอบว่า extension โหลดแล้ว
php -m | grep -i memcached
Error: Hit rate ต่ำ — Memcached ไม่ช่วยอะไร
อาจเกิดจาก TTL สั้นเกินไป หรือ cache key ไม่ consistent ทำให้ miss ทุกครั้ง ตรวจสอบ:
# ดู evictions (ถ้าสูง แปลว่า RAM น้อยเกินไป)
echo "stats" | nc 127.0.0.1 11211 | grep evictions
# ดูจำนวน item ที่ cache อยู่
echo "stats" | nc 127.0.0.1 11211 | grep curr_items
# ถ้า evictions สูง ให้เพิ่ม -m ใน /etc/memcached.conf
Error: "SERVER_ERROR object too large for cache"
ค่าที่จะ store ใหญ่เกิน 1 MB (ค่า default) ต้องเพิ่ม item size limit:
# เพิ่มใน /etc/memcached.conf
-I 10m # ขยาย max item size เป็น 10 MB
systemctl restart memcached
Error: WordPress Object Cache ไม่ทำงาน
drop-in file ต้องอยู่ใน wp-content/ และ PHP extension ต้องโหลดก่อน WordPress จะใช้ได้:
# ตรวจว่ามี object-cache.php อยู่
ls /var/www/html/wp-content/object-cache.php
# ตรวจว่า wp-config.php มี WP_CACHE
grep "WP_CACHE" /var/www/html/wp-config.php
# ควรแสดง: define('WP_CACHE', true);
คำถามที่พบบ่อย
TTL ควรตั้งเท่าไหร่?
ขึ้นอยู่กับว่าข้อมูลเปลี่ยนบ่อยแค่ไหน: ข้อมูล product/category ที่แทบไม่เปลี่ยน → 1-24 ชั่วโมง, ข้อมูล user-specific → 5-15 นาที, ผลการ query ที่ update รายชั่วโมง → 30-60 นาที ถ้าไม่แน่ใจให้เริ่มที่ 300 วินาที แล้วค่อยปรับตาม hit rate ที่เห็น
ต้องให้ RAM เท่าไหร่กับ Memcached?
แนะนำ 10-25% ของ RAM ทั้งหมด สำหรับ VPS 2GB ให้ 256-512MB (-m 256 หรือ -m 512) ดู stats ว่ามี evictions บ่อยไหม ถ้ามีให้เพิ่ม -m หรือลด TTL เพื่อให้ item เก่าหายเร็วขึ้น
Memcached กับ Redis เลือกตัวไหนสำหรับ WordPress?
ทั้งสองใช้ได้ดีสำหรับ WordPress Object Cache แต่ Redis มีข้อได้เปรียบตรง persistence (ข้อมูลไม่หายเมื่อ restart) และ data structure ที่หลากหลายกว่า ถ้า server มี RAM เพียงพอและต้องการ session store ด้วย เลือก Redis ถ้าต้องการแค่ query/object cache แบบง่ายและ RAM จำกัด Memcached ก็เพียงพอ