php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 14.09.2008, 02:29  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard [Zend Lucene] Geschwindigkeit

Hallo Leute,

ich muss eine große Datenmenge mittels Zend Lucene indexieren.
Es handelt sich um eine Größenordnung von mehreren 10.000 Dokumenten die regelmäßig zum Index hinzugefügt werden müssen.
Ich habe allerdings Probleme, den benötigten Speed zu erreichen.

Meine Dokumente sind alle gleich aufgebaut und enthalten 5 Keyword-, 4 Text, und 2 UnIndexed Felder die jeweils mit ein paar kleinen (<100Byte), größtenteils Strings, Werten gefüllt sind.

Diese Dokumente erstelle ich und speichere sie in ein Array.
Zu einem bestimmten Zeitpunkt möchte ich sie alle dem Index hinzufügen. Dieser Vorgang dauert 0.02s pro Dokument, also nur 50 Docs/s, was definitiv zu langsam ist und auch eigentlich nicht angehen kann. Am Server kann es nicht liegen, es handelt sich um einen schnellen 64bit Rootserver mit 4GB RAM, wobei allein PHP 1GB zugeteilt sind.

Ob der Index noch komplett leer ist, optimiert, oder nicht optimiert ist, ich erhalte nahezu immer diesen langsamen Wert.
Die Optimierungseinstellungen MaxBufferedDocs, MaxMergeDocs, MergeFactor sind alle auf ihren Standardwerten, da Veränderungen an diesen höchstens zur Verschlimmerung der Werte geführt haben.

Hat jemand eine Idee, wo hier Flaschenhälse vorhanden sein können?

Vielen Dank für jede Antwort schon einmal an dieser Stelle, Zender

PS:
Das englischsprachige Zend Forum ist leider total unfrequentiert, sonst hätte ich direkt dort gepostet. Ich hoffe, hier gibt es jemanden, der mit Zend Lucene Search vertraut ist.
Zender ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 14.09.2008, 03:06  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Hast du die Möglichkeit mal mittels Xdebug oder einem anderen Debugger (notfalls auch in einer lokalen Testumgebung) deinen Code mal zu testen, mit aktiviertem Profiler, danach kannst du mit WincacheGrind (Windows) / KCacheGrind (Linux), die erstellten Profiles auswerten.

Ausserdem solltest du mal schauen wie die CPU-Last während dem ganzen ist, wenn es eine Dual-Core oder Quadcore-CPU ist oder auch ein System mit mehreren CPUs, hast du das Problem, dass 1 PHP-Prozess maximal einen Core nutzen kann, daher solltest du schauen, dass du mehrere Instanzen parallel laufen lässt um die Performance auch auszunutzen.

Falls du das ganze noch über den Browser ( mod_php ) laufen hast, solltest du schauen das script direkt via shell über den php-(cgi)-interpreter zu starten.

Sollte Zend_Lucene irgendwo im Dateisystem einen Cache oder ähnliches nutzen, wäre es eventuell noch möglich ein bißchen RAM für ein RAM-Drive zu reservieren und diese temp-files dort auszulagern.

Man muss auch sagen, dass laut deiner Rechnung das ganze ja "nur" ~ 3 1/2 Minuten dauert, das empfinde ich jetzt nicht unbedingt als sonderlich lange.

Was ist übrigends gemeint dass du 1GB vom RAM für php hast ?
Ist das die Einstellung für max_memory ? Darf APC (oder ein anderer Bytecode-Cache ) so viel RAM nutzen ? Memcache für Daten ? ... ?

Mehr fällt mir jetzt ohne etwas mehr über das wie und das aussenrum zu erfahren nicht mehr mehr ein.

btw gibt es auch ein deutsches Zend Framework Forum: Zend Framework Forum - Powered by vBulletin
robo47 ist offline   Mit Zitat antworten
Alt 14.09.2008, 18:36  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard

Hallo robo 47,

danke erst einmal für deine umfassende Antwort.

Zum Profiling:
Wenn ich einen Profiler zuschalte, wird die Datenmenge des Logfiles schon bei wenigen Durchläufe meines Scripts (50.000) so groß, dass ich den Profile-Vorgang abbrechen muss. Bei 1000 Durchläufen hatte ich eine 100MB-Logdatei, dort konnte ich allerdings auch nur erkennen, dass die addDocument-Funktion von Lucene den Großteil der Zeit ausmacht...

Zum RAM:
Ja, max_memory steht auf 1024MB, weitere Einstellungen habe ich nicht verändert. Ist das nötig?

Zur Ausführungsart:
Beim Aufruf über den cli-Interpreter läuft das Script minimal schneller, allerdings ist der Unterschied im Vergleich zur Dauer der Luceneoperationen vernachlässigbar.

Allgemein zur Geschwindigkeit:
Die Indexierungsgeschwindigkeit ist nach längeren Tests die ich gerade durchgeführt habe noch langsamer, etwa bei 10 Dokumenten / s.
Afaik brauche ich eine viel höhere Geschwindigkeit, es kann doch nicht sein, dass das so langsam geht
Mir ist weiterhin folgendes aufgefallen:
Ich habe ein Unique-ID-String String Feld in jedem Document. Falls ich Documents update und nicht neu erstelle, dann lösche ich das alte Dokument mit dieser ID und füge ein neues ein.
Der Löschvorgang nimmt, falls die Indizierung nur aus Updates besteht, die Hälfte der Zeit ein.

Meine Löschfunktion:

protected function Remove($guid)
{
$term = new Zend_Search_Lucene_Index_Term($guid, 'guid');
$query = new Zend_Search_Lucene_Search_Query_Term($term);

$hits = $this->Find($query);
if (count($hits) == 1)
{
$this->index->delete($hits[0]->id);
// Log::Write("Remove: " . $guid);
}
}

Ich wäre dir sehr verbunden, falls du einen Hinweis darauf hättest, warum ich diese Probleme habe. Wenn du weitere Informationen brauchst, ich liefere sie gerne.

Gruß, Zender
Zender ist offline   Mit Zitat antworten
Alt 14.09.2008, 19:32  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Zitat:
Zitat von Zender Beitrag anzeigen
Zum RAM:
Ja, max_memory steht auf 1024MB, weitere Einstellungen habe ich nicht verändert. Ist das nötig?
Naja die Frage ist ob ein einzelner Prozess überhaupt so viel braucht, der Speicher ist ja auch nicht wirklich reserviert, es ist ja nur die Angabe wie viel RAM JEDER einzelne Prozess nutzen darf. Um den Wirklichen Verbrauch des Scriptes einzuschätzen kannst du dir ja mal am ende des scripts via PHP: memory_get_peak_usage - Manual dir den maximalen Verbrauch des Scriptes in ne Log ausgeben lassen.

Was einen allgemeinen Geschwindigkeitsvorteil für alle PHP-Scripte bringt, ist der Einsatz eines BytecodeCaches wie APC, eAccelerator, PHP-Accelerator oder Zend Optimizer, denen weißt man eine feste Menge RAM zu um darin den Bytecode der Scripte zu cachen und wahlweise können dort auch Variablen von php-scripten gespeichert werden (prozess und script übergreifend).

Zitat:
Zur Ausführungsart:
Beim Aufruf über den cli-Interpreter läuft das Script minimal schneller, allerdings ist der Unterschied im Vergleich zur Dauer der Luceneoperationen vernachlässigbar.
Unter Umständen kann man durch das kompilieren von php weitere Geschwindkeitsvorteile bekommen indem man sich ein php kompiliert das nur das absolute Minimum an Extensions mitkompiliert die gebraucht werden, kann auch nochmal ein bißchen was bringen.


Ich hab gerade mal noch das Zend Manual zu Zend_Lucene überflogen, da dieser Index ja komplett auf der Festplatte gespeichert wird, hat die Festplatte auch einen großen Einfluss auf die Performance. Hier kann man verschiedenes machen, z.b. den Index auf einer extra Festplatte auslagern, die weniger ausgelastet ist oder eben, die wohl schnellste Lösung, ihn auf ein RAM-Drive auslagern. Das ganze ist aber auch abhängig von der Größe des Index.
Desweiteren bei einem Server-Ausfall bzw. Reboot ist der Index dann futsch und muss neu erstellt werden, ausser man erstellt nach jedem überarbeiten des Index ein Backup vom RAM-Drive auf die Festplatte und bastelt sich ein Script das beim Booten nach dem erstellen des RAM-Drives, das Backup auf das RAM-Drive kopiert.

Zitat:
Allgemein zur Geschwindigkeit:
Die Indexierungsgeschwindigkeit ist nach längeren Tests die ich gerade durchgeführt habe noch langsamer, etwa bei 10 Dokumenten / s.
Afaik brauche ich eine viel höhere Geschwindigkeit, es kann doch nicht sein, dass das so langsam geht
Ich kann halt absolut nicht abschätzen wie der Server ansonsten ausgelastet ist (nicht nur CPU, sondern auch IO-Auslastung der Festplatte, etc), also wo eventuelle Performance-Bottlenecks noch auftreten. Denke da wirst du noch etwas rumtesten müssen, über die Profiles sollten eventuell auch einen Hinweis darauf geben wie lange die Schreib-Operationen dauern und das ganze dann gegebenenfalls eben mal mit ner weiteren Festplatte für den Index oder aber einem RAM-Drive austesten.

Ein paar weitere Fragen und Anhaltspunkte vielleicht noch:

Ist denn die CPU während dem Indizieren durch den Prozess voll ausgelastet ? Wenn nicht wäre das eben ein eventuelles Indiz dafür, dass das Bottleneck zumindest nicht die CPU ist.
robo47 ist offline   Mit Zitat antworten
Alt 14.09.2008, 22:21  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard

Ich ermittele bereits den höchsten genutzen Ram-Wert während der Indizierung, dieser liegt bei ca 800MB, da ich eben viele Dinge auf einmal cache die dann nach und nach (teilweise) indiziert werden.
Der Server ist momentan nur für dieses Projekt reserviert, dort läuft nichts außer einer Apache/MySQL Instanz.

Der Flaschenhals muss eigentlich bei der CPU/RAM liegen, und das deutet meiner Meinung nach darauf hin, dass irgendetwas bei Lucene falschläuft.
Der Index ist danach grade mal höchstens ein paar MB groß, nichts also, womit die Festplatte in irgend einer Weise Probleme haben sollte.

Gibt es irgendwelche Einstellungen in Lucene die unbedingt getätigt werden müssen, oder angepasst werden müssen? Kann evtl ein verwendeter Zeichensatz etc dafür sorgen, dass Lucene so unglaublich langsam arbeitet? Falsche Codierung oder so?
Zender ist offline   Mit Zitat antworten
Alt 15.09.2008, 22:31  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard

Ich habe gerade noch einmal genau beobachtet:
Während dem Hinzufügen von Dokumenten nimmt sich der Prozess die mit abstand höchste CPU-Auslastung. Es muss sich also um irgendetwas Lucene-Internes handeln, oder aber eine falsche Konfigurationseinstellung.

Ich denke, normalerweise sollte das ganze doch mindestens um den Faktor 20 (wenn nicht noch wesentlich mehr) schneller laufen
Zender ist offline   Mit Zitat antworten
Alt 24.09.2008, 19:22  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard

Ich habe jetzt einmal ein kleines Testscript erstellt, mit dem ich nachvollziehen möchte, warum die Lucene Komponente so langsam arbeitet:

PHP-Code:
<?php
error_reporting
(E_ALL);
require_once (
"Zend/Search/Lucene.php");

$indexPath "./data/testindex/";
$index Zend_Search_Lucene::create($indexPath);

$documentCount 5000;

$time microtime(true);
$documents = array();
for (
$i=0;$i<$documentCount;$i++)
{
    
$doc = new Zend_Search_Lucene_Document();
    
$doc->addField(Zend_Search_Lucene_Field::Keyword('guid'"fooValue"));
    
$doc->addField(Zend_Search_Lucene_Field::Keyword('otherValue',"someOtherValue"));
    
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('intValue1'100));
    
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('intValue2'254257));
    
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('intValue3'24471));
    
$doc->addField(Zend_Search_Lucene_Field::UnIndexed('intValue4'2541));    
    
$doc->addField(Zend_Search_Lucene_Field::Text('author'"dkjfkd.../ld2&/jf 390349  8dmdk3499dssss%%"), "ISO-8859-1");    

    
$documents[] = $doc;
}
$diff microtime(true) - $time;
echo 
"Creating " $documentCount " documents: " round($diff,1) . "s<br />";

$time microtime(true);
foreach (
$documents AS $doc)
{
    
$index->addDocument($doc);
}
$diff microtime(true) - $time;
echo 
"Sending documents: " round($diff,1) . "s (" round($diff/$documentCount,4) . "s per Document)<br />";

$time microtime(true);
$index->commit();
$diff microtime(true) - $time;
echo 
"Commiting: " round($diff,1) . "s<br />";
?>
Das Script soll das Hinzufügen von 5000 Dokumenten zu einem leeren Lucene Index simulieren. Der Index ist danach nichtmal einen Megabyte groß, die Laufzeit beträgt bei mir trotzdem stattliche 45s, wovon nahezu die gesamte Zeit allein auf das Senden der Dokumente entfällt. Warum braucht Lucene hier so lange, bzw wie ist es möglich, dass ich möglichst schnell tausende Dokumente zum Index hinzufüge?
Zender ist offline   Mit Zitat antworten
Alt 25.09.2008, 20:28  
Benutzer
 
Registriert seit: 09.08.2008
Beiträge: 35
Zender befindet sich auf einem aufstrebenden Ast
Standard

Ich habe, um das hinzuzufügen, auch mit den Werten MaxBufferedDocs, MaxMergeDocs und MergeFactor herumgespielt, diese bewirken jedoch keinerlei Änderung an der Laufzeit...
Zender ist offline   Mit Zitat antworten
Alt 25.09.2008, 21:08  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Soweit ich mir den Code von Zend_Search_Lucene angeschaut habe, passiert ja auch die ganze Analyse in der methode addDocument().

Du kannst ja mal nen profiler-dump von so nem ablauf uppen, dann schau ich es mir den mal an.
robo47 ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Geschwindigkeit analysieren snatch-ic PHP Tipps 2008 3 30.05.2008 03:49
Mysql Geschwindigkeit J_Jara Datenbanken 20 18.04.2008 09:00
Geschwindigkeit von Sockets Sascha Bahl PHP-Fortgeschrittene 17 05.03.2007 21:39
Geschwindigkeit: Array vs. MySQL Jacks Rache PHP Tipps 2006 4 13.03.2006 20:45
Geschwindigkeit bei Verwenden von require/include PHP-Fortgeschrittene 11 09.03.2006 17:08
geschwindigkeit und strecke Off-Topic Diskussionen 14 17.06.2005 23:22
MySQL - Geschwindigkeit faux PHP-Fortgeschrittene 17 28.05.2005 16:04
[Erledigt] XSLT -&amp;amp;gt; Geschwindigkeit PHP-Fortgeschrittene 4 10.02.2005 09:51
[Erledigt] Geschwindigkeit einer Webseite PHP Tipps 2004 22 01.08.2004 20:42

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
zend lucene, zend lucene performance, zend search lucene, lucene zend, php lucene performance, lucene performance, php lucene index zend, php zend lucene, lucene php, zend search lucene performance, zend lucene suggest, warum ist lucene so schnell, zend lucene cache, zend_lucene, zend lucene slow, zend_search_lucene performance, zend lucene search, zend geschwindigkeit, lucene langsam, lucene geschwindigkeit

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:34 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum