Estou tendo muitos problemas com a ineficiência de node_save (). Mas o nó está salvando meu problema? É isso que estou tentando descobrir.
Eu criei um loop com 100.000 iterações. Eu criei o mínimo necessário para o objeto nó ser válido e salvar corretamente. Aqui está o código de salvamento do nó:
$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);
}
Aqui estão os resultados:
100.000 nós foram salvos, cada um usando node_save (). Demorou 5196,22 segundos para concluir. Isso é apenas 19 economiza um segundo.
Para dizer o mínimo, isso não é aceitável, especialmente quando essa pessoa recebe cerca de 1200 consultas de inserção individuais por segundo e recebe 25.000 inserções por segundo .
Então, o que está acontecendo aqui? Onde está o gargalo? É a função node_save () e como ela é projetada?
Poderia ser o meu hardware? Meu hardware é um servidor de desenvolvimento, ninguém, exceto por mim - Intel dual core, 3Ghz, Ubuntu 12.04 com 16 GB de RAM.
Enquanto o loop é executado, meu uso de recursos é: MySQL 27% de CPU, 6M de RAM; PHP 22% CPU 2M RAM.
Minha configuração do mysql foi feita pelo assistente percona .
O Mysql diz que, se o uso da minha CPU estiver abaixo de 70%, o problema estará ligado ao disco . É verdade que eu tenho apenas uma usina WD Caviar 7200 RPM, mas espero ter mais de 19 pastilhas por segundo, espero!
Há pouco tempo, escrevi sobre como salvar 30.000 nós em um dia . No entanto, para ficar claro, esse nó não tem nada a ver com forças externas. É puramente uma referência para aprender sobre como aumentar a velocidade das chamadas para node_save ().
Realisticamente, preciso inserir 30.000 itens no banco de dados a cada minuto usando o node_save. Se o nó salvar não é uma opção, pergunto-me se posso escrever minha própria função de API drupal "node_batch_save ()" ou algo que aproveite a capacidade do mysql de fazer inserções em massa com a consulta INSERT . Pensamentos sobre como abordar isso?
fonte
Respostas:
Você nunca receberá 30.000 inserções por minuto usando node_save. De jeito nenhum.
Um INSERT é rápido porque é tudo o que faz. O salvamento do nó faz várias inserções (tabela principal, tabela de revisão, uma tabela para cada campo), limpa os caches de entidade e aciona ganchos. Os ganchos são a parte complicada. Se você possui muitos módulos de contribuição (ou mesmo um que se comporta mal) que podem realmente prejudicar o desempenho, especialmente se o autor não considerou o caso de uso "Estou economizando vários nós de uma vez". Por exemplo, eu tive que adicionar isso à minha classe Migrate:
Por outro lado, se você escrever uma função de gravação personalizada que não chama ganchos, você corre o risco de obter dados inconsistentes, em um estado inesperado pelo sistema. Eu nunca recomendaria fazer isso. Inicie o xhprof e veja o que está acontecendo.
fonte
node_save()
, mas adiciona algum código para mitigar os problemas conhecidos que podem ser causados, como pathauto reconstruir o cache de menu após cada nó salvarPrimeiro, instale o XCache / APC (para PHP <5.5) e configure o memcached para o Drupal.
Então você pode otimizar sua configuração do MySQL para consultas pesadas usando o script mysqltuner disponível em: http://mysqltuner.pl
Por exemplo
Outras sugestões:
fonte
Use o módulo Mongodb para armazenar campos https://drupal.org/project/mongodb Resultados aqui: conforme http://cyrve.com/mongodb
fonte