Wie implementieren hintergrund/asynchrone write-behind-caching in PHP?
Habe ich eine bestimmte PHP-Seite, die aus verschiedenen Gründen speichern muss ~200 Felder in einer Datenbank. Diese sind 200 separate insert und/oder update-Anweisungen. Nun ist die offensichtliche Sache zu tun ist, diese Zahl zu reduzieren, aber, wie ich schon sagte, aus Gründen, die ich gewonnen ' T die Mühe gehen in ich kann das nicht tun.
Ich hatte nicht erwartet, mit diesem problem. Wählt scheinen einigermaßen performant in MySQL aber inserts/updates nicht (es dauert etwa 15-20 Sekunden, um dieses update aus, was natürlich inakzeptabel ist). Ich habe geschrieben in Java/Oracle-Systeme, die glücklich machen Tausende von inserts/updates in der gleichen Zeit (in beiden Fällen läuft die lokalen Datenbanken; MySQL 5 vs OracleXE).
Nun in so etwas wie Java-oder .Net, ich könnte ganz leicht führen Sie einen der folgenden Schritte aus:
- Schreiben Sie die Daten auf einer in-memory
write-behind-cache (ie, es würde
wissen, wie beibehalten der Datenbank
und so tun könnte asynchron); - Schreiben Sie die Daten auf einer in-memory-cache
und die Nutzung der PaaS (Persistenz als
Service) - Modell ie, ein Zuhörer auf die
cache bestehen bleiben würden die Felder; oder - Einfach einen Hintergrundprozess starten
das könnte beibehalten der Daten.
Die minimale Lösung ist, um eine cache, die kann ich einfach update, die GESONDERT gehen und Update der Datenbank in seine eigene Zeit (dh, es wird sofort wieder nach update der in-memory-cache). Dies kann entweder ein globaler cache oder session-cache (obwohl eine global shared cache vorhanden Reiz in andere Art und Weise).
Andere Lösungen zu diesem problem?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollten Sie in der Lage sein zu tun 200 Einsätze relativ schnell, aber das hängt von vielen Faktoren ab. Wenn Sie mit einer Transaktions-engine und tun jeder in seine eigene Transaktion, nicht - das macht viel zu viel I/O.
Wenn Sie eine nicht-Transaktions-engine, wird es ein wenig kniffliger. Mit einem einzigen multi-row-insert ist wahrscheinlich besser als die Spülung-Politik von MySQL bedeutet, dass Sie brauchen nicht zu erröten, seine änderungen, die nach jeder Zeile.
Sie wirklich wollen, um in der Lage zu reproduzieren über Ihre Produktion-spec "development box" und analysieren Sie genau, warum es passiert. Es sollte nicht schwierig sein, zu stoppen.
Natürlich, eine andere Möglichkeit ist, dass deine Einsätze sind langsam, wegen der extremen Größe der Tabellen oder einer großen Zahl von Indizes - in diesem Fall sollten Sie skalieren Sie Ihre Datenbank-server entsprechend. Einlegen viele Zeilen in eine Tabelle, deren Indizes passt nicht ins RAM (oder nicht RAM richtig konfiguriert ist, um für die Zwischenspeicherung verwendet werden diejenigen Indizes) in der Regel wird ziemlich stinkig.
ABER nicht versuchen Sie, einen Weg, erschwert Ihre Anwendung, wenn es einen Weg gibt, der leicht zu drehen, statt, unter Beibehaltung der bisherigen Algorithmus.
Eine weitere Lösung, die man verwenden könnte (anstelle von tuning mysql 🙂 ) ist die Nutzung von einigen JMS-server und STOMP-Verbindung-Treiber für PHP zum schreiben von Daten auf Datenbank-server in einer asynchronen Weise. ActiveMQ verfügen über eine integrierte Unterstützung für STOMP-Protokoll. Und es ist StompConnect Projekt STOMP proxy für alle JMS-compilant-server (OpenMQ, JBossMQ etc).
mysql_query('INSERT INTO tableName VALUES(...),(...),(...),(...)')
Oben angegebene query-Anweisung ist besser. Aber wir haben eine andere Lösung zur Verbesserung der Leistung von insert-Anweisung.
Befolgen Sie die folgenden Schritte..
1. Erstellen Sie einfach eine csv-Datei(Komma-getrennt durch Trennzeichen getrennte Datei)oder einfach eine txt-Datei, und schreiben Sie alle Daten, die Sie einfügen möchten, mit dem Datei schreiben-Mechanismus (wie FileOutputStream-Klasse in Java).
2. verwenden Sie diesen Befehl,
3, wenn Sie nicht klar über diesen Befehl befolgen Sie dann die link
Blick auf die Statistik für Ihre Datenbank, während Sie die Einsätze. Ich bin raten, dass man Ihre updates sperrt die Tabelle, und daher sind alle Ihre Aussagen stehen in einer Warteschlange und erleben Sie diese Verzögerung. Andere Sache, zu suchen ist, ist die index-Erstellung/Aktualisierung, weil die mehr Indizes auf einer Tabelle, die alle langsamer
UPDATE
undINSERT
Aussagen bekommen.Andere Sache ist, dass ich glaube, Sie verwenden
MYISAM
(Tabelle engine), die sperrt die gesamte Tabelle auf AKTUALISIEREN.Ich schlage vor, Sie verwendenINNODB
statt.INNODB
langsamer aufSELECT
-Abfragen sind, sondern auch schneller aufINSERT
undUPDATE
weil es nur sperren die Zeile, die es ' s arbeiten, und nicht die gesamte Tabelle.Beachten Sie, dass wenn Ihre Tabelle EINFÜGEN-NUR (nicht löscht, und keine updates auf Spalten mit variabler Länge), fügt dann nicht sperren oder blockieren, liest bei der Verwendung von MyISAM.
Dies kann oder kann nicht verbessern die performance von Gewindeeinsätzen, aber es könnte helfen, wenn Sie mit gleichzeitigen insert - /lese-Probleme.
Ich bin mit dieser, und nur entfernen alte Aufzeichnungen täglich, gefolgt von 'optimize table'.
Können Sie aktualisieren Sie Ihre lokalen cache (hoffentlich memcached) ein und dann drücken Sie die write-Anforderungen über beanstalkd.
Ich würde vermuten, dass ein problem mit den SQL-inserts - es sollte wirklich nicht so lange dauert. Wäre vorbereitete Abfragen helfen? Hat dein mysql-server müssen etwas mehr dedizierten Speicher auf der Schlüsselraum? Ich denke, dass noch einige weitere Fragen müssen gestellt.
Wie machst du die inserts, machst du einen insert pro Datensatz
oder verwenden Sie eine einzige Abfrage
Dem späteren der beiden Optionen ist wesentlich schneller, und aus Erfahrung die erste option bewirkt, dass es wesentlich länger dauert als PHP muss warten, bis die erste Abfrage zu beenden, bevor die zweite, und so weiter.
Bedenken Sie:
können Sie CURL mit PHP zu tun Asynchrone Datenbank-Manipulationen.
Eine mögliche Lösung ist die Gabel jede Abfrage in einem separaten thread, aber PHP doesnot threads unterstützen. Wir können PCNTL Funktionen, aber es ist ein bisschen schwierig für mich, Sie zu benutzen. Ich benutze lieber diese andere Lösung zu erstellen, die Gabel und führen Sie asynchrone Vorgänge.
Finden Sie diese
http://gonzalo123.wordpress.com/2010/10/11/speed-up-php-scripts-with-asynchronous-database-queries/