การใช้ Redis เป็น Cache
ในบทที่แล้ว เราได้เรียนรู้เกี่ยวกับการ Caching เพื่อเพิ่มประสิทธิภาพ API ของเรา โดยได้ยกตัวอย่างการใช้ File-Based Caching ไปแล้ว ในบทนี้ เราจะมาดูอีกทางเลือกหนึ่งที่ทรงพลังกว่า นั่นคือการใช้ Redis เป็น Cache
Redis คืออะไร?
Redis (Remote Dictionary Server) เป็น In-Memory Data Structure Store ที่ใช้เป็นฐานข้อมูล, Cache และ Message Broker ได้ Redis มีประสิทธิภาพสูงมากเนื่องจากข้อมูลทั้งหมดถูกเก็บไว้ในหน่วยความจำ (RAM) ทำให้การอ่านและเขียนข้อมูลทำได้อย่างรวดเร็ว นอกจากนี้ Redis ยังรองรับ Data Structure ที่หลากหลาย เช่น Strings, Hashes, Lists, Sets, Sorted Sets, Bitmaps, HyperLogLogs และ Geospatial indexes ทำให้ Redis สามารถนำไปใช้ในงานที่หลากหลายได้
ทำไมต้องใช้ Redis เป็น Cache?
- ความเร็ว: Redis ทำงานในหน่วยความจำ ทำให้การเข้าถึงข้อมูลเร็วกว่าการอ่านจากดิสก์อย่างมาก (เช่น File-Based Cache หรือฐานข้อมูล)
- Data Structures ที่หลากหลาย: Redis มี Data Structures ที่หลากหลาย ทำให้เราสามารถจัดเก็บข้อมูลในรูปแบบที่เหมาะสมกับการใช้งานได้
- Persistence: Redis สามารถกำหนดให้บันทึกข้อมูลลงดิสก์ได้ ทำให้ข้อมูลไม่สูญหายเมื่อ Server Restart
- Support ที่ดี: Redis เป็น Open Source Project ที่มี Community ขนาดใหญ่ และมี Library ให้ใช้งานในหลายภาษา รวมถึง PHP
การติดตั้ง Redis
ก่อนที่เราจะเริ่มใช้งาน Redis ได้ เราต้องทำการติดตั้ง Redis Server ก่อน วิธีการติดตั้งจะแตกต่างกันไปขึ้นอยู่กับระบบปฏิบัติการที่คุณใช้งาน
บน Ubuntu/Debian:
sudo apt update
sudo apt install redis-server
บน macOS (ใช้ Homebrew):
brew install redis
brew services start redis
บน Windows:
คุณสามารถดาวน์โหลด Redis ได้จาก https://github.com/microsoftarchive/redis/releases และทำการติดตั้งตามขั้นตอนที่ระบุ
หลังจากติดตั้ง Redis Server แล้ว คุณสามารถตรวจสอบว่า Redis ทำงานได้ถูกต้องหรือไม่ โดยใช้ command line tool ชื่อ redis-cli
redis-cli ping
ถ้า Redis Server ทำงานได้ถูกต้อง คุณจะได้รับคำตอบเป็น PONG
การใช้งาน Redis ใน PHP
ในการใช้งาน Redis ใน PHP เราต้องติดตั้ง Redis extension ก่อน
ติดตั้ง Redis extension สำหรับ PHP:
คุณสามารถติดตั้ง Redis extension ได้โดยใช้ package manager ของ PHP (เช่น Composer หรือ PECL)
ใช้ PECL:
pecl install redis
หลังจากติดตั้งแล้ว อย่าลืมเพิ่ม extension=redis.so ลงในไฟล์ php.ini ของคุณ
ใช้ Composer:
composer require predis/predis
Composer จะติดตั้ง Predis ซึ่งเป็น PHP Client Library สำหรับ Redis
ตัวอย่างการใช้งาน Redis ใน PHP (ใช้ Predis):
<?php
require 'vendor/autoload.php'; // ถ้าใช้ Composer
use Predis\Client;
// กำหนดค่าการเชื่อมต่อ Redis
$redis = new Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
]);
try {
$redis->ping(); // ตรวจสอบการเชื่อมต่อ
echo "Connected to Redis successfully!\n";
} catch (Exception $e) {
die("Couldn't connect to Redis: " . $e->getMessage());
}
// ฟังก์ชันสำหรับดึงข้อมูลจากแหล่งข้อมูลหลัก (เช่น ฐานข้อมูล)
function fetchDataFromSource($id) {
// จำลองการดึงข้อมูลจากฐานข้อมูล
sleep(1); // Simulate slow database query
return "Data from source for ID: " . $id;
}
// ฟังก์ชันสำหรับดึงข้อมูลจาก Cache หรือแหล่งข้อมูลหลัก
function getData($id) {
global $redis;
$cacheKey = 'data:' . $id;
// ลองดึงข้อมูลจาก Cache
$cachedData = $redis->get($cacheKey);
if ($cachedData) {
echo "Data retrieved from cache!\n";
return $cachedData;
} else {
echo "Data not found in cache. Fetching from source...\n";
// ดึงข้อมูลจากแหล่งข้อมูลหลัก
$data = fetchDataFromSource($id);
// บันทึกข้อมูลลงใน Cache
$redis->set($cacheKey, $data);
$redis->expire($cacheKey, 3600); // กำหนด TTL (Time To Live) เป็น 1 ชั่วโมง
return $data;
}
}
// ทดสอบการใช้งาน
echo getData(123) . "\n"; // ครั้งแรกจะดึงข้อมูลจากแหล่งข้อมูลหลักและบันทึกลง Cache
echo getData(123) . "\n"; // ครั้งที่สองจะดึงข้อมูลจาก Cache
?>
คำอธิบาย Code:
- เราสร้าง instance ของ
Predis\Clientเพื่อเชื่อมต่อกับ Redis Server - เราสร้างฟังก์ชัน
getDataเพื่อดึงข้อมูล โดยจะตรวจสอบก่อนว่ามีข้อมูลใน Cache หรือไม่ ถ้ามีก็จะดึงข้อมูลจาก Cache ถ้าไม่มีก็จะดึงข้อมูลจากแหล่งข้อมูลหลักและบันทึกลง Cache - เราใช้
$redis->get($cacheKey)เพื่อดึงข้อมูลจาก Cache โดยใช้$cacheKeyเป็น Key - เราใช้
$redis->set($cacheKey, $data)เพื่อบันทึกข้อมูลลงใน Cache โดยใช้$cacheKeyเป็น Key และ$dataเป็น Value - เราใช้
$redis->expire($cacheKey, 3600)เพื่อกำหนด TTL (Time To Live) ให้กับ Cache Key ซึ่งในที่นี้คือ 1 ชั่วโมง (3600 วินาที) หลังจาก TTL หมดอายุ Redis จะลบ Key นั้นออกจาก Cache
เหตุผลเชิงออกแบบ:
- Cache Key Naming: การตั้งชื่อ Cache Key ที่ดีมีความสำคัญมาก เราควรตั้งชื่อ Key ให้สื่อความหมายและมีความเฉพาะเจาะจง เพื่อหลีกเลี่ยงการชนกันของ Key และทำให้ง่ายต่อการ Debug
- TTL (Time To Live): การกำหนด TTL ที่เหมาะสมมีความสำคัญเช่นกัน ถ้า TTL สั้นเกินไป เราจะต้องดึงข้อมูลจากแหล่งข้อมูลหลักบ่อยเกินไป ทำให้ประสิทธิภาพไม่ดีเท่าที่ควร แต่ถ้า TTL ยาวเกินไป ข้อมูลใน Cache อาจไม่เป็นปัจจุบัน
- Cache Invalidation: เมื่อข้อมูลในแหล่งข้อมูลหลักมีการเปลี่ยนแปลง เราต้องทำการ Invalidated Cache เพื่อให้ Cache เป็นปัจจุบัน วิธีการ Invalidated Cache มีหลายวิธี เช่น การลบ Cache Key ที่เกี่ยวข้อง หรือการ Update Cache Key ด้วยข้อมูลใหม่
สรุป
Redis เป็นเครื่องมือที่ทรงพลังสำหรับการ Caching API ของเรา ด้วยความเร็วและ Data Structures ที่หลากหลาย ทำให้ Redis สามารถช่วยเพิ่มประสิทธิภาพ API ของเราได้อย่างมาก อย่างไรก็ตาม การใช้งาน Redis อย่างถูกต้องและมีประสิทธิภาพต้องอาศัยความเข้าใจในหลักการ Caching และการออกแบบ Cache Key ที่ดี ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับการสร้าง Custom Exception เพื่อจัดการ Error ใน API ของเราอย่างมีประสิทธิภาพ