Estoy teniendo muchos problemas con la ineficiencia de node_save (). ¿Pero el nodo salva mi problema? En última instancia, eso es lo que estoy tratando de descubrir.
Creé un bucle con 100,000 iteraciones. Creé el mínimo para que el objeto de nodo sea válido y se guarde correctamente. Aquí está el código de guardado del nodo:
$node = new stdClass();
$node->type = "test_page";
node_object_prepare($node);
$node->uid = 1;
$node->title = $node_title;
$node->status = 1;
$node->language = LANGUAGE_NONE;
if($node = node_submit($node)){
node_save($node);
}
Aquí están los resultados:
Se guardaron 100,000 nodos, cada uno usando node_save (). Tardó 5196.22 segundos en completarse. Eso es SOLO 19 salvamentos por segundo.
Por decir lo menos, eso no es aceptable, especialmente cuando esta persona recibe alrededor de 1200 consultas de inserción individuales por segundo , y esta persona obtiene 25,000 inserciones por segundo .
Entonces, ¿qué está pasando aquí? ¿Dónde está el cuello de botella? ¿Es con la función node_save () y cómo está diseñado?
¿Podría ser mi hardware? Mi hardware es un servidor de desarrollo, nadie más que yo, Intel dual core, 3Ghz, Ubuntu 12.04 con 16 gigas de ram.
Mientras el ciclo se ejecuta, mi uso de recursos es: MySQL 27% CPU, 6M RAM; PHP 22% CPU 2M RAM.
Mi configuración mysql fue realizada por el asistente de percona .
Mysql dice que si el uso de mi CPU es inferior al 70%, mi problema está relacionado con el disco . De acuerdo, solo tengo una ejecución del molino WD Caviar 7200 RPM, ¡pero espero obtener más de 19 inserciones por segundo!
No hace mucho tiempo escribí sobre salvar 30,000 nodos en un día . Sin embargo, para ser claros, este nodo no tiene nada que ver con ninguna fuerza externa. Es puramente un punto de referencia aprender sobre cómo aumentar la velocidad de las llamadas a node_save ().
Siendo realistas, necesito ingresar 30,000 elementos en la base de datos cada minuto usando node_save. Si el guardado de nodos no es una opción, me pregunto si puedo escribir mi propia función api de drupal "node_batch_save ()" o algo que aproveche la capacidad de mysql para hacer inserciones masivas con la consulta INSERT . ¿Pensamientos sobre cómo abordar esto?
fuente
Respuestas:
Nunca obtendrá 30 000 inserciones por minuto usando node_save. De ninguna manera.
Un INSERT es rápido porque eso es todo lo que hace. Node save realiza múltiples inserciones (tabla principal, tabla de revisión, una tabla para cada campo), borra cualquier caché de entidad y dispara ganchos. Los ganchos son la parte difícil. Si tiene muchos módulos contrib (o incluso uno que se porta mal) que realmente pueden matar el rendimiento, especialmente si el autor no tuvo en cuenta el caso de uso "Estoy ahorrando una tonelada de nodos a la vez". Por ejemplo, tuve que agregar esto a mi clase Migrate:
Por otro lado, si escribe una función de guardado personalizada que no invoca ganchos, está en claro peligro de obtener datos inconsistentes, en un estado inesperado por el sistema. Nunca recomendaría hacer eso. Enciende xhprof y mira lo que está sucediendo.
fuente
node_save()
, pero agrega un código para mitigar los problemas conocidos que pueden ser causados, como Pathauto reconstruyendo el caché del menú después de cada guardado de nodoEn primer lugar, instale XCache / APC (para PHP <5.5) y configure memcached para Drupal.
Luego puede optimizar su configuración de MySQL para consultas pesadas utilizando el script mysqltuner disponible en: http://mysqltuner.pl
P.ej
Otras sugerencias:
fuente
Utilice el módulo Mongodb para almacenar campos https://drupal.org/project/mongodb Resultados aquí: según http://cyrve.com/mongodb
fuente