12/08/2018, 13:48

Tăng tốc ứng dụng Rails với model cache sử dụng Redis

Giới thiệu Đối với các ứng dụng nhỏ vấn đề về hiệu năng thường ít được chú ý đến, nhưng với những ứng dụng lớn, việc cải thiện hiệu năng trở nên quan trọng. Tối ưu câu truy vấn hay sử lý tắc nghẽn như N + 1 query thuộc danh sách các việc cần làm. Một trong các hướng tiếp cận tốt nhất để cải ...

caching_banner.jpg

Giới thiệu

Đối với các ứng dụng nhỏ vấn đề về hiệu năng thường ít được chú ý đến, nhưng với những ứng dụng lớn, việc cải thiện hiệu năng trở nên quan trọng. Tối ưu câu truy vấn hay sử lý tắc nghẽn như N + 1 query thuộc danh sách các việc cần làm. Một trong các hướng tiếp cận tốt nhất để cải thiện hiệu năng đó là model caching.

Trong bài viết này, sẽ trình bày phương pháp caching model sử dụng Redis.

Khái quát Redis

1. Redis là gì?

Redis là một hệ thống dữ liệu key-value, mỗi giá trị được quản lý bằng một cặp khóa và giá trị. Khi ghi dữ liệu ta phải chỉ rõ cặp khóa và giá trị, khi đọc dữ liệu ta phải chỉ rõ ta muốn đọc giá trị ở khóa nào. Trong Redis, khóa (value) có thể là một chuỗi, giá trị của dữ liệu (value) có thể là một trong số kiểu dữ liệu thông dụng:

  • Tập hợp (set)
  • Tập hợp đã sắp xếp (sorted set)
  • Chuỗi (string)
  • Danh sách (list) Bên cạnh việc lưu trữ dữ liệu theo dạng key-value trên RAM với hiệu năng cao, redis còn hỗ trợ lưu trữ dữ liêu trên đĩa cứng (persistent redis) cho phép phục hồi dữ liệu khi gặp sự cố.

2. Tại sao sử dụng Redis?

  • Redis hỗ trợ thêm mới, cập nhật và loại bỏ dữ liệu một cách nhanh chóng.
  • Lưu trữ dữ liệu dạng key-value
  • Data được lưu trên RAM, tắc tốc độ đọc ghi
  • Key có thể hết hạn hoặc không
  • Nhanh, nhẹ nhàng
  • Persistence redis
  • Hỗ trợ nhiều database
  • Truy vấn theo kiểu key
  • Redis lấy và nạp dữ liệu trên Ram, nhưng đồng thời dữ liệu có thể được lưu trên đĩa cứng giúp dễ dàng phục hồi khi có sự cố
  • Key là một string nhưng value có thể là một trong các dạng dữ liệu: hash, list, string, set

Thực hành

1. Cài đặt Redis

curl -O http://redis.googlecode.com/files/redis-2.2.2.tar.gz
tar xzf redis-2.2.2.tar.gz
cd redis-2.2.2
make
cp src/redis-server src/redis-cli /usr/bin

2. Khởi động Redis

redis-server

3. Ví dụ

Chúng ta sẽ tạo một ứng dụng nhỏ và đặt tên nó là SnippetDemo

rails new SnippetDemo

Tạo một resource Snippet

rails generate scaffolt Snippet content:text

Chúng ta sẽ sử dụng gem rack-mini-profiler để hiển thị tốc độ page, và gem Faker để tạo dữ liệu test. Thêm hai gem trên vào file Gemfile sau đó chạy lệnh bundle install

gem "rack-mini-profiler"
gem "faker"

Trong file db/seed.rb ta tạo dữ liệu, lưu lại sau đó chạy lệnh rake db:seed

100000.times do
  Snippet.create(content: Faker::Lorem.paragraph)
end

Cài đặt home page trỏ đến snippets index trong file config/routes.rb

root 'snippets#index'

Kết quả khi không sử dụng Redis

long responser.png

Sử dụng Redis

Cài đặt gem

gem "redis"
gem "redis-namespace"
gem "redis-rails"
gem "redis-rack-cache"

Thêm config trong file config/application.rb

..
module SnippetDemo
  class Application < Rails::Application
    ..
    config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', { expires_in: 90.minutes }
    ..
  end
end

Sử dụng Redis namespace, trong file config/initializers/redis.rb

$redis = Redis::Namespace.new("site_point", :redis => Redis.new)

Thay vì load dữ liệu từ DB ta thực hiện như sau

def fetch_snippets
  snippets =  $redis.get("snippets")
  if snippets.nil?
    snippets = Snippet.all.to_json
    $redis.set("snippets", snippets)
    # Expire the cache, every 5 hours
    $redis.expire("snippets",5.hour.to_i)
  end
  @snippets = JSON.load snippets
end

Lần đầu tiên cần load danh sách từ cơ sở dữ liệu, sau đó đẩy vào trong cache. Từ những lần load dữ liệu tiếp theo sẽ load trực tiếp từ trong cache. Ta thấy tốc độ load được cải thiện dõ dàng.

low responser.png

Kết luân

Redis là một công cụ mạnh giúp caching dữ liệu, nhằm cải thiện hiệu năng ứng dụng của bạn.

Nguồn tham khảo

http://www.victorareba.com/tutorials/speed-your-rails-app-with-model-caching-using-redis http://ktmt.github.io/blog/2013/07/16/tim-hieu-redis-2/

0