{"id":158,"date":"2009-09-05T13:56:46","date_gmt":"2009-09-05T16:56:46","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=158"},"modified":"2009-12-30T13:28:46","modified_gmt":"2009-12-30T15:28:46","slug":"como-evitar-dog-pile-effect-no-rails","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2009\/09\/como-evitar-dog-pile-effect-no-rails\/","title":{"rendered":"Como evitar que a sua aplica\u00e7\u00e3o Rails seja derrubada pelo dog-pile effect"},"content":{"rendered":"
Todo mundo j\u00e1 ouviu falar de escalabilidade. Todo mundo tamb\u00e9m j\u00e1 ouviu falar de Memcached<\/a>. O que nem todos ouviram falar ainda \u00e9 do dog-pile effect e de como evitar esse problema. Mas antes de discutirmos sobre o que \u00e9 o dog-pile effect, vamos primeiro dar uma olhada em como \u00e9 simples usar o Memcached com o Rails.<\/p>\n Se voc\u00ea nunca usou o Memcached com Raills ou ainda n\u00e3o conhece muito sobre escalabilidade com Rails, os epis\u00f3dios do Scaling Rails<\/a> feitos pelo Gregg Pollack<\/a> s\u00e3o extremamente recomendados, especialmente o epis\u00f3dio<\/a> sobre Memcached.<\/p>\n Dado que voc\u00ea tem o Memcached instalado e quer us\u00e1-lo dentro do seu aplicativo Rails, basta voc\u00ea ir em um dos arquivos de configura\u00e7\u00e3o, por exemplo o production.rb e colocar:<\/p>\n Por padr\u00e3o, o Rails vai procurar por um processo do Memcached rodando no localhost na porta 11211.<\/p>\n Mas pra qu\u00ea eu vou querer usar o Memcached? Bem, digamos que o seu aplicativo possui alguma p\u00e1gina que precise rodar uma query lenta no banco de dados, tal como uma query para gerar um ranking de blog posts baseados na influencia dos autores, que demora em m\u00e9dia 5 segundos. Nesse caso, toda vez que um usu\u00e1rio entrar nessa p\u00e1gina do seu aplicativo, essa query ser\u00e1 executada e o aplicativo ter\u00e1 um tempo de resposta muito alto.<\/p>\n Como voc\u00ea n\u00e3o vai querer que todo usu\u00e1rio sofra esperando 5 segundos para ver o ranking, o que voc\u00ea faz? Armazena o resultado dessa query no Memcached. Assim, uma vez que o resultado da query estiver cacheado, seus usu\u00e1rios n\u00e3o ter\u00e3o que esperar pelos malditos 5 segundos!<\/p>\n Legal, voc\u00ea est\u00e1 cacheando o resultado da query do ranking e voc\u00ea finalmente vai poder dormir a noite. Ser\u00e1 mesmo?<\/p>\n Vamos supor que voc\u00ea est\u00e1 expirando o cache baseado no tempo, ou seja, digamos que a query cacheada deva expirar ap\u00f3s 5 minutos. Vejamos como esse processo funciona diante de dois cen\u00e1rios:<\/p>\n Um \u00fanico usu\u00e1rio acessando depois do cache ficar obsoleto (stale):<\/b><\/p>\n Nesse primeiro cen\u00e1rio, quando um usu\u00e1rio acessar a p\u00e1gina do ranking, a query deve ser executada novamente, fazendo com que a CPU do seu sistema tenha um pico de consumo para conseguir process\u00e1-la. Depois dos 5 segundos, seu usu\u00e1rio, poder\u00e1 visualizar o ranking. At\u00e9 aqui, ok, demorou, mas o usu\u00e1rio conseguiu ver o ranking e seu sistema (ainda) est\u00e1 de p\u00e9.<\/p>\n N usu\u00e1rios acessando depois do cache ficar obsoleto (stale):<\/b><\/p>\n Digamos que, em um dado hor\u00e1rio, essa p\u00e1gina do seu aplicativo tenha em m\u00e9dia 4 requests\/segundo. Nesse cen\u00e1rio, entre a chegada do primeiro request e o banco de dados retornar o resultado da query, passar\u00e3o 5 segundos e ocorrer\u00e1 algo em torno de 20 requests. O problema \u00e9, todos esses 20 requests ir\u00e3o dar cache miss e seu aplicativo executar\u00e1 a query em todos os casos, consumindo muitos recursos de CPU e mem\u00f3ria. Esse \u00e9 o dog-pile effect.<\/p>\n Dependendo de quantas requests resultarem em cache miss, do qu\u00e3o pesado for o processamento de sua query e dos recursos de infra dispon\u00edveis, o dog-pile effect pode acabar derrubando sua aplica\u00e7\u00e3o!<\/p>\n Caramba!!! Quer dizer que o dog-pile effect \u00e9 t\u00e3o s\u00e9rio assim e pode chegar a derrubar minha aplica\u00e7\u00e3o!? Sim, isso pode acontecer. Mas existem algumas solu\u00e7\u00f5es para evitarmos esse tipo de problema. Vamos dar uma olhada em uma delas.<\/p>\nRails com Memcached<\/h3>\n
\r\nconfig.cache_store = :mem_cache_store\r\n<\/pre>\n
O que \u00e9 o dog-pile effect?<\/h3>\n