Giải pháp performance cho việc update lượt xem hiệu quả

Đối với một website có nhiều lượt truy cập hằng ngày, giải pháp nào để việc update lượt xem cho từng bài viết cụ thể để không gây ảnh hưởng đến performance của cả hệ thống.

Nếu mỗi user truy cập vào bài viết đó mình lập tức update vào CSDL 1 lượt xem, thì 1.000 rùi 10.000 user truy cập vào cùng 1 lúc thì hệ thống có chịu nổi không?

Anh em nào có giải pháp tốt nhất cho việc này xin chia sẻ để mọi người cùng tham khảo nhé !

Trả lời:

Đối với website có lượt truy cập cao như vậy thì bạn nên hạn chế những thao tác liên quan đến database, bạn có thể dùng redis để lưu trữ những record này, rồi muốn insert vào database thì set cron để chạy lấy dữ liệu từ redis để import vào database. Hoặc tốt hơn nữa thì dùng php-resque, nghĩa là sẽ dùng background task để xử lý. Bạn có thể tham khảo thêm https://github.com/chrisboulton/php-resque

Trong trường hợp này không thể cứ update vào CSDL hoài được, cần phải có cơ chế cache, ví dụ:

  • Bài viết đang xem có id là 123, lượt xem là 100
  • Bạn sẽ lưu vào cache với key là baiviet_123, value là 100
  • Người dùng đọc bài viết, bạn sẽ tăng giá trị của key baiviet_123 lên 100 + 1 = 101
  • Người tiếp theo vào thì cứ tăng lên thành 102, 103, 104...
  • Bạn cần 1 cái worker (hoặc đặt cron job cũng được), update cái số lượt xem cho bài viết có id = 123 trong CSDL theo một thời gian định sẵn nào đó (1 tiếng, 2 tiếng, nửa ngày...)
  • Khi hiển thị số lượt xem bài viết bạn cũng phải lấy từ cache lên

Cache thì có thể dùng memcached, apc, redis...

Thank mọi người đã quan tâm!

Trong trường hợp mình sử dụng cơ chế cache, có vẻ như ổn. Nhưng mình có vài thắc mắc:

Nếu như dùng memcached, apc theo mình biết thì ưu điểm của nó là get key nhanh, nhưng khi server mất điện hoặc là restart server thì mọi key lưu sẽ mất hết, lúc đó thì bài viết sẽ mất một số lượt xem mà chưa kịp chạy cron job -> Hướng giải quyết ?

Trong trường hợp mình sài redis thì nó có cơ chế backup lại key data khi server mất điện hoặc restar, nhưng mà khi get key thì mình cảm thấy hơi chậm cực kỳ.?

Ý kiến mọi người thế nào?

Ở các website nhiều truy cập, người ta sẽ setup proxy nghịch để anonymous request sẽ không tới trực tiếp PHP Application nếu như nội dung cho nó đã được cache. Nếu đây là cách mà website bạn đang sử dụng, có lẽ việc đếm lượt xem sẽ trở nên khó khăn hơn. Có hai cách tui nghĩ có thể sử dụng được:

  1. Viết một app riêng, sử dụng Redis làm storage server. Ngôn ngữ kịch bản thì sử dụng cái gì cũng được, cố gắng dùng cái nào chịu tải càng cao càng tốt, thí dụ như nodejs chẳng hạn. Cron job của bạn sẽ được setup để đồng bộ các số đếm ở app này với app chính.

  2. Cho Google Analytics lo hết mọi việc, mỗi giờ (cái này tuỳ bạn), cho cron job fetch nội dung các trang được xem trong vòng một giờ trở lại, từ các con số đếm có được, bạn lại update vào app chính.

Redis nếu sử dụng theo cách thông thường thì với lượng dữ liệu nhỏ thì cỡ vài trăm key thì tốc độ không thành vấn đề. Còn nếu với lượng dữ liệu lớn cỡ vài trăm ngàn key trở lên thì bạn phải dùng cơ chế pipeline của redis. Bạn tham khảo thêm tại đây https://groups.google.com/forum/#!topic/redis-db/q7EdSUejzaU