SAMPLE WEB APPLICATION USING REDIS

Ở các bài viết trước, chúng ta đã cùng nhau tìm hiểu căn bản về Redis với Tổng quan về RedisRedis Data Types And Commands. Cùng với đó là phân tích việc xây dựng 1 ứng dụng Redis qua bài viết Anatomy Of Redis Application. Trong bài viết này, chúng ta sẽ tìm hiểu cách xây dựng 1 website sử dụng Redis.

Mô tả website

Website được đặt tên là RBlog, là 1 blog system đơn giản với các chức năng sau:

  • Tạo mới/chỉnh sửa/xóa entry. User cần đăng nhập vào hệ thống để có thể thực hiện các thao tác trên. Ngoài ra, bất kỳ ai cũng có thể đọc bài viết (entry).

  • Thông tin của entry gồm có title và content. Người dùng có thể thích(like) 1 entry, cũng có thể bỏ like entry đó (dislike).

  • Hệ thống cung cấp 1 filter cho phép người dùng đọc những entry có số lượng like nhiều nhất.

Thiết kế Database

Với mô tả hệ thống như trên, chúng ta hoàn toàn có thể sử dụng chỉ MySQL hoặc chỉ Redis cho database của mình. Tuy nhiên, để tận dụng ưu thế của từng hệ quản trị cơ sở dữ liệu, chúng ta sẽ sử dụng đồng thời cả 2 hệ thống trên. Sơ đồ tổ chức database được mô tả như hình dưới đấy.

rblog_db.png

Có thể thấy là sơ đồ trên không chính xác theo thiết kế MySQL DB, vì có lẫn 2 “bảng” của Redis. Cụ thể là chúng ta sẽ lưu thông tin login của user và dữ liệu entry qua 2 bảng MySQL là users và entries. Còn danh sách những người like 1 entry sẽ lưu bằng Redis SET với key pattern là: entry:entry_id:like:users, và số like ứng với từng entry sẽ lưu bằng Redis ZSET với key là entry:like:numbers, score là số lượng like còn value là entry_id.

Thiết kế này giúp tăng tốc cho bài toàn tìm kiếm top entries được like nhiều nhất do tận dụng ưu thế của ZSET, cũng như đẩy các thao tác có tần suất cao (like/unlike) từ MySQL ra Redis để tốc độ nhanh hơn. Còn bảng user và email thường là những data có tần số thay đổi thấp, dữ liệu lớn, nên có thể lưu trong MySQL để đỡ tốn dung lượng RAM.

Xây dựng hệ thống với CakePHP

Tác giả hiện đang là 1 PHP Developer, đã từng làm việc với framework Zend, CakePHP và Phalcon. Trong 3 framework đó, nếu như Zend quá nặng nề, thì CakePHP và Phalcon đều là framework gọn nhẹ với nhiều tính năng hữu ích. Tuy nhiên Phalcon tốn khá nhiều thời gian cài đặt, cũng như do framework rất mới nên nhiều chức năng chưa hoàn chỉnh. Do đó, tác giả chọn CakePHP cho việc xây dựng RBlog bởi CakePHP giúp tạo prototype nhanh chóng. Ngoài ra CakePHP cũng có nhiều plugin rất thuận tiện cho việc cải tiến tốc độ phát triển. RBlog sử dụng plugin BoostCake cho thiết kế giao diện trên nền Boostrap, và CakeDC Migrations cho quản lý Database.

RBlog được viết bằng CakePHP, về cơ bản thì không có gì khác so với các project CakePHP khác. Tuy nhiên để làm việc với Redis, chúng ta định nghĩa thêm 1 số class theo mô hình dưới đây.

rblog_model_class1.png

Theo như mô hình trên, chúng ta có 3 class abstract để quản lý các thao tác với Redis. Các class này sử dụng biến $redis là 1 instant của class Redis (tham khảo PHP Redis). AbstractRedisModel quản lý các thao tác cơ bản về kết nối với Redis. AbstractRedisSetModel và AbstractRedisSortedSetModel quản lý các thao tác với Set và ZSet trong Redis. Cần chú ý là AbstractRedisModel thừa kế AppModel chuẩn của CakePHP, việc này nhằm định hướng cho các function sẽ viết theo cách của Cake, để các hàm ở Controller có thể gọi các hàm của Redis như Model bình thường. Cụ thể là thay vì dùng SADD, ZINCRBY,… chúng ta chỉ cần dùng save. Thay vì dùng ZRANGE, SISMEMBER,… chúng ta chỉ cần dùng find.

Mặc dù Redis có 5 kiểu dữ, nhưng ở RBlog chúng ta chỉ dùng SET và ZSET, nên chỉ cần xây dựng class cho 2 kiểu dữ liệu này. Trong trường hợp muốn làm việc với cả 5 kiểu dữ liệu, sẽ cần định nghĩa thêm 3 class nữa. Tuy nhiên do phạm vi của project, chúng ta dừng lại ở SET và ZSET.

Giao diện

Giao diện RBlog được xây dựng trên nền bootswatch-amelia, 1 theme của Twitter Bootstrap. Hình dưới đây là screen shot của RBlog, màn hình “Top liked entries”

RBlog.png

Source Code

Bạn đọc quan tâm có thể tham khảo source code của RBlog theo đường link sau. https://github.com/dinhhoanglong91/rblog


All Rights Reserved