Asas Redis

Redis adalah salah satu daripada data cache yang bagi aku amat suka lebih lagi jika digandingkan bersama Laravel kerana bagi aku redis dan laravel agak senang nak dibuat.

Pertama sekali adalah, pasang redis pada server anda. Kalau tak ada maka boleh rujuk pada kaedah pemasangan redis yang pelbagai. Kemudian untuk Laravel, pasang pula library predis yang akan membantu Laravel berhubung dengan redis.

composer require predis/predis

Kalau tak ada sebarang perubahan secara manual yang korang jalankan, sepatutnya dah boleh guna terus. Untuk kali ini aku letakkan contoh dimana apabila seorang pengguna masuk ke paparan log masuk sesebuah sistem, dia akan dapat melihat;

  1. Form login page
  2. Pengumuman yang masih aktif

Maka secara normalnya, setiap kali pengguna masuk ke paparan log masuk, sistem akan membuat satu query baru kepada database untuk mendapatkan senarai pengumuman yang masih aktif. Dengan kata lain, jika ada 1000 pengguna masuk ke sesebuah paparan yang sama maka 1000 kali query yang sama akan dijalankan kepada pangkalan data. Dan disebabkan datanya tidak berubah dalam jangka masa tersebut, maka sebenarnya itu adalah satu jenis pembaziran sumber. Kita boleh kurangkan masalah ini dengan menggunakan cache, dalam kes ini kita gunakan Redis.

// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
{
	$today = date('Y-m-d');
	$announcements = Announcement::where('start_at', '<=', $today)
	->where('end_at', '>=', $today)
	->get();

	return view('auth.login')->with(['announcements' => $announcements]);
}

Kod di atas adalah kod asal yang kita akan ubah dengan cara:

  1. Periksa cache di dalam Redis adakah data tersebut sudah ada
  2. Jika tiada, kita query ke pangkalan data
  3. Kemudian masukkan ke dalam cache Redis
  4. Hantar data ke paparan
// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
{
	$today = date('Y-m-d');
	$announcements = Redis::get('announcements:active');

	if ($announcements == null) {
		$announcements = Announcement::where('start_at', '<=', $today)
		->where('end_at', '>=', $today)
		->get();

            // make it expired every 6 hours
		Redis::set('announcements:active', $announcements, 43200);
	} else {
		$announcements = json_decode($announcements);
	}

	return view('auth.login')->with(['announcements' => $announcements]);
}

Maka jika kita lihat dengan menggunakan library seperti Laravel Debugbar, kita akan dapat dapati tiada query baru yang dibuat selepas query pertama dilakukan. Kerana selepas query pertama, query kedua hanya mengambil data yang disimpan secara cache daripada Redis sahaja. Dengan kata lain, jika terdapat 1000 request, kita hanya membuat 1 query sahaja. Penjimatan sebanyak 999 query.

Refactor

Kod di atas tiada masalah, cuma kita boleh cantikkannya lagi dengan mengeluarkan kod yang mencari data pengumuman tersebut dan menukarkannya menjadi fungsi yang khusus untuknya. Perkara ini adalah untuk memudahkan kita menggunakan fungsi yang sama jika perlu sebagai contoh untuk memparkan senarai pengumuman yang sama di dashboard selepas log masuk berjaya.

// app/Http/Repositories/AnnouncementRepository.php

public static function getActiveAnnouncements($date)
{
	$announcements = Redis::get('announcements:active');

	if ($announcements == null) {
		$announcements = Announcement::where('start_at', '<=', $date)
		->where('end_at', '>=', $date)
		->get();

            // make it expired every 6 hours
		Redis::set('announcements:active', $announcements, 43200);
	} else {
		$announcements = json_decode($announcements);
	}

	return $announcements;
}

Saya cipta satu fail baru sebagai repository yang dinamakan sebagai AnnouncementRepository.

// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
    {
        $announcements = AnnouncementRepository::getActiveAnnouncements(date('Y-m-d'));

        return view('auth.login')->with(['announcements' => $announcements]);
    }

Kini saya hanya perlu memanggil data pengumuman dengan memanggil fungsi getActiveAnnouncements daripada AnnouncementRepository yang telah dibuat. Sekarang fungsi showLoginForm akan lebih ringkas dan fokus kepada perkara yang mahu dilakukan sahaja.

Notakaki

  • Redis + Laravel = mudah
  • Data di dalam Redis berada di dalam memori. Maka RAM perlu sesuai dengan jumlah data yang disimpan.
  • Redis bukan tempat simpan data yang kekal. Hanya sementara.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.