Mam dużo problemów z nieefektywnością node_save (). Ale czy węzeł zapisuje mój problem? Właśnie tego próbuję się dowiedzieć.
Utworzyłem pętlę ze 100 000 iteracjami. Stworzyłem absolutne minimum, aby obiekt węzła był poprawny i poprawnie zapisany. Oto kod zapisu węzła:
$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);
}
Oto wyniki:
Zapisano 100 000 węzłów, każdy za pomocą node_save (). Wykonanie tego zadania zajęło 5196,22 sekund. To TYLKO 19 oszczędza sekundę.
Mówiąc co najmniej, jest to nie do przyjęcia, szczególnie gdy ta osoba otrzymuje około 1200 pojedynczych zapytań na sekundę , a ta osoba otrzymuje 25 000 wstawek na sekundę .
Co się tu dzieje? Gdzie jest wąskie gardło? Czy jest z funkcją node_save () i jak jest zaprojektowana?
Czy to może być mój sprzęt? Mój sprzęt to serwer programistyczny, nikt na nim poza mną - dwurdzeniowy Intel, 3Ghz, Ubuntu 12.04 z 16 gigabajtami pamięci RAM.
Podczas działania pętli moje użycie zasobów to: MySQL 27% CPU, 6M RAM; PHP 22% CPU 2M RAM.
Moja konfiguracja mysql została wykonana przez kreatora Percona .
Mysql mówi, że jeśli użycie procesora spadnie poniżej 70%, mój problem jest związany z dyskiem . To prawda, że mam tylko jeden bieg młyna WD Caviar 7200 RPM, ale mam nadzieję, że powinienem otrzymywać więcej niż 19 płytek na sekundę, mam nadzieję!
Nie tak dawno temu pisałem o oszczędzaniu 30 000 węzłów dziennie . Jednak dla jasności ten węzeł nie ma nic wspólnego z żadnymi siłami zewnętrznymi. Jest to wyłącznie test porównawczy, aby dowiedzieć się, jak zwiększyć szybkość wywołań funkcji node_save ().
Realistycznie muszę co minutę wprowadzać do bazy danych 30 000 elementów za pomocą node_save. Jeśli zapisywanie węzłów nie jest opcją, zastanawiam się, czy mogę napisać własną funkcję API drupal „node_batch_save ()” lub coś, co wykorzystuje zdolność mysql do wykonywania wstawiania zbiorczego za pomocą zapytania INSERT . Myśli, jak do tego podejść?
źródło
Odpowiedzi:
Nigdy nie dostaniesz 30 000 wstawek na minutę za pomocą node_save. Nie ma mowy.
INSERT jest szybki, ponieważ to wszystko, co robi. Węzeł save wykonuje wiele wstawek (tabela główna, tabela wersji, tabela dla każdego pola), czyści wszelkie pamięci podręczne jednostek i odpala haki. Haki są trudną częścią. Jeśli masz wiele modułów contrib (lub nawet takich, które źle się zachowują), które mogą naprawdę zabić wydajność, szczególnie jeśli autor nie wziął pod uwagę przypadku użycia „Oszczędzam mnóstwo węzłów naraz”. Na przykład musiałem dodać to do mojej klasy Migrate:
Z drugiej strony, jeśli napiszesz niestandardową funkcję składowania, która nie wywołuje żadnych przechwyceń, istnieje wyraźne niebezpieczeństwo otrzymania niespójnych danych w stanie nieoczekiwanym przez system. Nigdy nie zalecałbym tego. Odpal xhprof i zobacz, co się dzieje.
źródło
node_save()
, ale dodaje trochę kodu do złagodzenia znane problemy, które mogą być spowodowane np Pathauto odbudowy cache menu po każdym węźle oszczędzaniaPrzede wszystkim zainstaluj XCache / APC (dla PHP <5.5) i skonfiguruj memcached dla Drupala.
Następnie możesz zoptymalizować konfigurację MySQL pod kątem ciężkich zapytań, używając skryptu mysqltuner dostępnego na stronie: http://mysqltuner.pl
Na przykład
Inne sugestie:
źródło
Użyj modułu Mongodb do przechowywania pól https://drupal.org/project/mongodb Wyniki tutaj: zgodnie z http://cyrve.com/mongodb
źródło