Redis Trong Laravel Là Gì?

Redis Trong Laravel Là Gì?
Redis (viết tắt của chữ Remote Dictionary Server) là kho dữ liệu key-value. Nó được lưu trong kho bộ nhớ và mã nguồn mở. Có tốc độ truy cập thần tốc.

Khi công nghệ chưa phát triển, lập trình viên thường sử dụng các thư mục để lưu trữ dữ liệu. Ngày nay, chúng ta sử dụng các cơ sở dữ liệu có liên quan đến nhau để lưu trữ các thông tin. Redis trong Laravel cũng được ra đời và dùng với mục đích tương tự. Nó có nhiệm vụ lưu giữ các dữ liệu có cấu trúc và thời gian lưu trữ cực kỳ nhanh. 

 

Khái niệm về Redis 

 

Redis là một loại dự án store mã nguồn mở để lưu trữ các cặp dữ liệu theo kiểu key-value. Redis còn có tên gọi là server cấu trúc dữ liệu vì các khóa có thử chứa dữ liệu dạng strings, lists, hashes, sets và sorted sets. Trước khi ứng dụng Redis lên Laravel, các bạn nên tải thư viện predis/predis (~1.0) bằng Composer.

 

Redis còn là hệ thống hỗ trợ caching data trên RAM, cho phép hỗ trợ đa dạng cấu trúc cơ sở dữ liệu, định kỳ sao lưu dữ liệu ra ổ đĩa cứng, sửa-đổi-bổ sung dữ liệu đơn giản. Với nhiều đặc điểm nổi bật, Redis đang trở thành công cụ được ứng dụng rộng rãi trong các hệ thống như social network, chat,…nói chung là các hệ thống đòi hỏi truy xuất nhanh và ổn định.

 

Cấu hình 

 

Cấu hình cho Redis thường ở file config/database.php. Ở trong file này, các bạn sẽ thấy 1 mảng redis có chứa thông số đến Redis server. 

 

'redis' => [
    'cluster' => false,
    'default' => [
        'host'     => '127.0.0.1',
        'port'     => 6379,
        'database' => 0,
    ],
],

 

Cấu hình server mặc định đòi hỏi cung cấp đầy đủ thông tin để phát triển. Tuy nhiên, các bạn có thể thay đổi các giá trị này theo môi trường của các bạn. Các bạn chỉ cần cung cấp đúng tên Redis server, chỉ định host và port mà server sử dụng. 

 

Thông số cluster sẽ cung cấp cho Laravel Redis client biết và thực hiện phân mảnh trên các node của Redis. Nó cũng cho phép ta tạo pool cho các node và 1 lượng lớn RAM có thể sử dụng được. 

 

Tuy nhiên, các bạn cần lưu ý đến chuyện phân mảnh ở phía client (không xử lý khi thất bại). Do đó, nó thích hợp ứng dụng với loại dữ liệu đã được cache có thể dùng được trong các data store chính khác.

 

Hơn nữa, các bạn có thể khai báo 1 mảng options trong kết nối đến Redis nên nó cho phép bạn chỉ định 1 set các thông số client của Predis. Nếu Redis server yêu cầu đăng nhập, bạn cần cung cấp mật khẩu (thêm thông số password) vào trong mảng cấu hình cho Redis server. Nếu bạn có Redis PHP extension cài thông qua PECL, bạn cần phải đổi tên của Redis trong config/app.php.

 

Sử dụng cơ bản

 

Chúng ta có thể tương tác với Redis bằng cách gọi một số hàm trong Redis façade. Redis façade thường hỗ trợ các hàm động. Điều đó có nghĩa là bạn có thể gọi bất kỳ câu lệnh Redis nào trong façade. Nó sẽ được truyền thẳng trực tiếp đến Redis. Ví dụ bạn gọi GET trên Redis bằng cách gọi hàm get trong Redis façade như sau:  

 

<?php
namespace App\Http\Controllers;
use Redis;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     *
     * @param    int  $id
     * @return  Response
     */
    public function showProfile($id)
    {
        $user = Redis::get('user:profile:'.$id);
        return view('user.profile', ['user' => $user]);
    }
}

 

Laravel sử dụng các hàm magic để truyền dòng lệnh đến Redis server. Do đó, bạn chỉ cần truyền đúng tham số mà lệnh Redis muốn. 

 

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

 

Bạn cũng có thể thử cách khác. Bạn truyền câu lệnh đến server có sử dụng hàm command. Hàm command nhận tên trong tham số đầu tiên và một mảng các giá trị nằm ở tham số thứ hai. 

 

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

 

Cách sử dụng nhiều Redis connection 

 

Bạn lấy một đối tượng kết nối Redis bằng cách gọi đến hàm Redis::connection như thế này: 

 

$redis = Redis::connection();

 

Lệnh này cung cấp đối tượng kết nối tới Redis server mặc định. Nếu không sử dụng bất cứ server clustering nào, thì bạn có thể truyền vào tên server trong hàm connection để lấy một server chỉ định được khai báo trong cấu hình Redis. 

 

$redis = Redis::connection('other');

 

Các câu lệnh pipelining

 

Pipelining phát huy tác dụng khi các bạn cần gửi nhiều câu lệnh đến server trong một yêu cầu. Hàm pipeline nhận một tham số (một closure nhận đối tượng Redis). Bạn có thể cung cấp tất cả câu lệnh đến đối tượng Redis này. 

 

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

 

Publish và Subscribe

 

Laravel có cung cấp một interface tiện ích cho 2 lệnh của Redis – publish và subscribe. Các câu lệnh này cho phép các bạn nghe một bản tin trên một kênh. Bạn đăng tải bản tin đó tới một kênh (từ ứng dụng khác) hoặc thậm chí sử dụng một ngôn ngữ lập trình mới. Vì vậy, chúng có thể trao đổi dễ dàng giữa các ứng dụng và quá trình thực hiện cũng nhanh chóng.

 

Bạn nên thiết lập một listener trên một kênh thông qua Redis có sử dụng hàm subscribe. Bạn đặt hàm gọi này bên trong câu lệnh Artisan vì chuyện gọi hàm subscribe phải mất một khoảng thời gian để thực hiện tiến trình đầy đủ. 

 

<?php
namespace App\Console\Commands;
use Redis;
use Illuminate\Console\Command;
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;
        });
    }
}
// Bạn có thể đăng bản tin tới kênh có sử dụng publish. 
Route::get('publish', function () {
    // Route logic...
    Redis::publish('test-channel', json_encode(['foo' => 'bar']));
});

 

Đăng ký subscription (sử dụng wildcard)

 

Khi sử dụng hàm psubscribe, bạn có thể subscribe tới 1 kênh dạng wildcard – là kênh hữu dụng để giữ các bản tin trên tất cả kênh. Tên $channel sẽ được truyền ở tham số thứ 2 trong closure. 

 

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

 

Các ứng dụng của Redis

 

Caching

 

Sử dụng làm bộ nhớ đệm. Nhờ có tốc độ đọc và ghi nhanh, Redis có thể trở thành bộ nhớ đệm. Bộ nhớ đệm là nơi chia sẻ dữ liệu giữa các ứng dụng với nhau hoặc trở thành database tạm thời. Redis cũng có thể trở thành Full Page Cache cho website. Vì tính nhất quán, bạn cũng không cảm nhận sự chậm trễ khi khởi động Redis. 

 

Counter

 

Trở thành bộ đếm. Với thuộc tính tăng và giảm thông số rất nhanh (trong khi dữ liệu lại được lưu trên RAM, sets và sorted sets), Redis được sử dụng để đếm lượt view của 1 trang web hoặc các bảng xếp hạng trong game. Redis có hỗ trợ thread safe nên nó có thể đồng bộ dữ liệu giữa các request. 

 

Publish/Subscribe (Pub/Sub)

 

Redis tạo kênh chia sẻ dữ liệu. Nó hỗ trợ tạo các kênh để trao đổi dữ liệu giữa publisher và subscriber giống như kênh trong Socket Cluster hoặc chủ đề trong Apache Kafka. Pub/Sub được sử dụng để theo dõi các kết nối trong mạng xã hội hoặc các hệ thống chat. 

 

Queues

 

Redis tạo hàng đợi để giải quyết lần lượt các request. Nó cho phép lưu trữ theo danh sách và cung cấp nhiều thao tác với các thành phần có trong danh sách đó. Do đó, nó còn được sử dụng như một message queue. 

 

Các kiểu dữ liệu trong Redis 

 

Không giống như RDMS hay PostgreSQL, Redis không có bảng. Nó lưu trữ dữ liệu dưới dạng key-value. Trên thực tế, memcache cũng lưu trữ dữ liệu giống vậy. Tuy nhiên, kiểu dữ liệu của memcache bị hạn chế hơn Redis. Do đó, nó không hỗ trợ nhiều thao tác từ phía người dùng. 

 

STRING

 

String, integer hoặc float đều có thể làm việc với Redis. Từng phần của string cũng có thể được điều chỉnh tăng hoặc giảm giá trị của integer hoặc float. 

 

LIST

 

LIST là một danh sách nằm trong strings và được sắp xếp theo thứ tự insert. Redis có thể thêm một phần tử vào đầu hoặc cuối list. List là lựa chọn thích hợp ở các bài toán cần thao tác với các phần tử gần đầu và cuối. Vì việc truy xuất như vậy là rất nhanh dù insert triệu phần tử. Tuy nhiên, yếu điểm của nó là truy cập vào các phần tử ở giữa list rất chậm.

 

SET

 

SET là tập hợp các string không được sắp xếp sẵn từ trước. Redis hỗ trợ các thao tác thêm, đọc và xóa mỗi phần tử. Đồng thời, nó cũng kiểm tra sự xuất hiện của phần tử trong tập hợp. Redis cũng hỗ trợ các phép toán tập hợp, bao gồm intersect, union và difference.

 

HASH

 

HASH lưu trữ bảng của các cặp key-value (key được xếp ngẫu nhiên). Redis hỗ trợ tính năng thêm, đọc, xóa mỗi phần tử hoặc là đọc toàn bộ các giá trị.

 

SORTED SET (ZSET)

 

SORTED SET (ZSET) là một danh sách mà mỗi phần tử là map của một string (member) và một floating-point number (score). Danh sách thường được xếp theo score này. Các phần tử của ZSET cũng được sắp xếp theo thứ tự từ score nhỏ đến score lớn.

 

Persistent redis là gì

 

Bên cạnh chuyện lưu trữ key-value trong bộ nhớ RAM, Redis có thêm 2 background threads chuyên định kỳ ghi dữ liệu vào đĩa cứng. Có 2 loại file được lưu trong đĩa cứng.  

 

RDB (Redis DataBase file)

 

RDB thực hiệu và sao lưu snapshot của DB vào ổ đĩa cứng sau mỗi một khoảng thời gian nhất định. Nó cho phép người dùng lưu các phiên bản khác nhau của DB nên khá thuận tiện trong phiên kiểm tra nếu có sự cố xảy ra. Bằng việc lưu trữ dữ liệu vào 1 file cố định, người dùng có thể di chuyển dữ liệu tới các trung tâm lưu trữ hoặc máy chủ khác.

 

RDB sẽ không phải là lựa chọn hợp lý nếu bạn muốn giảm tối đa rủi ro mất trắng dữ liệu. Người dùng sẽ thiết lập để tạo RDB snapshot mới (khoảng 5-7 phút/lần). Nếu có sự cố, Redis bị tê liệt và dữ liệu trong những giây phút cuối sẽ không được lưu.

 

Bên cạnh đó, RDB cần dùng fork() để tạo tiến trình con phục vụ cho thao tác disk I/O. Nếu dữ liệu quá lớn, quá trình fork() mất rất nhiều thời gian và server sẽ không thể đáp ứng được request từ người dùng trong một vài giây (tùy thuộc vào lượng dữ liệu và hiệu suất hoạt động của CPU). 

 

AOF (Append Only File)

 

AOF có nhiệm vụ là lưu lại toàn bộ các thao tác của người dùng mà server đã nhận được trước đó. Các thao tác này sẽ được phục hồi khi khởi động lại server hoặc tái thiết lập phiên làm việc từ đầu.

 

Khi sử dụng AOF, chuyện dataset vững bền. Người dùng có thể config để Redis ghi log (theo từng câu query hoặc 1 giây là 1 lần khởi động). Redis ghi trong log AOF là hoạt động theo kiểu thêm vào cuối file sẵn có. 

 

Tiến trình tìm file có sẵn là không cần. Kể cả khi một nửa câu lệnh đã được lưu trong file log (có thể do ổ đĩa bị đầy), Redis vẫn có chức năng quản lý và sửa chữa lỗi đó (redis-check-aof).

 

Redis cũng cung cấp quá trình chạy nền và cho phép chúng ta ghi lại file AOF khi dung lượng file khổng lồ.

 

File AOF thường lớn hơn file RDB (cùng 1 dataset). AOF có thể chạy chậm hơn RDB (tùy theo cách thức mà bạn thiết lập trong một khoảng thời gian khi sao lưu dữ liệu vào ổ cứng). Tuy nhiên, nếu bạn thiết lập log AOF trong 1 giây 1 lần, hiệu năng đạt được tương đương với RDB.

 

Dù hiếm nhưng file AOF có thể có bug do AOF không thể tái tạo chính xác dataset khi khởi động lại Redis.

 

 

 

 

Hồ Hữu Hiền

Mình là developer nên đôi khi viết bài không hay lắm mong các bạn thông cảm. Nếu muốn biết thêm thông tin về mình thì vui lòng vào website này để biết. https://huuhienqt.dev/

Bình luận (0)