Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

Redis สำหรับ PHP: คู่มือปฏิบัติการสำหรับแคชในหน่วยความจำ

Redis คืออะไร?

Redis เป็นที่เก็บข้อมูล (data store) ที่จัดเก็บข้อมูลหลักในหน่วยความจำ (in-memory) ทำให้เร็วกว่าฐานข้อมูลแบบดั้งเดิมที่เก็บข้อมูลบนดิสก์อย่างมาก เนื่องจากความเร็วนี้ Redis มักนำมาใช้เป็นเครื่องมือแคช (caching)

Redis จัดเก็บข้อมูลในรูปแบบคีย์-ค่า (key-value) รองรับชนิดข้อมูลหลากหลาย ไม่เหมือนฐานข้อมูลแบบดั้งเดิมที่ใช้เอกสารหรือแถว สามารถนึกภาพ Redis ได้เหมือนออบเจ็กต์ JSON ขนาดใหญ่ที่ทุกอย่างเป็นคีย์-ค่า ทำให้อาจไม่เหมาะสำหรับข้อมูลที่มีโครงสร้างซับซ้อน

Redis ยังสามารถใช้เป็นฐานข้อมูลได้ เนื่องจากมีความสามารถเขียนข้อมูลลงดิสก์เพื่อความคงทน (persistence) สามารถกำหนดให้บันทึกข้อมูลเป็นระยะหรือหลังทุกคำสั่ง หากไม่กำหนด persistence ข้อมูลจะหายไปเมื่อระบบล้ม

Redis ได้รับความนิยมในระบบ production และถูกใช้โดยบริษัทใหญ่อย่าง Twitter, GitHub, Snapchat และ Stack Overflow

กรณีการใช้งานที่เหมาะสม

  • รหัสผ่านครั้งเดียว (OTP): ใช้ได้ครั้งเดียว มีอายุสั้น Redis ตั้งวันหมดอายุได้ จึงเก็บ OTP ได้ปลอดภัยโดยไม่ต้องกังวลการลบ
  • ทรัพยากรที่เข้าถึงบ่อย: ข้อมูลที่เปลี่ยนแปลงน้อยแต่ถูกเข้าถึงมาก ใช้ Redis ลดเวลาคิวรี่ฐานข้อมูลหรือเรียกบริการภายนอก
  • คิวรี่หนัก: คิวรี่ที่ใช้เวลานานและผลลัพธ์ไม่เปลี่ยนบ่อย เก็บผลลัพธ์ไว้ใน Redis เพื่อลดเวลาประมวลผล

วิธีติดตั้ง Redis

ติดตั้ง Redis ได้ในทุกระบบปฏิบัติการ คำแนะนำสำหรับ macOS, WSL และ Linux:

macOS

brew install redis

เริ่ม Redis:

redis-server

Windows Subsystem for Linux และ Linux

Redis รองรับ Windows โดยตรงไม่เต็มที่ ให้ใช้ WSL เพื่อสภาพแวดล้อม Linux

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /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-get update
sudo apt-get install redis

เริ่ม Redis:

sudo service redis-server start

ทดสอบการติดตั้ง:

redis-cli ping

ควรได้ผลลัพธ์ PONG

คำสั่งพื้นฐานของ Redis

ใช้ redis-cli เพื่อเข้าสู่สภาพแวดล้อม REPL

กำหนดข้อมูล (SET)

SET username Zubs

ดึงข้อมูล (GET)

GET username

ลบข้อมูล (DEL)

DEL username

ตรวจสอบความมีอยู่ (EXISTS)

คืนค่า 0 หากไม่มีคีย์, 1 หากมี

EXISTS username

ตั้งเวลาหมดอายุ (TTL)

ใช้ SETEX เพื่อกำหนดอายุข้อมูล:

SETEX key seconds value

ตรวจสอบเวลาที่เหลือด้วย TTL:

  • -1: ไม่มีวันหมดอายุ (เก็บถาวร)
  • -2: คีย์ไม่มีอยู่
  • จำนวนวินาที: เวลาที่เหลือ

เพิ่มวันหมดอายุให้คีย์ที่มีอยู่แล้วด้วย EXPIRE:

SET age 26
EXPIRE age 20

สร้างแอปพลิเคชัน PHP ใช้ Redis แคช

สร้างเว็บแอปพลิเคชันง่ายๆ ที่ดึงข้อมูลรูปภาพจาก JSONPlaceholder และใช้ Redis แคชเพื่อเร่งการตอบสนอง

สร้างโปรเจกต์ PHP ด้วย Composer

composer init -q

สร้างโฟลเดอร์ public และไฟล์ index.php เริ่มเซิร์ฟเวอร์:

php -S localhost:8080

ติดตั้ง Router และ HTTP Client

composer require altorouter/altorouter guzzlehttp/guzzle

อัปเดต index.php เพื่อจัดการเส้นทาง /photos และ /photos/[i:id] เรียก JSONPlaceholder โดยตรง (ก่อนแคช)

ติดตั้งและใช้งาน Redis ใน PHP

ติดตั้ง PHP Redis extension:

pecl install redis

เชื่อมต่อ Redis ใน PHP:

$redis = new Redis();
$redis->connect('127.0.0.1');

แคชข้อมูลด้วย Redis

เก็บข้อมูล JSON จาก JSONPlaceholder พร้อมตั้งเวลาหมดอายุ 1 ชั่วโมง (3600 วินาที):

$response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos');
$redis->setex('photos', 3600, $response->getBody()->getContents());

ปรับปรุงเส้นทาง /photos ให้ตรวจสอบแคชก่อน:

$router->map('GET', '/photos', function () use ($client, $redis) {
    if (!$redis->exists('photos')) {
        $response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos');
        $redis->setex('photos', 3600, $response->getBody()->getContents());
    }
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['data' => json_decode($redis->get('photos'))]);
});

ผลลัพธ์: เวลาตอบสนองเฉลี่ยลดจาก ~1400ms เหลือ ~20ms (เร็วกว่า 50 เท่า)

ปรับเส้นทาง /photos/id เช่นกัน:

$router->map('GET', '/photos/[i:id]', function (int $id) use ($client, $redis) {
    if (!$redis->exists('photos:' . $id)) {
        $response = $client->request('GET', 'https://jsonplaceholder.typicode.com/photos/' . $id);
        $redis->setex('photos:' . $id, 3600, $response->getBody()->getContents());
    }
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['data' => json_decode($redis->get('photos:' . $id))]);
});

เวลาตอบสนองลดจาก ~900ms เหลือ < 5ms (เร็วกว่า 45 เท่า)

สรุป

Redis เป็นเครื่องมืออันทรงพลังสำหรับแคชในหน่วยความจำ ช่วยเพิ่มประสิทธิภาพแอปพลิเคชัน PHP ได้อย่างมาก การใช้คีย์-ค่าพร้อม TTL ทำให้จัดการข้อมูลชั่วคราวได้อย่างมีประสิทธิภาพ โค้ดตัวอย่างทั้งหมดพร้อมดาวน์โหลดที่ GitHub