옛글/Ruby on the Rails

[Ruby on rails] Sidekiq이 버벅거린다면, Rails sidekiq process 갯수 늘리기

ShakeJ 2017. 4. 13. 19:14

동접자가 많아지고 백그라운드 잡이 많아지면 점점 서버가 느려지고 백그라운드 잡이 실패하는 경우도 생깁니다.


Redis Server > Sidekiq > Background Job (내부에서 Mysql 쿼리문을 던짐) > 반복 

인 경우, 몇백개의 작업이 동시에 실행되면 Mysql database에 동시 접속 가능한 Pool의 갯수가 작을 경우 default로 설정된 타임아웃(5초)로 인해 Background Job이 실패를 하는 경우가 있습니다!


첫번째로는 일단 Mysql의 pool을 늘려주어야 합니다. Mysql에 쿼리를 보내면 처리하는 종업원의 수를 늘려봅니다.


실서버의 /shared/config/database.yml을 만져줍시다. 


production:

adapter: mysql2

...: ...   

pool: 50 


종업원의 숫자를 50명으로 늘려줍니다. 

혹시나 데이터베이스에서 사용한 버퍼 메모리가 작을 수 있으니 체크를 해봅니다. 


mysql -u root -p 로 접속 후, 

mysql> SHOW STATUS LIKE '%innodb_buffer_pool%'; 




bytes_data 를 보시면 현재 34메가를 사용중이네요. 혹시나 가용 버퍼 메모리를 바꾸고 싶다면,


vi etc/mysql/my.cnf에 해당 세팅을 추가한 후 리스타트 하시면 됩니다. 


[mysqld] 

… 

innodb_buffer_pool_size = 64M


자 이제 Pool은 늘렸으니 Sidekiq에서 일을 하는 종업원 수를 늘릴 차례입니다. 


initializer/sidekiq.rb 를 들어갑니다 (없으시면 생성하시면 됩니다.)


Sidekiq.configure_server do |config|

  ActiveRecord::Base.connection.disconnect!

  ActiveRecord::Base.configurations['production']['pool'] = 50

  #ActiveRecord::Base.configurations['staging']['pool'] = 50

  ActiveRecord::Base.establish_connection

end


혹시나 Staging 에도 Pool을 설정하시려면 추가하시면 됩니다. 다만 database.yml 에 Staging이 없으면 deploy 시 아예 Sidekiq이 뜨지 않기 때문에 조심하셔야 합니다.

위와 같이 완료가 되면, 데이터베이스와 Sidekiq 두 부분 모두 동시에 처리가능한 Pool의 숫자가 올라가게 됩니다! 



+ Unicorn에도 Worker 갯수를 지정할 수 있습니다. 

실제로 클라이언트단에서 들어오는 요청들에 처리를 해주는 Unicorn worker의 갯수도 변경이 가능합니다. 
config/unicorn/production.rb 에 보시면, worker_processes 8 라는 옵션이 있습니다. 
말 그대로 8개의 worker를 돌린다는 의미입니다. 
해당 worker는 한 클라이언트에서 요청이 들어와서 처리가 되는 동안 다른 클라이언트에서 요청이 들어오면 다른 worker에서 처리를 하게 됩니다. 무작정 worker를 올리게 되면 메모리가 가득차 Unicorn이 죽어버리는 경우도 있으니, newrelic등으로 메모리 사용량을 보며 조정합시다! (사실 동접자 몇천명 단위가 아닌 이상 2개만 해도 충분합니다)