Sử dụng cơ sở dữ liệu bản sao với các mô hình ActiveRecord của bạn

Tram Ho

Thỉnh thoảng, chúng ta phải đối mặt với vấn đề: đi cùng với mô hình Mysql thông thường, chúng ta cũng có một replica database.

Replica database này dường như được giữ đồng bộ với database production, nhưng nó không được sử dụng bởi các web servers hay các background workers, mọi thứ trong đó chỉ có thể được sử dụng làm dữ liệu đọc(read-only).

Tại sao chúng ta quan tâm đến nó? Trong các hệ thống lớn ngày nay, thường có các page dashboard, trên đó có một số tính năng làm việc với lượng thông tin dữ liệu lớn như: hiển thị các số liệu thống kê, thông tin về trạng thái của một số modul trong hệ thống…
Trong các bài toán này, vấn đề sẽ đơn giản nếu chúng ta không phải quan tâm đến các số liệu thống kê realtime, thì chỉ việc truy vấn các dữ liệu trong database và lưu kết quả vào cache.

Mọi việc sẽ trở nên phức tạp nếu chúng ta quan tâm đến các số liệu chính xác theo thời gian thực, chính xác đến từng giây, khi đó vấn đề tối ưu các câu truy vấn nhằm trả về các số liệu nhanh và chính xác nhất là nhiệm vụ then chốt. Đó là lúc các bạn có thể cần đến replica database, và tìm hiểu mô hình kết nối nó với Active Record trong ứng dụng Rails.

Ý tưởng ban đầu của chúng ta là implement trên mỗi table riêng biệt mà chúng ta muốn sử dụng khi truy vấn replica:

Trong đó, config leadfeeder_replica_#{env} được định nghĩa trong file database.yml cho mỗi môi trường mà chúng ta sử dụng(development, test, production…), bằng cách này chúng ta sẽ có được sự linh hoạt trong các câu truy vấn:

Như các bạn có thể thấy, dường như không thực sự DRY để định nghĩa các modul này trong mỗi model. Ngoài ra chúng ta phải nhớ gọi readonly! trên các bản ghi replica để ngăn chăn việc ghi vào database này. Việc này có thể được thực hiện tự động cho mỗi model bằng việc sử dụng callback after_initialize trong active record:

Nhưng điều này vẫn chưa giải quyết được vấn đề DRY trên các model. Giải pháp được đưa ra là sử dụng ActiveSupport::Concern kết hợp với callback included:

Base use cases only

Điều gì sẽ xảy ra khi truy vấn trên các model quan hệ, trên các bảng được join với nhau:

Thật là không may, trong trường hợp này, nó sẽ không trả về Account::Replica mà chỉ trả về instance Account. Nó cũng query trực tiêp vào database production khi chúng ta sử dụng lazy loading account.

Source:

https://medium.com/@konole/using-replica-database-with-your-activerecord-models-b2a8ce9ef46

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo