Leak Memory Ruby on Rails và cài đặt jemalloc

Bối cảnh Chào mọi người ! Mình làm một dự án cũng khá là lâu, dự án được cái cũng có số lượng người dùng tương đối, nên cũng may mắn được trải nghiệm vấn đề như thế này: Server batch (dùng để chạy sidekiq job) cứ khoảng 1 tuần với số lượng người dùng

Bối cảnh

Chào mọi người ! Mình làm một dự án cũng khá là lâu, dự án được cái cũng có số lượng người dùng tương đối, nên cũng may mắn được trải nghiệm vấn đề như thế này:

  1. Server batch (dùng để chạy sidekiq job) cứ khoảng 1 tuần với số lượng người dùng đủ lớn thì sẽ càng ngày càng leak memory và không giải phóng, hậu quả đương nhiên là chiếc server già cỗi nó cứ cảnh báo liên tục. Em Bot cảnh báo vì thế mà hoạt động hết công suất.
  2. Cũng đau đầu, mình có nhảy vào check các job đang hoạt động bằng câu lệnh quen thuộc ps aux|gref sidekiq
    Và kết quả là [0 of 25 busy] chẳng thấy cái job nào được chạy cả. Tương tự kiểm tra queue job sidekiq cũng không thấy gì bất thường.
  3. Chạy htop để theo dõi %CPU %MEM => thì thấy tác vụ liên quan đến ruby đang chiếm % khá cao.
  4. Giải pháp tạm thời cho vấn đề trên là restart lại sidekiq. Mọi thứ lại okie cho đến 1 tuần sau đó =))

Nguyên nhân và cài đặt jemalloc

1. Nguyên nhân

Như mình đã nói ở trên, phán đoán ban đầu nguyên nhân ngọn thì nó là do leak memory, các tác vụ xử lý xong không giải phóng bộ nhớ và càng ngày sẽ càng đầy. Tuy nhiên nguyên nhân gốc rễ thì mình tìm được ở bài viết này taming-rails-memory-bloat. Vấn đề về cấp phát bộ nhớ cũng như khả năng giải phóng của ruby on rails khi sử dụng sidekiq được mô tả khá chi tiết ở trong bài viết, mình không đề cập thêm. Bài viết có đề cập rằng việc sử dụng jemalloc mang lại kết quả khả quan (giảm việc sử dụng bộ nhớ, tránh phân mảnh … đến hơn 4 lần). Nói chung cái này phải cài thử và có thời gian theo dõi thực tế thì chúng ta mới có đánh giá khách quan được.

2. Cài đặt jemalloc

  • Cài đặt jemalloc lên server và theo dõi (nó chỉ là reinstall ruby với option jemalloc thôi nhé):

sudo apt install libjemalloc-dev rvm reinstall 2.5.1 -C --with-jemalloc

  • Sau khi cài đặt thì check thử xem đã cài đặt thành công chưa bằng câu lệnh:

ruby -r rbconfig -e "puts RbConfig::CONFIG['LIBS']"

  • Kết quả trả về có chứa ‘jemalloc’ là được:

-lpthread -ljemalloc -lgmp -ldl -lcrypt -lm

Lưu ý:Mình đã cài đặt thử trên các môi trường Dev, stag để test lại các chức năng dự án trước khi được cấp phép install nó trên Production. Các chức năng hoạt động bình thường, tuy nhiên để test leak memory thì do việc sử dụng chủ yếu là QA, số lượng request khôgn đủ nhiều, nên có thể chưa có đánh giá nào đó rõ ràng, mọi người cân nhắc trước khi sử dụng nhé.

3. Một số cách thủ công khác

Crontab restart sidekiq
  • Tại sao tôi lại gọi là thủ công, vì như ở đầu bài viết có đề cập, việc restart lại sidekiq sẽ giúp giải phóng thủ công memory. Do đó tuỳ theo dự án của bạn như thế nào thì có thể chạy crontjob để restart sidekiq thủ công. Tuy nhiên phải có những lưu ý sau:
  • Cơ chế restart sidekiq của bạn không làm mất các job đang chạy mà chỉ đẩy lại các job về queue và lôi ra xử lý lại.
  • Nên viết một file sidekiq.service trong thư mục /etc/systemd/system để dùng câu lệnh sudo service sidekiq restart được dễ dàng hơn. (Nội dung file service này tôi sẽ không ghi chi tiết ở đây vì có thể nó không phù hợp với dự án của bạn, tuy nhiên hiểu đơn giản thì cách dùng của nó cũng tương tự một file bash script mà thôi, khác cái là đứng đâu bạn cũng có thể sử dụng được câu lệnh trên).
Config concurency của sidekiq
  • Như ở ví dụ đầu tiên sau khi check ra [0 of 25 busy] chúng ta cứ hiểu là tôi đang sử dụng concurency config của sidekiq là 25. Theo link bài viết đã được dẫn ở trên cũng đã để cập đến vấn đề này, tất nhiên việc giảm con số này sẽ giúp giảm leak memory, nhưng cũng nên cân bằng với spec dự án, để đưa ra con số cho phù hợp.

Tổng kết

Bài viết trên đây là một vài kiến thức tôi thu nhặt được trong quá trình xử lý vấn đề leak memory của dự án, mục đích viết bài vừa để chia sẻ kinh nghiệm cá nhân đến những ai đang gặp vấn đề tương tự, cũng như là một NOTE cho chính bản thân. Thật vui nếu như bài viết nhận được những comment bổ sung kiến thức của quý bạn đọc, nó sẽ là kinh nghiệm quý báu không chỉ cho tôi mà còn cho những ai có thể view được bài viết này.
(Bài viết là trải nghiệm ban đầu sau khi cài đặt jemalloc, mình sẽ update kết quả đánh giá sau một thời gian sử dụng để so sánh hiệu quả).

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ