Laravel: Redis


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Mục lục bài viết: 


Giới thiệu

Redis là một kho khóa-giá trị nâng cao, mã nguồn mở. Nó thường được gọi là máy chủ cấu trúc dữ liệu vì các khóa có thể chứa chuỗibămdanh sáchtập hợp và tập hợp được sắp xếp.

Trước khi sử dụng Redis với Laravel, ta cần cài đặt và sử dụng phần mở rộng phpredis PHP qua PECL. Nếu bạn đang sử dụng Laravel Sail thì tiện ích mở rộng này đã được cài đặt trong vùng chứa Docker của ứng dụng của bạn.

Nếu bạn không thể cài đặt phần mở rộng phpredis, bạn có thể cài đặt gói predis/predis này qua Composer:

composer require predis/predis

Cấu hình

Bạn có thể định cấu hình cài đặt Redis của ứng dụng của mình thông qua file cấu hình config/database.php. Trong tệp này bạn sẽ thấy một mảng redis chứa các máy chủ Redis được ứng dụng của bạn sử dụng:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

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

    'cache' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => env('REDIS_CACHE_DB', 1),
    ],

],

Mỗi máy chủ Redis được định nghĩa trong tệp cấu hình của bạn bắt buộc phải có tên, máy chủ lưu trữ và cổng trừ khi bạn xác định một URL duy nhất để đại diện cho kết nối Redis:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'default' => [
        'url' => 'tcp://127.0.0.1:6379?database=0',
    ],

    'cache' => [
        'url' => 'tls://user:password@127.0.0.1:6380?database=1',
    ],

],

Cấu hình sơ đồ kết nối

Theo mặc định, các máy khách Redis sẽ sử dụng lược đồ tcp khi kết nối với máy chủ Redis của bạn; tuy nhiên, bạn có thể sử dụng mã hóa TLS/SSL bằng cách chỉ định tùy chọn cấu hình scheme trong mảng cấu hình máy chủ Redis của bạn:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

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

],

Cụm (Cluster)

Nếu ứng dụng của bạn đang sử dụng một cụm máy chủ Redis, bạn nên định nghĩa các cụm này trong một khóa clusters của cấu hình Redis của bạn. Khóa cấu hình này không tồn tại theo mặc định, vì vậy bạn sẽ cần tạo nó trong file cấu hình config/database.php:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'clusters' => [
        'default' => [
            [
                'host' => env('REDIS_HOST', 'localhost'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_PORT', 6379),
                'database' => 0,
            ],
        ],
    ],

],

Theo mặc định, các cụm sẽ thực hiện sharding phía máy khách trên các nút của bạn, cho phép bạn gộp các nút và tạo ra một lượng lớn RAM có sẵn. Tuy nhiên, sharding phía máy khách không xử lý chuyển đổi dự phòng; do đó, nó chủ yếu phù hợp với dữ liệu được lưu trong bộ nhớ cache tạm thời có sẵn từ một kho dữ liệu chính khác.

Nếu bạn muốn sử dụng cụm Redis gốc thay vì phân cụm phía máy khách thì bạn đặt giá trị cấu hình options.cluster thành redis trong file config/database.php:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    'options' => [
        'cluster' => env('REDIS_CLUSTER', 'redis'),
    ],

    'clusters' => [
        // ...
    ],

],

Predis

Nếu bạn muốn ứng dụng của mình tương tác với Redis thông qua gói Predis, bạn cần đảm bảo rằng giá trị của REDIS_CLIENT là predis:

'redis' => [

    'client' => env('REDIS_CLIENT', 'predis'),

    // ...
],

Ngoài các mặc định hostportdatabase, và password, Predis còn hỗ trợ thêm các thông số kết nối có thể được định nghĩa cho mỗi máy chủ Redis. Để sử dụng các tùy chọn cấu hình bổ sung này, hãy thêm chúng vào cấu hình máy chủ Redis trong file config/database.php như sau:

'default' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    'read_write_timeout' => 60,
],

Bí danh Redis Facade

Tệp config/app.php của Laravel chứa một mảng aliases để định nghĩa tất cả các bí danh lớp sẽ được đăng ký bởi framework. Nếu bạn đang sử dụng ứng dụng Predis và muốn bật các bí danh này, bạn có thể bỏ comment phần aliases đó đi trong file config/app.php.

phpredis

Theo mặc định, Laravel sẽ sử dụng phần mở rộng phpredis để giao tiếp với Redis. Ứng dụng khách mà Laravel sẽ sử dụng để giao tiếp với Redis được quy định bởi giá trị của tùy chọn redis.client, trong đó phpredis chính là giá trị của REDIS_CLIENT:

'redis' => [

    'client' => env('REDIS_CLIENT', 'phpredis'),

    // ...
],

Ngoài các tùy chọn mặc định hostportdatabase, và password, phpredis còn hỗ trợ các thông số kết nối bổ sung sau đây: namepersistentprefixread_timeoutretry_intervaltimeout, và context. Bạn có thể thêm bất kỳ tùy chọn nào sau đây vào cấu hình máy chủ Redis của mình trong file config/database.php:

'default' => [
    'host' => env('REDIS_HOST', 'localhost'),
    'password' => env('REDIS_PASSWORD', null),
    'port' => env('REDIS_PORT', 6379),
    'database' => 0,
    'read_timeout' => 60,
    'context' => [
        // 'auth' => ['username', 'secret'],
        // 'stream' => ['verify_peer' => false],
    ],
],

Tương tác với Redis

Bạn có thể tương tác với Redis bằng cách gọi các phương thức khác nhau trên facade RedisRedis hỗ trợ phương thức động, có nghĩa là bạn có thể gọi bất kỳ lệnh Redis nào trên facade và lệnh đó sẽ được chuyển trực tiếp đến Redis.

Trong ví dụ sau, ta sẽ gọi lệnh GET của Redis bằng cách gọi phương thức get của facade Redis như sau:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;

class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        return view('user.profile', [
            'user' => Redis::get('user:profile:'.$id)
        ]);
    }
}

Laravel sử dụng các phương thức magic để chuyển các lệnh đến máy chủ Redis. Nếu một lệnh Redis yêu cầu các đối số, bạn nên chuyển các đối số đó đến phương thức tương ứng của facade như sau:

use Illuminate\Support\Facades\Redis;

Redis::set('name', 'Taylor');

$values = Redis::lrange('names', 5, 10);

Ngoài ra, bạn có thể chuyển các lệnh tới máy chủ bằng cách sử dụng phương thức command của Redis, pương thức này chấp nhận tên của lệnh làm đối số đầu tiên và một mảng giá trị làm đối số thứ hai của nó:

$values = Redis::command('lrange', ['name', 5, 10]);

Sử dụng nhiều kết nối Redis

File config/database.php cho phép bạn định nghĩa nhiều kết nối/máy chủ Redis. Bạn có thể nhận được kết nối đến kết nối Redis cụ thể bằng cách sử dụng phương thức connection:

$redis = Redis::connection('connection-name');

Để có được một phiên bản của kết nối Redis mặc định, bạn có thể gọi phương thức connection mà không cần đối số:

$redis = Redis::connection();

Giao dịch

Phương thức transaction của Redis facade cung cấp một bao đóng thuận tiện bằng cách sử dụng các lệnh MULTI và EXEC của Redis. Tất cả các lệnh Redis được đưa ra trong quá trình bao đóng sẽ được thực hiện trong một giao dịch duy nhất:

use Illuminate\Support\Facades\Redis;

Redis::transaction(function ($redis) {
    $redis->incr('user_visits', 1);
    $redis->incr('total_visits', 1);
});

Khi xác định giao dịch Redis, bạn không thể lấy bất kỳ giá trị nào từ kết nối Redis. Hãy nhớ rằng, giao dịch của bạn được thực hiện như một hoạt động nguyên tử và đơn lẻ và hoạt động đó không được thực hiện cho đến khi toàn bộ quá trình đóng của bạn hoàn tất việc thực hiện các lệnh của nó.

Tập lệnh Lua

Phương thức eval cung cấp một phương pháp thực hiện nhiều lệnh Redis trong một hoạt động duy nhất. Tuy nhiên, eval có lợi điểm là có thể tương tác và kiểm tra các giá trị chính của Redis trong quá trình hoạt động đó. Các tập lệnh Redis được viết bằng ngôn ngữ lập trình Lua.

Lúc đầu, phương thức eval có thể hơi đáng sợ, nhưng chúng ta sẽ khám phá một ví dụ cơ bản để phá vỡ lớp băng. Phương thức eval sẽ tiếp nhận một số đối số. Đầu tiên, bạn cần truyền tập lệnh Lua (dưới dạng một chuỗi) vào phương thức. Thứ hai, bạn nên truyền số lượng các khóa (dưới dạng số nguyên) mà tập lệnh sẽ tương tác. Thứ ba, bạn cần truyền tên của các khóa đó. Cuối cùng, bạn có thể truyền bất kỳ đối số bổ sung nào khác mà bạn cần truy cập trong tập lệnh của mình.

Trong ví dụ sau, chúng ta sẽ tăng biến đếm, kiểm tra giá trị mới của nó và tăng biến đếm thứ hai nếu giá trị của biến đếm đầu tiên lớn hơn năm. Cuối cùng, chúng ta sẽ trả về giá trị của biến đếm đầu tiên:

$value = Redis::eval(<<<'LUA'
    local counter = redis.call("incr", KEYS[1])

    if counter > 5 then
        redis.call("incr", KEYS[2])
    end

    return counter
LUA, 2, 'first-counter', 'second-counter');

Vui lòng tham khảo tài liệu Redis để biết thêm thông tin về tập lệnh Redis.

Lệnh Pipelining

Đôi khi bạn có thể cần thực hiện hàng chục lệnh Redis, phương thức pipeline sẽ làm điều này cho bạn. Phương thức pipeline có một đối số là một closure để nhận một đối tượng Redis. Tất cả các lệnh sẽ được gửi đến máy chủ Redis cùng một lúc. Các lệnh sẽ vẫn được thực hiện theo thứ tự mà chúng đã được đưa ra:

use Illuminate\Support\Facades\Redis;

Redis::pipeline(function ($pipe) {
    for ($i = 0; $i < 1000; $i++) {
        $pipe->set("key:$i", $i);
    }
});

Pub / Sub

Laravel cung cấp một giao diện thuận tiện cho các lệnh Redis là publish và subscribe. Các lệnh Redis này cho phép bạn lắng nghe các thông điệp trên một "kênh" nhất định. Bạn có thể xuất bản tin nhắn lên kênh từ một ứng dụng khác hoặc thậm chí sử dụng ngôn ngữ lập trình khác, cho phép giao tiếp dễ dàng giữa các ứng dụng và quy trình.

Trước tiên, ta hãy thiết lập trình nghe kênh bằng phương thức subscribe. Chúng ta sẽ đặt lệnh gọi phương thức này trong một lệnh Artisan vì việc gọi subscribe sẽ bắt đầu một quá trình xử lý dài:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisSubscribe extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'redis:subscribe';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Subscribe to a Redis channel';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        Redis::subscribe(['test-channel'], function ($message) {
            echo $message;
        });
    }
}

Tiếp theo ta có thể xuất bản thông báo lên kênh bằng phương thức publish:

use Illuminate\Support\Facades\Redis;

Route::get('/publish', function () {
    // ...

    Redis::publish('test-channel', json_encode([
        'name' => 'Adam Wathan'
    ]));
});

Đăng ký ký tự đại diện

Sử dụng phương thức psubscribe bạn có thể đăng ký một kênh ký tự đại diện, kênh này có thể hữu ích để xem tất cả thông báo trên tất cả các kênh. Tên kênh sẽ được chuyển làm đối số thứ hai cho phần đóng được cung cấp:

Redis::psubscribe(['*'], function ($message, $channel) {
    echo $message;
});

Redis::psubscribe(['users.*'], function ($message, $channel) {
    echo $message;
});
» Tiếp: Query Builder
« Trước: Ủy quyền (Authorization)
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!