Best Practice zum Aufzeichnen einer großen Anzahl von Treffern in der MySQL-Datenbank

Lesezeit: 4 Minuten

Nun, das ist die Sache. Nehmen wir an, mein zukünftiges PHP-CMS muss täglich 500.000 Besucher anlocken und ich muss sie alle in der MySQL-Datenbank aufzeichnen (Referrer, IP-Adresse, Zeit usw.). Auf diese Weise muss ich 300-500 Zeilen pro Minute einfügen und 50 weitere aktualisieren. Das Hauptproblem besteht darin, dass das Skript die Datenbank jedes Mal aufruft, wenn ich eine neue Zeile einfügen möchte, was jedes Mal der Fall ist, wenn jemand auf eine Seite schlägt.

Meine Frage, gibt es eine Möglichkeit, eingehende Treffer zuerst lokal zwischenzuspeichern (und was ist die beste Lösung für APC, CSV …?) Und sie beispielsweise alle 10 Minuten regelmäßig an die Datenbank zu senden? Ist das eine gute Lösung und was ist die beste Vorgehensweise für diese Situation?

  • Außerdem, was ist der beste Weg, um zu verfolgen einzigartig Besucher (pro IP-Adresse) auf diesem großen Tisch?

    – lebhaftgrün

    17. Mai 2011 um 14:55 Uhr

  • SELECT DISTINCT ( ip ) FROM access_log

    – Entstehung

    18. Juni 2011 um 23:11 Uhr

Benutzer-Avatar
OZ_

500.000 täglich sind es nur 5-7 Abfragen pro Sekunde. Wenn jede Anfrage 0,2 Sekunden lang bedient wird, haben Sie fast 0 gleichzeitige Anfragen, sodass Sie sich keine Sorgen machen müssen.
Selbst wenn Sie 5-mal mehr Benutzer haben – alles sollte gut funktionieren.
Sie können einfach verwenden VERZÖGERT EINFÜGEN und tune dein mysql.
Zum Thema Tuning: http://www.day32.com/MySQL/ – Es gibt ein sehr nützliches Skript (ändert nichts, zeigt Ihnen nur die Tipps zur Optimierung der Einstellungen).

Sie können Memcache oder APC verwenden, um zuerst das Protokoll dorthin zu schreiben, aber mit INSERT DELAYED erledigt MySQL fast die gleiche Arbeit und wird es besser machen 🙂

Verwenden Sie dafür keine Dateien. DB wird Sperren viel besser bedienen als PHP. Es ist nicht so einfach, effektive Mutexe zu schreiben, also lassen Sie DB (oder Memcache, APC) diese Arbeit erledigen.

  • +1 für eine vollständigere Antwort und Diskussion von INSERT DELAYED

    – Kevin Peno

    17. Mai 2011 um 15:58 Uhr

Eine häufig verwendete Lösung:

Sie könnten einen Zähler in implementieren Zwischenspeicher die Sie bei einem Besuch erhöhen und alle 100 (oder 1000) Treffer ein Update an die Datenbank senden.

  • Einen Speichercache anstelle eines Dateicaches (wie in einer anderen Antwort) zu haben, ist bei weitem schneller! +1

    – Matthieu Napoli

    17. Mai 2011 um 13:28 Uhr

Wir tun dies, indem wir lokal auf jedem Server in CSV speichern und dann einen winzigen Cron-Job haben, um die Einträge in die Datenbank zu pushen. Damit soll vermieden werden, dass vor allem eine hochverfügbare MySQL-Datenbank benötigt wird – die Datenbank sollte in der Lage sein, diese Menge an Einfügungen problemlos zu bewältigen.

Speichern Sie sie irgendwo in einer verzeichnisbasierten Datenbank (oder Flatfile, hängt davon ab) und verwenden Sie zu einem bestimmten Zeitpunkt einen PHP-Code, um sie in Ihre MySQL-Datenbank einzufügen/aktualisieren. Ihr PHP-Code kann regelmäßig mit Cron ausgeführt werden, also überprüfen Sie, ob Ihr Server über Cron verfügt, damit Sie den Zeitplan dafür festlegen können, sagen wir alle 10 Minuten.

Schauen Sie sich diese Seite an: http://damonparker.org/blog/2006/05/10/php-cron-script-to-run-automated-jobs/. Einige Codes wurden in die Cloud geschrieben und können von Ihnen verwendet werden 🙂

Eine Möglichkeit wäre zu verwenden Apache access.log. Sie können eine ziemlich feine Protokollierung erhalten, indem Sie verwenden Chronolog Dienstprogramm mit Apache . Cronolog verwaltet die Speicherung einer sehr großen Anzahl von Zeilen in Dateien und kann sie basierend auf Tag, Jahr usw. des Volumens rotieren. Die Verwendung dieses Dienstprogramms verhindert, dass Ihr Apache unter Protokollschreibvorgängen leidet.

Verwenden Sie dann, wie von anderen gesagt, einen Cron-basierten Job, um diese Protokolle zu analysieren und die gewünschten zusammengefassten oder Rohdaten in MySQL zu übertragen.

Sie können für schreibintensive Jobs eine dedizierte Datenbank (oder sogar einen Datenbankserver) mit bestimmten Einstellungen verwenden. Beispielsweise benötigen Sie möglicherweise keinen InnoDB-Speicher und behalten ein einfaches MyIsam. Und Sie könnten sogar an einen anderen Datenbankspeicher denken (wie von @Riccardo Galli gesagt)

Benutzer-Avatar
Markus B

Wenn Sie sich unbedingt direkt bei MySQL anmelden MÜSSEN, sollten Sie die Verwendung von zwei Datenbanken in Betracht ziehen. Einer, der für schnelle Einfügungen optimiert ist, was bedeutet, dass keine anderen Schlüssel als möglicherweise ein auto_increment-Primärschlüssel vorhanden sind. Und ein weiteres mit Schlüsseln für alles, was Sie abfragen würden, optimiert für schnelle Suchen. Ein zeitgesteuerter Job würde regelmäßig Treffer aus der Nur-Einfüge-Datenbank in die Nur-Lese-Datenbank kopieren, und Sie erhalten am Ende das Beste aus beiden Welten. Der einzige Nachteil ist, dass Ihre verfügbaren Statistiken nur so frisch sind wie der vorherige “Kopie”-Lauf.

Benutzer-Avatar
MarkR

Ich habe auch zuvor ein System gesehen, das die Daten in einer flachen Datei auf der lokalen Festplatte auf jedem Webserver aufzeichnet (achten Sie darauf, nur atomare Anhänge zu machen, wenn Sie mehrere Prozesse verwenden) und sie regelmäßig asynchron mit einem Daemon-Prozess in die Datenbank zu schreiben oder Cron-Job.

Dies scheint die vorherrschende optimale Lösung zu sein; Ihre Webanwendung bleibt verfügbar, wenn die Überwachungsdatenbank ausgefallen ist, und Benutzer leiden nicht unter Leistungseinbußen, wenn die Datenbank aus irgendeinem Grund langsam ist.

Das einzige, was ich sagen kann, ist, dass Sie diese lokal generierten Dateien überwachen – eine Anhäufung weist definitiv auf ein Problem hin und Ihre Ops-Ingenieure bemerken es sonst möglicherweise nicht.

1245440cookie-checkBest Practice zum Aufzeichnen einer großen Anzahl von Treffern in der MySQL-Datenbank

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy