400% CPU y 5% Ram, realmente estoy programando mal?

Iniciado por bavo08, 27 Octubre 2014, 05:42 AM

0 Miembros y 2 Visitantes están viendo este tema.

bavo08

Estimados,

Soy multidisciplinario y si tengo que ser sincero el PHP no es mi fuerte, es más, sigo utilizando mysql_query(), mysql_fetch_array() y row respectivamente para dar una noción, además no toco nada de POO.

Lo que sucede ultimamente es que tengo un tráfico creciente y estoy en una constante carrera contrareloj por enmendar errores de desarrollo iniciales como por ejemplo, llamar a tablas mysql muy grandes y buscarlas por alfanumeros y no por el índice, solo por dar un ejemplo.

La situacione se está saliendo de contról al punto en que tengo los 4 núcleos del servidor consumiendose mientras que solo un 5% de ram.

Algunos crons y mostrar información con cierto delay ha ayudado a reducir un poco el consumo, pero nada fuera del otro mundo... es decir, nada relevante.

El problema, básicamente radica en el consumo exajerado de mysql, en grán parte por utilizar búsquecas con cámpos que no responden a índices sinó a alfanumericos en tablas muy muy grandes y otras cosas.

Sabiendo que mi nivel de conocimiento es bajo / intermedio, ¿que me recomiendan? puedo mejorar el código aún más, pero sacrifico funciones, puedo generar jobs que hagan ciertas tareas que requieran mucho consumo cada X tiempo, pero tampoco es la grán cosa.

La realidad es que todo en conjunto ayuda, quizás reduzca el consumo en un 50%, pero, ¿existe algo de que me esté perdiendo y permita ser aún más eficiente?

¿Es normal que grán parte del consumo esté dado por MySQL? ¿Esto se dá en la mayoría de los proyectos?


Mil gracias desde ya!

engel lex

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

MinusFour

Pueden ser varios factores que hagan que el servidor SQL empieze a usar todo el CPU. Yo empezaría por checar, que las conexiones a mysql las esten cerrando propiamente (en especial si estas usando conexiones persistentes) y que no estes ejecutando muchas queries en tablas gigantescas sobre campos no indexados.

Debugea tus queries desde PHPmyAdmin, si mal no recuerdo te regresa el tiempo que tardan cada una de las queries.

bavo08

#3
Cita de: engel lex en 27 Octubre 2014, 05:50 AM
cuantas visitas por minuto tienes?

Tengo unas 300 - 400 mil visitas / ejecuciones / interacciones por día, esta cantidad varía según el horario habiendo picos y valles. Es decir, en ocasiones puede llegar a haber 10 peticiones por segundo y luego 4-5 y así...




Cita de: MinusFour en 27 Octubre 2014, 06:02 AM
Pueden ser varios factores que hagan que el servidor SQL empieze a usar todo el CPU. Yo empezaría por checar, que las conexiones a mysql las esten cerrando propiamente (en especial si estas usando conexiones persistentes) y que no estes ejecutando muchas queries en tablas gigantescas sobre campos no indexados.

Debugea tus queries desde PHPmyAdmin, si mal no recuerdo te regresa el tiempo que tardan cada una de las queries.

Exacto, cada tanto tengo queries que temoran 3-4 segundos en resolverse, claramente (o según yo tengo entendido) el problema puede venir por ahí cuando se arma un cuello de botella y dispara el consumo. Una vez, hace meses atrás ya habia depurado las tablas y pasé de pagar 200U$D por un server a uno de 20U$D, es decir, tenía claramente un problema de eficiencia.

Ahora las cosas no están tán mal como ántes, pero sigue siendo alto.



Mod: No hacer doble post. Existe el botón modificar.

moikano→@

#4
Yo te recomendaría que utilizases indices en las tablas de mysql y, sobretodo, que si las tablas se te hacen muy grandes puede que sea porque necesitas dividirlas, por ejemplo, si guardas visitas en una tabla y esta no la partes en años, meses o incluso dias (dependiendo del tamaño) puede que al final tengas una tabla de gigas imposible de consultar en segundos, incluso con índices.

Luego también podrías pensar en migrar las partes que tienen que ser mas rápidas a mongodb o incluso redis, pero esto sería mas avanzado y te tocaría aprender NOSQL.

Por otra parte, revisa tus consultas SQL's, puede que estes haciendo consultas repetidamente cuando en realidad con un INNER o con una SUBCONSULTA podrías hacerlo en solo una.

Por último no está de más hacer un debug del tiempo de ejecución de tus php's, para eso te recomiendo XDEBUG.

Al final lo que te quería decir:
-Tablas pequeñas y rápidas de consultar.
-Pasar tablas mas críticas a mongodb o redis.
-Revisar o que te revisen las consultas SQL.
-Revisar código PHP con xdebug o cualquier otra aplicación.

bavo08

Cita de: moikano→@ en 27 Octubre 2014, 13:55 PM
Yo te recomendaría que utilizases indices en las tablas de mysql y, sobretodo, que si las tablas se te hacen muy grandes puede que sea porque necesitas dividirlas, por ejemplo, si guardas visitas en una tabla y esta no la partes en años, meses o incluso dias (dependiendo del tamaño) puede que al final tengas una tabla de gigas imposible de consultar en segundos, incluso con índices.

Luego también podrías pensar en migrar las partes que tienen que ser mas rápidas a mongodb o incluso redis, pero esto sería mas avanzado y te tocaría aprender NOSQL.

Por otra parte, revisa tus consultas SQL's, puede que estes haciendo consultas repetidamente cuando en realidad con un INNER o con una SUBCONSULTA podrías hacerlo en solo una.

Por último no está de más hacer un debug del tiempo de ejecución de tus php's, para eso te recomiendo XDEBUG.

Al final lo que te quería decir:
-Tablas pequeñas y rápidas de consultar.
-Pasar tablas mas críticas a mongodb o redis.
-Revisar o que te revisen las consultas SQL.
-Revisar código PHP con xdebug o cualquier otra aplicación.

Cool, muy elaborada tu respuesta, pues creo que si, hay una tabla centrál que debe tener varios millones de filas, las demás no tienen tanto. Lo peor de ello es que de esos varios millones en muchas ocacioens no busca en índices.

Lo de particionar las tablas se puede automatizar de alguna manera? Es decir, imagina que me aya olvidado de generar la tabla para "noviembre" manualmente, sería desastroso, un crash terrible si es que comienza a usar una tabla que no existe.

¿Se automatizan esas cosas?

Creo que voy a utilizar estas:

Cita de: moikano→@ en 27 Octubre 2014, 13:55 PM
Al final lo que te quería decir:
-Tablas pequeñas y rápidas de consultar.
-Revisar o que te revisen las consultas SQL.

Sé que el problema pasa por SQL ya que con un simple TOP veo que es el único proceso que consume 350 - 380% del CPU.

Mil gracias!


MinusFour

Antes que te metas en algo relativamente complicado como lo es sharding u otros tipos de horizontal partitioning yo te recomendaría que empezaras por indexar correctamente tus campos. MySQL soporta horizontal partitioning, pero va a depender de como estan compuestos tus campos y como haces las queries.

moikano→@

Cita de: MinusFour en 27 Octubre 2014, 16:42 PM
Antes que te metas en algo relativamente complicado como lo es sharding u otros tipos de horizontal partitioning yo te recomendaría que empezaras por indexar correctamente tus campos. MySQL soporta horizontal partitioning, pero va a depender de como estan compuestos tus campos y como haces las queries.

Eso es cierto. Lo primero son los índices, ten en cuenta que no hablamos de las primary keys, hablamos de otra cosa, aunque consultes con un campo tipo date puedes hacer indices de esos campos. Consúltalo y verás.

CitarLo de particionar las tablas se puede automatizar de alguna manera? Es decir, imagina que me aya olvidado de generar la tabla para "noviembre" manualmente, sería desastroso, un crash terrible si es que comienza a usar una tabla que no existe.

Esto es relativamente fácil. Puedes crear, por programación, las tablas del mes en el mismo momento que vayas a insertar la fila y el mes no exista.
Eso si, haz una nomenglatura razonable y que te dure tiempo, no pongas "noviembre".

Tu caso es mas típico de lo que crees. PHP es un lenguaje fácil de aprender pero también fácil de aprender malas costumbres.

JorgeEMX

Cita de: bavo08 en 27 Octubre 2014, 15:35 PM
Cool, muy elaborada tu respuesta, pues creo que si, hay una tabla centrál que debe tener varios millones de filas, las demás no tienen tanto. Lo peor de ello es que de esos varios millones en muchas ocacioens no busca en índices.

También depende mucho el alcance de tus datos al hacer los querys. Así sea una tabla de miles de millones de registros, si necesitas datos recientes deberías empezar por ordenar los resultados de forma descendente. Y después, de asegurarte sólo de regresar los registros necesarios. Es decir, usar limites (clausula limit) dentro de lo que sea posible.

Dudo mucho que usar NoSQL sea una solución viable a usar en poco tiempo, ya que contiene otra lógica y forma de estructura y entonces tendrías que cambiar la obtención de los datos en la mayoría de procesos. A menos que, en toda la aplicación uses llamadas tipo REST y que tus procesos ya tengan definida una estructura gral de salida que sea con la que trabajes (en este caso, sólo quedaría armar tus base de datos NoSQL de la misma forma). Pero por lo que dices, casi estoy seguro que revuelves PHP con HTML y demás cosas.

Sobre PHP, podrías empezar por crear estadísticas de cuanto lleva cada proceso. Aunque aquí la mayoría de problemas viene de crear ciclos infinitos o muy pesados para tareas muy simples, de sobrecargar variables ocupando mucha memoria y de crear ifs anidados enormes sin mucho sentido.