Integrasi Redis Pada Aplikasi laravel

​Assalamualaikum Warahmatullahi Wabarakatuh, lama tak jumpa, mumpung ada kesempatan, disini saya akan memberikan tutorial bagaimana caranya mengintegrasikan redis yang digunakan sebagai database cache pada aplikasi laravel.

 

 

Pendahuluan

Perlu diketahui Redis adalah tools open source untuk penyimpanan struktur data dalam memori sumber terbuka. Sering digunakan untuk database dan cache. Nah, pada artikel ini kita akan menerapkan caching pada laravel.

Laravel sendiri telah mendukung penggunaan Redis, yang digunakan untuk cache sebagai penyimpan data sementara sehingga dapat mempercepat proses query database dan mendapatkan umpan balik, dengan begitu akan mengurangi jumlah waktu yang dihabiskan untuk pulling up data.

Karena kecepatan Redis ini lah, membuat Redis sesuatu yang cool yang harus kamu coba, Redis memberikan cara terstruktur untuk menyimpan data dalam memori. Oleh karena itu, Redis dapat lebih cepat daripada database tradisional yang biasa ditulis ke disk. Redis juga menawarkan lebih banyak struktur data untuk menyimpan datamu, redis menyediakan struktur data seperti string, hash, list, set, sorted sets dengan range queries, bitmaps, hyperloglogs, indeks geospasial, dan streams. Karena fitur itu, Redis sering digunakan untuk menyimpan state-state sementara. Hal ini umum terjadi pada arsitektur microservice, session stores, dan data yang tidak membutuhkan persistensi jangka panjang. [1]

 

Redis Method

Untuk mengetahui method apa saja yang bisa digunakan/support oleh laravel, silahkan baca dokumentasinya dihalaman official redis.

Pada tutorial ini kita hanya membutuhkan 3 method saja:

- GET

Method get ini kita akan mencari/menampilkan data berdasarkan key yang dicari. Semisal saya mempunyai key artikels lalu saya akan mendapatkan value dari key tersebut.  Method Get hanya menyimpan data berupa string dan akan mengembalikan error key stores hashes atau yang lain. 

 

- SET

Method set ini kita akan menyimpan sebuah data kedalam redis dengan menggunakan key yang sama yaitu artikels. Jika key sudah ada sebelumnya, maka akan teroverride dengan data yang baru.

 

- DEL

Method del ini akan menghapus data berdasarkan key yang diinputkan. Semisal saya mempunyai key artikels_tutorial-php jika kalian menjalankan method del maka akan terhapus data tersebut sesuai keynya.

 

Persiapan project laravel

Disini kita akan memulai projectnya, saya akan menamai projectnya yaitu blog-lara-redis, silahkan jalan perintah create-project pada terminal.

composer create-project laravel/laravel blog-lara-redis
cd blog-lara-redis
php artisan serve

Selanjutnya, kita perlu menginstal pacakge predis di aplikasi kita menggunakan composer sebelum menggunakan Redis pada aplikasi kita. Predis adalah klien Redis yang ditulis seluruhnya dalam PHP dan tidak memerlukan ekstensi tambahan. Jalankan perintah berikut di terminal untuk menginstal Predis:

composer require predis/predis

 

Konfigurasi database redis

Ketika sudah menginstall predis, kamu buka file database.php difolder config/database.php, Dalam file tersebut, kamu akan melihat redis array yang berisi konfigurasi redis server. Secara default, client diatur ke phpredis, dan karena predis digunakan pada tutorial ini kalian rubah menjadi predis.

'redis' => [
  'client' => env('REDIS_CLIENT', 'predis'),
  'options' => [
      'cluster' => env('REDIS_CLUSTER', 'redis'),
      'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
  ],
  'default' => [
      'url' => env('REDIS_URL'),
      'host' => env('REDIS_HOST', '127.0.0.1'),
      'password' => env('REDIS_PASSWORD', null),
      'port' => env('REDIS_PORT', '6379'),
      'database' => env('REDIS_DB', '0'),
  ],
],

 

[OPTIONAL] Jika kalian menggunakan redis socket (unix).

silahkan tambahkan didalam array default

'scheme' => env('REDIS_SCHEME','tcp')

lalu ubah host menjadi path.

sebelum

'default' => [
            'url' => env('REDIS_URL'),
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],

sesudah

'default' => [
            'url' => env('REDIS_URL'),
            'path' => env('REDIS_HOST',null),
            'scheme' => env('REDIS_SCHEME','tcp'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', '6379'),
            'database' => env('REDIS_DB', '0'),
        ],

Mengapa saya menggunakan redis unix? karena pada artikel [2] menjelaskan bahwa lebih cepat responnya redis unix daripada redis tcp.

 

 

jangan lupa tambahkan REDIS_SCHEME  dan REDIS_CLIENT di file .env

REDIS_HOST=/var/run/redis/redis-server.sock
REDIS_CLIENT=predis
REDIS_PASSWORD=null
REDIS_PORT=null
REDIS_SCHEME=unix

 

Membuat Seed data

Jika kalian sudah mengubah settingan dataabase di file .env dan sudah membuatnya diserver database, selanjutnya kita akan membuat seed data. Data ini hanyalah untuk data testing sementara, yang digunakan ujicoba untuk caching.

php artisan make:seeder ArtikelSeeder

Nantinya akan membuat file baru ArtikelSeeder didalam folder database/seeders.

Kemudian kita buat faker data, berikut adalah kodenya.

<?php

namespace Database\Seeders;

use App\Models\Posts;
use Faker\Factory as Faker;
use Illuminate\Support\Str;
use Illuminate\Database\Seeder;

class ArtikelSeeder extends Seeder
{
    public function getFakeData($faker)
    {
        $paragraphs = rand(8, 15);
        $i = 0;
        $ret = "";
        while ($i < $paragraphs) {
            $ret .=  $faker->paragraph(rand(2, 6)) ;
            $i++;
        }
        return $ret;
    }
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $faker = Faker::create('id_ID');
        for ($i=0; $i < 250 ; $i++) {            
            $dt = new Posts();
            $dt->title = $faker->sentence();
            $dt->slug = Str::slug($dt->title, '-');
            $dt->html = $this->getFakeData($faker);
            $dt->status = 'publish';
            $dt->published_at = $faker->dateTimeBetween();
            $dt->save();
        }
    }
}

 

Kemudian kita akan mengeksekusi file seeder tersebut dengan perintah

php artisan db:seed --class=ArtikelSeeder

 

Get Data

Untuk menampilkan data artikel dari database, kita akan membuat controller bernama BlogController dan tambahkan function GetArtikel dengan parameter slug.

Pada request pertama akan mengambil dari database terlebih dahulu dan melalukan caching ke redis. Dan jika ada request kembali, maka data akan diambil langsung dari redis.

 

Pertama, kita akan buat controller terlebih dahulu

php artisan make:controller BlogController

lalu, tambahkan fungsi GetArtikel() untuk mendapatkan semua postingan artikel.

use App\Models\Posts;
use Illuminate\Support\Facades\Redis;

public function GetArtikel($slug) {

  $cached = Redis::get('artikel:slug:' . $slug);

  if(isset($cached)) {
      $blog = json_decode($cached, FALSE);

      return response()->json([
          'status_code' => 200,
          'message' => 'mengambil data dari redis',
          'data' => $blog,
      ]);
  }else {
      $blog = Posts::where('slug',$slug)->where('status','publish')->first();
      Redis::set('artikel:slug:' . $slug, $blog, 'EX', 120);

      return response()->json([
          'status_code' => 200,
          'message' => 'mengambil data dari database',
          'data' => $blog,
      ]);
  }
}

Dalam kode diatas, pertama-tama akan diperiksa terlebih dahulu oleh Redis berdasarkan key artikel:slug:_slug. Jika terdapat key yang sama maka akan mengambilnya dalam format json. Jika tidak terdapat didalam Redis, maka akan menampilkan dari database lalu akan menyimpan di Redis dengan key artikel:slug:_slug dan maximal durasi penyimpanan yaitu 120 detik caching. Silahkan rubah angka 120 sesuai keinginan kamu, Ingat! satuan detik.

 

Jika kamu ingin data cachenya permanent alias tanpa expired. Silahkan hapus parameter ketiga 'EX' dan parameter ke empat 120 pada method Redis::set() .

 

Selanjutnya kita akan membuat route di routes/web.php dimana API kita dapat berinteraksi saat digunakan.

 // untuk laravel 8 kebawah
Route::get('/artikel/{slug}', 'BlogController@GetArtikel')->name('posts_slug');
 // untuk laravel 8
Route::get('/artikel/{slug}', [ BlogController::class, "GetArtikel" ])->name('posts_slug');

 

Update Data

Pada proses ini kita akan mengambil satu data lalu mengupdate data tersebut di database. Ketika sudah terupdate kita akan mencari key dari Redis, setelah mendapatkan keynya kita hapus terlebih dahulu. Lalu kita membuat key baru berdasarkan slug. 

 

Kita akan membuat function UpdateArtikel() dengan parameter Request dan id terlebih dahulu.

public function UpdateArtikel(Request $request, $id) {

  $update = Posts::where('id',$id)->where('status','publish')
                       ->update($request->all());

  if($update) {

      // Menghapus key artikel:slug:_slug dari Redis
      Redis::del('artikel:slug:' . $update->slug);

      $blog = Posts::where('id',$id)->where('status','publish')->first();
      // Insert key yang baru
      Redis::set('artikel:slug:' . $blog->slug, $blog);

      return response()->json([
          'status_code' => 200,
          'message' => 'Artikel telah diupdate',
          'data' => $blog,
      ]);
  }

}

Mengapa data yang diredis dihapus dahulu?

Karena  suatu saat kita mengubah slugnya data di redis akan ikut terhapus (jika expirednya permanen). Dengan begitu data yang tidak digunakan bisa terhapus dan tidak membebani memory server.

 

Dalam kode diatas, kita mendapatkan id dari blog terlebih dahulu. Lalu dicari melalui database, setelah itu akan mengupdate data. Setelah menjalankan update data di database, kita akan menghapus key lama di redis.  Selanjutnya kita akan mencari data  berdasarkan id yang kita cari. Lalu memasukkannya ke redis dengan key artikel:slug:_slug .

 

Setelah semua selesai tambahkan di routes

// jika laravel 8 kebawah
Route::post('/artikel/update/{id}', 'BlogController@UpdateArtikel');
// jika laravel 8
Route::post('/artikel/update/{id}', [ BlogController::class, "UpdateArtikel" ])->name('posts_update');

 

Hapus Data

Pada langkah terakhir ini, kita akan menghapus suatu artikel dari database kemudian juga akan menghapus key dari Redis.

Pertama tambahkan function deleteArtikel dengan parameter id

public function deleteArtikel($id) {
  $old_data = Posts::where('id',$id)->where('status','publish');
  $tmp = $old_data->first();

  // Menghapus key artikel:slug:_slug di Redis
  Redis::del('artikel:slug:' . $tmp->slug);
  // menghapus data di database
  $old_data->delete();

  return response()->json([
      'status_code' => 201,
      'message' => 'Artikel terhapus'
  ]);
}

Pada kode diatas kita mencari data berdasarkan id artikel, setelah itu kita akan menghapus key pada redis berdasarkan slug yang didapatkan dari database tadi. Setelah data terhapus pada redis, kita akan menghapus datanya dari database dan akan response json.

Jangan lupa untuk menambahkan routenya

// jika laravel 8 kebawah
Route::delete('/artikel/delete/{id}', 'BlogController@deleteArtikel');
// jika laravel 8
Route::delete('/artikel/delete/{id}', [ BlogController::class, "deleteArtikel" ])->name('posts_delete');

 

Kesimpulan

Pada artikel ini, kita sudah mempraktekkan bagaimana caranya mengintegrasikan redis yang digunakan sebagai database cache pada aplikasi laravel. Selain itu, kita juga sudah membahas Redis dan manfaatnya, dan bagaimana menggunakan Redis di Laravel untuk menyimpan data sementara untuk mempercepat query database. Kita juga sudah melakukan langkah-langkah untuk update dan menghapus data di Redis menggunakan key dan menerapkan metode Get/Set secara efektif. Saya harap tutorial ini bermanfaat.

 

Terima Kasih,

Wassalamualaikum Warahmatullahi Wabarakatuh.

 

Apabila artikel ini membantu kamu, dan jika kamu memiliki sedikit rezeki, mohon dukungannya dalam bentuk segelas kopi melalui URL dibawah ini:

Last Updated: Rabu, 18 Agustus 2021 9:46 GMT+7

Comments