본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การใช้งาน Redis Cache กับ PHP: ตัวอย่างการ Cache ข้อมูลจากฐานข้อมูล

บทความนี้สาธิตวิธีการใช้ Redis Cache กับ PHP เพื่อเพิ่มประสิทธิภาพในการดึงข้อมูลจากฐานข้อมูล MySQL โดยครอบคลุมตั้งแต่การติดตั้ง predis/predis library, การเชื่อม...

การใช้งาน Redis Cache กับ PHP: ตัวอย่างการ Cache ข้อมูลจากฐานข้อมูล

ในบทความที่แล้ว เราได้เรียนรู้วิธีการติดตั้งและตั้งค่า Redis Server บน Ubuntu ในบทความนี้ เราจะมาดูวิธีการนำ Redis Cache มาใช้งานร่วมกับ PHP เพื่อเพิ่มประสิทธิภาพในการเข้าถึงข้อมูลจากฐานข้อมูล MySQL โดยเราจะทำการ Cache ผลลัพธ์ของ query เพื่อลดภาระของ database server และเพิ่มความเร็วในการตอบสนองของแอปพลิเคชัน

ขั้นตอนที่ 1: การติดตั้ง predis/predis library

ในการใช้งาน Redis กับ PHP เราจำเป็นต้องมี library ที่ช่วยในการเชื่อมต่อและสื่อสารกับ Redis Server Library ที่นิยมใช้กันคือ predis/predis ซึ่งสามารถติดตั้งได้ง่ายๆ ผ่าน Composer:

composer require predis/predis

หลังจากรันคำสั่งนี้ Composer จะทำการดาวน์โหลดและติดตั้ง predis/predis library ลงใน project ของเรา

ขั้นตอนที่ 2: การเชื่อมต่อกับ Redis Server

เมื่อติดตั้ง library เรียบร้อยแล้ว เราสามารถเริ่มเขียนโค้ด PHP เพื่อเชื่อมต่อกับ Redis Server ได้ ตัวอย่างเช่น:

<?php

require 'vendor/autoload.php'; // โหลด Composer autoloader

try {
    $redis = new Predis\Client([
        'scheme' => 'tcp',
        'host'   => '127.0.0.1', // หรือ IP address ของ Redis server
        'port'   => 6379,        // default port
        'password' => 'your_redis_password' // หากมีการตั้ง password ใน redis.conf
    ]);

    $redis->ping(); // ตรวจสอบการเชื่อมต่อ

    echo "Connected to Redis successfully!\n";

} catch (Exception $e) {
    echo "Couldn't connect to Redis: " . $e->getMessage() . "\n";
}

?>

คำอธิบาย:

  • require 'vendor/autoload.php';: โหลด autoloader ของ Composer เพื่อให้สามารถใช้งาน predis/predis library ได้
  • new Predis\Client([...]);: สร้าง instance ของ Predis client โดยระบุ scheme (tcp), host, port และ password (ถ้ามี)
  • $redis->ping();: ส่งคำสั่ง PING ไปยัง Redis Server เพื่อตรวจสอบว่าการเชื่อมต่อสำเร็จหรือไม่
  • try...catch: ใช้เพื่อดักจับ exception ที่อาจเกิดขึ้นระหว่างการเชื่อมต่อ เช่น Redis Server ไม่พร้อมใช้งาน หรือ password ไม่ถูกต้อง

ข้อผิดพลาดที่พบบ่อย:

  • "Could not connect to Redis": ตรวจสอบให้แน่ใจว่า Redis Server กำลังทำงานอยู่ และ host, port, password ถูกต้อง
  • "php_network_getaddresses: getaddrinfo failed": ตรวจสอบว่า host name ที่ระบุสามารถ resolve ได้หรือไม่ (เช่น ในกรณีที่ใช้ domain name)

ขั้นตอนที่ 3: การ get/set ค่าใน Redis

เมื่อเชื่อมต่อกับ Redis Server ได้แล้ว เราสามารถใช้คำสั่ง get และ set เพื่ออ่านและเขียนข้อมูลใน Redis ได้ ตัวอย่างเช่น:

<?php

require 'vendor/autoload.php';

$redis = new Predis\Client([
    'scheme' => 'tcp',
    'host'   => '127.0.0.1',
    'port'   => 6379,
    'password' => 'your_redis_password'
]);

// Set ค่า
$redis->set('mykey', 'Hello Redis!');

// Get ค่า
$value = $redis->get('mykey');

echo "Value from Redis: " . $value . "\n"; // Output: Value from Redis: Hello Redis!

// Check if key exists
if ($redis->exists('mykey')) {
    echo "Key 'mykey' exists in Redis.\n";
} else {
    echo "Key 'mykey' does not exist in Redis.\n";
}

?>

คำอธิบาย:

  • $redis->set('mykey', 'Hello Redis!');: กำหนดค่า 'Hello Redis!' ให้กับ key ที่ชื่อ 'mykey'
  • $redis->get('mykey');: อ่านค่าของ key 'mykey'
  • $redis->exists('mykey');: ตรวจสอบว่า key 'mykey' มีอยู่ใน Redis หรือไม่

ขั้นตอนที่ 4: การกำหนด TTL (Time-To-Live)

TTL คือระยะเวลาที่ข้อมูลใน Redis จะถูกเก็บไว้ หลังจาก TTL หมดอายุ ข้อมูลนั้นจะถูกลบออกจาก Redis โดยอัตโนมัติ การกำหนด TTL มีประโยชน์ในการจัดการ cache data ที่มีการเปลี่ยนแปลงบ่อย ตัวอย่างเช่น:

<?php

require 'vendor/autoload.php';

$redis = new Predis\Client([
    'scheme' => 'tcp',
    'host'   => '127.0.0.1',
    'port'   => 6379,
    'password' => 'your_redis_password'
]);

// Set ค่าพร้อมกำหนด TTL เป็น 60 วินาที
$redis->setex('mykey', 60, 'This data will expire in 60 seconds.');

// Get ค่า
$value = $redis->get('mykey');

echo "Value from Redis: " . $value . "\n";

sleep(61); // Wait for 61 seconds

$value = $redis->get('mykey');

echo "Value from Redis after 61 seconds: " . $value . "\n"; // Output: Value from Redis after 61 seconds: (null)

?>

คำอธิบาย:

  • $redis->setex('mykey', 60, 'This data will expire in 60 seconds.');: กำหนดค่าพร้อม TTL โดย setex รับพารามิเตอร์ 3 ตัว: key, TTL (วินาที), และ value
  • หลังจาก 60 วินาที ข้อมูลที่เก็บไว้ใน key 'mykey' จะถูกลบออกจาก Redis ทำให้การเรียก $redis->get('mykey') คืนค่า null

ขั้นตอนที่ 5: การ cache query results

ตอนนี้เรามาดูตัวอย่างการ cache ผลลัพธ์ของ query จากฐานข้อมูล MySQL โดยสมมติว่าเรามีตาราง users ที่มี column id และ name เราต้องการ cache ข้อมูลผู้ใช้ที่มี id เท่ากับ 1

<?php

require 'vendor/autoload.php';

// Database connection parameters
$dbHost = 'localhost';
$dbName = 'mydatabase';
$dbUser = 'myuser';
$dbPass = 'mypassword';

// Redis connection parameters
$redisHost = '127.0.0.1';
$redisPort = 6379;
$redisPassword = 'your_redis_password';

try {
    // Connect to Redis
    $redis = new Predis\Client([
        'scheme' => 'tcp',
        'host'   => $redisHost,
        'port'   => $redisPort,
        'password' => $redisPassword
    ]);

    // Connect to MySQL
    $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName", $dbUser, $dbPass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $userId = 1;
    $cacheKey = 'user:' . $userId;

    // Try to get data from cache
    $cachedData = $redis->get($cacheKey);

    if ($cachedData) {
        // Data found in cache
        $user = json_decode($cachedData, true);
        echo "Data retrieved from cache:\n";
        print_r($user);
    } else {
        // Data not found in cache, fetch from database
        $stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
        $stmt->bindParam(':id', $userId);
        $stmt->execute();
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user) {
            // Store data in cache with a TTL of 300 seconds (5 minutes)
            $redis->setex($cacheKey, 300, json_encode($user));
            echo "Data retrieved from database and stored in cache:\n";
            print_r($user);
        } else {
            echo "User not found in database.\n";
        }
    }

} catch (Exception $e) {
    echo "Error: " . $e->getMessage() . "\n";
}

?>

คำอธิบาย:

  • เชื่อมต่อกับทั้ง Redis Server และ MySQL database
  • กำหนด $cacheKey โดยใช้ prefix 'user:' ตามด้วย user ID เพื่อให้ง่ายต่อการจัดการ cache data
  • พยายามอ่านข้อมูลจาก cache โดยใช้ $redis->get($cacheKey)
  • ถ้าข้อมูลอยู่ใน cache ($cachedData ไม่เป็น null) ให้ decode ข้อมูลจาก JSON และแสดงผล
  • ถ้าข้อมูลไม่อยู่ใน cache ให้ query จาก database, encode ข้อมูลเป็น JSON, และเก็บไว้ใน cache ด้วย TTL 300 วินาที

กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย:

  • Cache Miss: ในครั้งแรกที่เรียกใช้ script ข้อมูลจะยังไม่อยู่ใน cache ทำให้ต้อง query จาก database
  • Data Inconsistency: ถ้าข้อมูลใน database มีการเปลี่ยนแปลง แต่ cache ยังคงเก็บข้อมูลเก่าอยู่ จะทำให้เกิด data inconsistency แก้ไขได้โดยใช้ cache invalidation strategies ซึ่งจะกล่าวถึงในบทความถัดไป
  • Serialization: การ serialize ข้อมูลเป็น JSON ก่อนเก็บใน Redis เป็นวิธีที่ง่ายและสะดวก แต่มี overhead ในการ encode/decode หากต้องการประสิทธิภาพที่สูงขึ้น อาจพิจารณาใช้ serialization format อื่นๆ เช่น MessagePack หรือ Protocol Buffers

ในบทความนี้ เราได้เรียนรู้วิธีการใช้งาน Redis Cache ร่วมกับ PHP เพื่อเพิ่มประสิทธิภาพในการเข้าถึงข้อมูลจากฐานข้อมูล MySQL เราได้เห็นตัวอย่างการเชื่อมต่อกับ Redis Server, การ get/set ค่า, การกำหนด TTL, และการ cache query results ในบทความถัดไป เราจะมาเรียนรู้เกี่ยวกับ Cache Invalidation Strategies ซึ่งเป็นแนวทางการจัดการ cache ที่มีประสิทธิภาพ เพื่อให้มั่นใจว่าข้อมูลใน cache เป็นข้อมูลที่ถูกต้องและทันสมัยอยู่เสมอ

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기