Como aprovechar al máximo tu servidor

Este post comienza con la inquietud de migrar un blog que recibe hasta 100,000 visitas diarias, es decir que cuando se pública en esta red, genera hasta 1,000 requests por segundo, dependiendo la nota y el título, muchas de estas veces, se llegaba hasta 2,900 visitas simultáneas en tiempo real en Google Analytics usando WordPress y Mediatemple.

El punto es que al comenzar y hace un propio CMS para poder tener un control total de la comunidad sin atenernos a Buddypress, Cubepoints y otros plugins que lo que hacen es quitarte visitas saturando la base de datos.

Cual fue mi sorpresa al poner la app en producción, anunciarla y ver que se cayera y el load average subiera por los cielos con tan solo 50 visitas simultaneas:

Esto fue difícil de asimilar, porque un server de 1 GB en RAM de Amazon EC2 solo soporta 50 visitas.

Después de indagar, aprendí que esto se debe a que el sitio no debería estar generando vistas ni queries cada que tiene visitas, esto utiliza mucho CPU y RAM en. Por otro lado, estaba usando Apache2, y nginx tiene mejor performance según las gráficas.

apachevsnginx

Lo comprobé  haciendo el experimento nuevamente y podemos observar que logra soportar más de 100 usuarios simultáneos, definitivamente nginx funciona mejor que apache2 para optimizar recursos del server.

Ahora después de todo esto, el server se colgó de nuevo, ¿Pero que pasa?

Lo que pasa es que no se esta usando la tecnología de Cache correctamente, esto lo que hace, al primer visitante genera el query a la base de datos y el render de la vista, pero si cacheamos el query y la vista, a la segunda visita ya no va a hacer ningún query. Entonces observemos las vistas y veamos su performance:

laravelcache

Eso hace muchos queries, apesar de usar eager loading, eso sobrecalienta los servers de la base de datos y se cuelga debido a que ocupa 15.25MB en RAM del servidor cargar esto y distribuirlo porque renderea la vista y todos los querys.

Pero si esto lo cacheamos correctamente, podremos ahorrar quizá la mitad de recursos del servidor y poder repartir la carga con Amazon AWS ElastiCache.

Así que ya agregue un método en los controllers para poder cachear tanto los queries como la vista completa para reducir considerablemente el tiempo de carga:

priemracarga

Como podemos ver se redució considerablemente el tiempo de carga de 1,140 milisegundos a 211.25 milsegundos, es decir = 928.75 milisegundos menos.  Esto quiere decir que las siguientes cargas durante 60 minutos van a ser cacheada hasta que pasen estos 60 minutos la próxima carga del request que siga.

Para el código:

 public function viewPost($slug)
{
if(\Cache::has('post-'.$slug)) { //Se checa si no hay ya algo cacheado
$post = Cache::get('post-'. $slug); // Si si, entonces cargarlo y retornalo
return $post;
}
Cache::store('redis')->put('post-'.$slug, $this->cachePost($slug), 60); //Si no se encuentra entonces guardalo
$post = Cache::get('post-'. $slug);
return $post;
}

Y la funcion de cachePost()


<span style="line-height: 1.7;">public function cachePost($slug) </span><span style="line-height: 1.7;">{</span>

$post = \App\models\Post::where('slug', $slug)->with('user')->first();
if($post->type == 'video')
{
$info = Embed::create($post->featured_media);
$post->featured_media = $info->code;
$post->featured = $info->image;
$info->width = 650;
return \View::make('frontend.post', compact('post'))->render();
}
return \View::make('frontend.post', compact('post'))->render();
}

Y esta es otra vista que muestra videos, cargaba muy lento porque tenia muchos queries y vista, vean ahora como quedo:

otravista

Ahora viene la prueba final, hacer el commit y push para despues darle pull en el servidor y configurar .env las variables environment para usar Amazon AWS ElastiCache y redis y hagamos la prueba en la página que se nos caía cuando se hacían muchos requests:

ramsuccess

Podemos observar que de 542 milisegundos que tomó abrir la primera vez que no estaba cacheada, bajo a 83 milisegundos, y el ram disminuyó casi ¡20 megas en RAM!
Cachear es genial, pero ahora debo setear los tiempos para esto, que incremente, a menos que se edite o un comentario sea agregado.

Hagamos la prueba con tráfico para ver como se comporta y si puede tolerar más visitas de las de antes:

Como podemos observar ya soporta requests recurrentes ocupando menos CPU y menos RAM. Lo cual nos permite estabilizar el servidor y lograr economizar más en Elastic Beasntalk.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s