Hallo,
ich beschäftige mich seit ein paar Tagen mit der Performance unserer TYPO3-Site (V. 3.8.0). Sie läuft auf einem Apache 2.0 (SuSE 9.2) mit einer Doppel-CPU und 1 GB RAM. MySQL-Version ist 4.1.
Durch die Installation von eAccelerator habe ich schon mal einen ordentlichen Schub erreichen können. Die Apache-Konfiguration ist auch ganz ordentlich angepasst.
MySQL key_buffer_size und table_cache sind soweit auch optimal eingestellt. Die meisten key_reads werden aus dem RAM bedient, die Festplattenzugriffe sind minimal.
So weit, so gut. Nach langem Probieren und Beobachten komme ich aber so langsam zu dem Schluß, dass der Query-Cache von MySQL überhaupt nicht mit TYPO3 zurecht kommt. Mein Verhältnis von Qcache_inserts und Qcache_hits ist mit 1,03 atemberaubend schlecht. Es scheint, als sei bei TYPO3 fast jedes SELECT einzigartig.
Selbst wenn ich die Größe des Caches auf 100 MB erhöhe, ändert sich nichts an den schlechten Werten.
Wie habt Ihr dieses Problem gelöst? Einfach ignorieren und es hinnehmen? Oder den Cache einfach wieder ausschalten? Oder auf die Suche im Quelltext gehen, und Queries, die garantiert nicht aus dem Cache bedient werden können, mit SQL_NO_CACHE erweitern?
Was mich auch interessieren würde: Hat jemand von Euch ein TYPO3 laufen, das bessere Werte beim Query-Caching erzielt?
Hier noch ein paar Zahlen:
| Com_select | 377633 |
| Qcache_queries_in_cache | 24189 |
| Qcache_inserts | 377509 |
| Qcache_hits | 388217 |
| Qcache_lowmem_prunes | 135806 |
| Qcache_not_cached | 72 |
| Qcache_free_memory | 25720288 |
| Qcache_free_blocks | 3383 |
| Qcache_total_blocks | 52328 |
| Key_read_requests | 3296183 |
| Key_reads | 7740 |
Das schlechte Verhältniss kann ich (leider) bestätigen:
22312596 / 22320781 ( = 0,9996) (inserts / hits)
Mein QCache ist 20 MB groß und es sind im Durchschnitt (über ein Jahr) 13 MB belegt.
Cache auf keinen Fall ausschalten, ein bisschen was bringt er ja. Dann müßte man sich mal anschauen, welche Queries da gestellt werden. Ich hab da schon so einen Verdacht ...
Deine recht kleine Cache-Größe wundert mich etwas. Obwohl mein Cache 100 MB groß ist, habe ich jede Menge lowmem_prunes. Ist meine Site so viel größer als Deine?
Meine aktuell höchste Seiten-ID ist die 625. Dazu kommen noch ziemlich viele Extensions (TemplaVoila, css-styled-content, news, indexed_search, tt_board, DAM, ldap_sync, ...), ca. 200 PDFs im DAM, eine Hand voll Benutzergruppen, ca. 30 FE-User und 10 BE-User.
Oder läuft bei mir etwas schief, dass dieser Cache nicht ausreicht?
Die höchste Seiten-ID und die Anzahl der installierten Extensions sagt doch nichts darüber aus, wie groß der Query-Cache sein will.
Wenn ich mal davon ausgehe, daß die Standardseite aus normalen Inhaltstypen + tt_news besteht, dann schau ich mir die Größe dieser Tabellen an, weil auf diese Tabellen wohl die meisten SELECTS gemacht werden.
Meine Datenbank ist ingesamt 250 MB groß, tt_content hat 1 MB, und die tt_news knapp 150 kb. Dann brauch ich doch keinen 100 MB großen QC. Der Sinn des QC ist ja nicht, die ganze Datenbank im Speicher zu halten (dann nimmst du einen anderen Datenbanktypp), sondern nur häufige Abfragen.
Da muß ich Dir widersprechen. Die Größe des benötigten Query-Cache hat nur am Rande etwas mit der Größe der DB-Tabellen zu tun. Der Query-Cache cached ja keine Tabellen (dafür ist der Table-Cache zuständig), sondern nur die Results von Selects. Und je mehr Extensions ich verwende, desto höher ist die Wahrscheinlichkeit, dass jedes Select anders ist.
In der Folge hat man also dieselben Inhalte mehrfach im Query-Cache liegen. Vermutlich wäre die optimale Lösung, den Query-Cache für das Backend auszuschalten. Nur wie will man das machen?
Die Größe des benötigten Query-Cache hat nur am Rande etwas mit der Größe der DB-Tabellen zu tun.
Wenn eine Tabelle 1MB groß ist, so wird ein SELECT kaum mehr als 1MB zurückgeben (Typo3 geht recht sparsam mit Joins um).
Das nur Resultate gecacht werden, habe ich im übrigen auch geschrieben.
Wie gesagt: Man muß sich mal die einzelnen Abfragen anschauen, wie die aufgebaut sind.
woida schrieb
Die Größe des benötigten Query-Cache hat nur am Rande etwas mit der Größe der DB-Tabellen zu tun.
Wenn eine Tabelle 1MB groß ist, so wird ein SELECT kaum mehr als 1MB zurückgeben (Typo3 geht recht sparsam mit Joins um).
Das nur Resultate gecacht werden, habe ich im übrigen auch geschrieben.
Hmm, es ist immer noch nicht ganz klar geworden. Noch ein Versuch:
Bleiben wir bei dem Beispiel mit der 1 MB großen Tabelle. Sagen wir, die hat die Spalten id, content und timestamp. Und jetzt hast Du eine Seite, wo alle News angezeigt werden, die nicht älter als 14 Tage sind. Dein Select sieht also in etwa so aus:
SELECT id, content FROM tabelle WHERE timestamp > 12345678
wobei "12345678" der aktuelle Timestamp minus 14 Tage ist.
Diese Seite wird 10 mal pro Minute aufgerufen und liefert ein Resultset, das 10 KB groß ist. Wie oben ersichtlich, ist jedes einzelne select unterschiedlich. Nach einer einzigen Stunde hat man also 60x10x10 KB = 6 MB Daten im Query Cache liegen, obwohl die Tabelle nur 1 MB groß ist.
Das ist für das FE natürlich ein extremes Beispiel. Schaut man sich aber das BE an, ist o.g. Beispiel noch harmlos.
Nochmal zurück zu meiner ursprünglichen Frage:
In den Kommentaren in der Doku von mysql.com habe ich die Tage eine Diskussion gelesen, in der auch ein Supportler von mysql mitredete. Leider habe ich mir die URL nicht gespeichert.
Kernaussage war, dass der "Königsweg" ist, Selects mit immer anderer where-Klausel nicht zu cachen, also mit dem Zusatz SQL_NO_CACHE zu versehen.
Wenn ich es richtig verstanden habe, ist es aber bei extremen Mißverhältnissen performanter, den Cache abzuschalten.
Mein Wunsch wäre also, dass man per TS den Zusatz SQL_NO_CACHE für bestimmte Elemente vorgeben könnte. Dann muss man nicht im Quelltext fummeln. Vielleicht wäre das ein feature-request für zukünftige Releases. Mit dem neuen DB-Layer ist ja der Grundstein dafür schon gelegt.
Hat sich sonst noch jemand damit beschäftigt? Ich wäre froh über weitere Erfahrungsberichte. In meinen Augen ist das nämlich der engste Flaschenhals von TYPO3. Erschwerend kommt dazu, dass die Verwendung von Indexes bei den meisten Extensions stiefmütterlich behandelt wird. Besonders mit kombinierten Indexes über mehrere Spalten ließe sich viel verbessern.
P.S.: Schön übrigens, dass die Contentspalte hier nicht mehr hinter die rechte Spalte rutscht.
Das ist sehr interessant, was Du schreibst.
Hast Du Dir mal den Artikel durchgelesen ?
http://typo3.org/development/articles/testing-and-tuning-typo3-performance/
Ansonsten empfehle ich Dir, eine Diskussion in der dev-Liste anzuregen (oder zu schauen, ob es solch eine schon gibt). Da bekommst Du vll. auch Hinweise von den Core-Entwicklern.
Hallo,
ja, den Artikel kenne ich. Der war übrigens einer der Auslöser, warum ich mich näher mit der Performance beschäftigt habe.
Das einzige, was ich nicht nachvollziehen kann, ist das hier:
because TYPO3 does a lot of repetitive queries, so caching queries should work well
Aufgrund meiner Status-Zahlen von mysql würde ich glatt das Gegenteil behaupten. Ist meine Installation wirklich so exotisch? Das kann ich nicht glauben. Die Anzahl der Besucher ist mit 300 bis 600 pro Tag auch nicht so hoch, dass man von einer High-Traffic-Site sprechen könnte.
Eigentlich habe ich auch überhaupt keine Probleme mit der load des Servers. Meistens idlet der recht gelangweilt vor sich hin. Aber in den regelmäßigen Fällen, in denen der Cache einer Seite abläuft, dauert die Neu-Generierung oft so lange, dass man mehrere Sekunden die weiße Seite mit dem Hinweis "Page ist being generated..." sieht.
Und genau daran will ich schrauben. Das finde ich nicht schön, dass ein ausreichend dimensionierter Server in diesen Fällen nicht flotter die Seite erstellt.
Mittlerweile bin ich fast so weit, das Thema Query-Cache abzuhaken. Stattdessen scheint es sich mehr zu lohnen, an den Indexes zu optimieren. Obwohl ich mich damit auf ein Gebiet begebe, das ich eigentlich nicht betreten wollte. Nämlich Änderungen zu machen, die nicht standardkonform sind und bei einem Update möglicherweise verworfen werden.
Eine andere Idee wäre, bei einem abgelaufenen Seiten-Cache die neue Seite nicht erst beim Aufruf durch einen Client zu erstellen. Die Umsetzung scheint mir aber fast unmöglich. Für einzelne Seiten, bei denen der Cache deutlich kürzer als 24 Stunden gültig ist, könnte man es mit einem wget-Aufruf per cronjob realisieren. Aber für die große Masse kann man das wohl nicht automatisieren. Schade eigentlich. Das Problem ist, dass ein abgelaufener Cache erst dann vom System erkannt wird, wenn ein Client die Seite anfordert.
Ansonsten finde ich das Caching-Konzept von TYPO3 im Vergleich zu anderen CMS übrigens hervorragend.
Diese Seite wird 10 mal pro Minute aufgerufen und liefert ein Resultset, das 10 KB groß ist. Wie oben ersichtlich, ist jedes einzelne select unterschiedlich. Nach einer einzigen Stunde hat man also 60x10x10 KB = 6 MB Daten im Query Cache liegen, obwohl die Tabelle nur 1 MB groß ist.
Richtig. An diesen Fall hatte ich nicht gedacht. Aber es scheint, als ob SELECTS, die nur einmal gestellt wurden nicht im QC bleiben, bis dieser Vollläuft, sondern schon vorher ausgesondert werden.
woida schrieb
Aber es scheint, als ob SELECTS, die nur einmal gestellt wurden nicht im QC bleiben, bis dieser Vollläuft, sondern schon vorher ausgesondert werden.
Ganz bestimmt nicht. Worauf stützt Du diese These?