Cache query  trong ứng dụng thực tế

Cache query trong ứng dụng thực tế

Ở đây mình có 1 bài toán thực tế đó chính là cache dữ liệu api gọi đến server với thông tin lấy từ trong mysql

Nguồn dữ liệu của mình ổn định và có 1 ít đọc ghi dữ liệu trong quá trình cache :

1 Thực tế website

Thực tế website mình sẽ có lượng truy cập vào trong web cao trong khoảng thời gian từ 9h sáng đến 23h đêm . Việc gọi Api sẽ thường xuyên trong khoảng thời gian này .Việc cập nhật dữ liệu thì sẽ được thực hiện trong khoảng 7,8h sáng 

2 : Phương hướng xử lý 

Việc đầu tiên thì chắc chắn sẽ phải cache lại thông tin dữ liệu : 

Thông thường với dữ liệu nếu thay đổi theo 1 khoản thời gian cụ thể thì mình sẽ dev cache 1 cục sau đó sẽ xử lý với các hàm xử lý array :

 $all_data = Cache::remember('all_data', 86400, function () {
               return DB::table('excels')->get(['MNT', 'NAME'])->toArray();
           });

Như vậy thì nhanh hơn và tiện hơn . Chỉ cần truy vấn sql 1 lần duy nhất

Nhưng vấn đề ở đây là chúng ta lại có dữ liệu người dùng nhập lẻ tẻ không vào 1 thời gian cố định nào và trong thời gian lượng người truy cập cao do đó mình đưa ra phương án 2 đó chính là cache từng phần tử 1 ,Khi nào có phần tử mới thì mình cache luôn phần tử đó .

Bước xử lý như sau :

Bước 1 Cache dữ liệu lúc 2h sáng với schedule :

Mình tạo schedule cache dữ liệu với command sau :

php artisan make:command ExcelDMS

Với nội dung như sau :

<?php

namespace App\Console\Commands;

use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class CacheDMS extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:cache-d-m-s';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command cache thông tin của khách hàng';

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        // $this->info('Bắt đầu chạy ' . Carbon::now());
        $status = DB::table('excels')->select(['id', 'MNT', 'NAME'])->chunkById(1000, function ($items) {
            foreach ($items as $item) {
                Cache::remember($item->MNT, 8600, function () use ($item) {
                    return $item;
                });
            }
        });
        if($status){
            $this->info(Carbon::now().'-run');
        }else{
            $this->error( Carbon::now() .'-error');
        }
        
      
    }
}

Và cấu hình schedule như sau :

 $schedule->command('app:cache-d-m-s')->dailyAt('1:50')->appendOutputTo(storage_path('logs\schedule.log'));

Ở trong file api :

 $id_search = $request->id;  
$data = Cache::remember($id_search, 86300, function () use ($id_search) {
            return DB::table('excels')->where('MNT', 'like', $id_search)->get(['MNT', 'NAME']);
        });
        return \response()->json($data);

Trong file api.php của thư mục routers

Route::get('excel/{id}',[\App\Http\Controllers\Api\ExcelController::class,'index']);

Oke vậy là xong mình đã có 1 api vừa nhanh vừa đỡ truy cập mysql nhiều tránh sập server