Boardunity & Video Forum

Boardunity & Video Forum (https://boardunity.de/)
-   Entwicklung und Konzeption sozialer Software (https://boardunity.de/entwicklung-konzeption-sozialer-software-f76.html)
-   -   Konzept: Speichern von geparsten Beiträgen (https://boardunity.de/konzept-speichern-geparsten-beitr-gen-t2822.html)

Gérome 13.02.2005 14:05

Konzept: Speichern von geparsten Beiträgen
 
Hallo,

ich möchte an dieser Stelle ein Konzept vorstellen, welches wir mit unserem phpBB im Rahmen unseres letzten Updates (DP 2005) realisiert haben. Es soll sich hierbei nicht um einen echte "Mod"-Anleitung handeln, sondern nur um die reine Vorstellung des Konzepts sowie der Schilderung unserer bisherigen Erfahrungen damit.

Das Parsen der Beiträge war in unserem Fall ein echter Ressourcenfresser. Das Syntax-Highlighting, die Akronyme sowie die Zeilennummern in Codeblöcken waren wesentlich an der Last beteiligt. Unsere Idee war es nun, den fertigen HTML-Code mit in der Datenbank zu sichern, um dann normale Thread-Ansichten aus diesem Cache bedienen zu können.

Beim phpBB setzen sich die Beiträge aus Informationen aus 2 Tabellen zusammen: Es gibt die _posts - Tabelle, welche die Meta-Informationen enthält sowie die _posts_text - Tabelle, welche den tatsächlichen Beitrag enthält.
Wir haben nun eine zusätzliche Tabelle _post_cache eingefügt, welche den Cache beinhaltet. Diese Tabelle besteht aus drei Spalten: "post_id", "cache_time" und "cache_data". Die _posts - Tabelle haben wir um eine Spalte "has_valid_cache" erweitert, welche als einfaches Flag dient, ob der Cache vorliegt.

In der Anzeige der Threads fragen wir nun ab, ob ein Cache vorliegt und liefern diesen ggf aus, wenn nicht, dann wird der Beitrag herkömmlich geparst und danach automatisch in den Cache eingefügt. Dieses Vorgehen hat den Vorteil, dass sich der Cache selbstständig neu aufbaut, wenn wir ihn löschen, weil etwa neue BBCodes oder Smilies hinzugekommen sind.

Um die Datenbank nicht mehr als nötig zu belasten, wird der HTML-Code, der in den Cache geschrieben werden soll, mittels gzipdeflate() komprimiert. Das für die Anzeige nötige Dekomprimieren benötigt lediglich eine verschwindend geringe Zeit, welche bei der Auslieferung nicht ins Gewicht fällt.

Derzeit enthält unser Cache 117.760 Beiträge und die Tabelle ist 60,9 MB groß. Die Serverlast ist nach unseren letzten Modifikationen am Forum deutlich gesunken, dieser Cache hat wesentlich dazu beigetragen. Im Moment schnurrt der Server geradezu vor sich hin. *auf Holz klopf*

Was jetzt noch fehlt, sind Pflegefunktionen wie ein geeigneter Algorithmus, um alte, nur selten aufgerufene Beiträge wieder aus dem Cache zu entfernen oder aber eine Funktion, die Beiträge, die gar keinen BBCode enthalten oder sehr kurz sind, erst gar nicht in den Cache eintragen.

Insgesamt hat sich diese Angelegenheit für uns gelohnt und darum stelle ich sie hier vor. Für eine komplette MOD-Anleitung fehlt mir leider die Zeit, insbesondere für den damit verbundenen Support.


Grüße,
Gérome

MaMo 13.02.2005 14:23

Erst am Schluss kam für mich das wichtige bzw. der gute Gedanke. Bis dato dachte ich, es wäre zu speicherintensiv und teilweise sinnlos das ganze zu realisieren, aber wenn man das nur mit langen Beiträgen, die zu parsenden Code enthalten macht, wird das ganze schon um einiges sinnvoller. Ich werde mir das ganze mal für das Viscacha überlegen und dann nochmal später darauf zurückkommen.

Mfg MaMo

MrNase 13.02.2005 16:36

Das vB scheint auch sowas zu besitzen.. Ich sehe da die Tabelle 'post_parsed' die bei mir aber leer ist *g*

Es ist sicherlich eine Interessante Überlegung. :)
Wird der Cache des neuen Beitrags dann aber neu erstellt wenn jemand etwas ändert?!

Fabchan 13.02.2005 17:01

Eine weitere Möglichkeit, die Datenbank zu entlasten wäre es, die geparsten Beiträge in Dateien zu speichern. Dann werden diese auch bei einem Datenbankbackup nie mitgesichert, was ebenfall ein Vorteil ist, weil man sie in einem Backup nicht unbedingt benötigt. Ob ein Beitrag BB-Codes, Badwords und/oder Smilies enthält, lässt sich ganz ein fach mit $beitragvorher == $beitragnachher herausfinden, sollte also auch kein Problem sein.

Ansonsten: Interessante Idee, werde ich vielleicht irgendwann auch einmal brauchen können.

Luki 13.02.2005 17:18

interessante Sache und auch eine gute Idee bei den "langsamen" Codeparsern vom phpbb / vb :) *läster*

das vB ist rasend schnell, da es komplette Beiträge cachen kann (anzahl kann man im Admin Panel einstellen)

printf 13.02.2005 18:15

das neue Woltlab und das phpBB3 unterstützt soweit ich weiss auch diese Funktion...

also neu ist die Idee nicht

Gérome 13.02.2005 21:34

@MrNase: Wenn ein Beitrag editiert wird, so wird er aus dem Cache entfernt und bei der nächsten Anzeige neu eingefügt.

@Karl: Nein, neu ist diese Idee keinesfalls - diesen Eindruck wollte ich auch nicht erwecken. Dass es möglich ist, einen Cache zu implementieren, wird keinen hier vom Hocker hauen. Mir ging es ja darum, unsere Erfahrungen mit diesem System mitzuteilen. ;-)

Gérome

LonelyPixel 13.02.2005 22:31

Hm, ich hatte sowas eh schon vor zu implementieren, sobald ich endlich mal wieder Zeit dafür hab. Aber die Idee, den Cache gzip zu komprimieren, fand ich interessant! :)

Luki 10.08.2005 22:07

ich überlege gerade ebenfalls eine solche Funktion zu impletieren... - suche nur noch nach der genialsten Methode.

filecaching oder caching in der Datenbank??
Wie macht das vB das? - wird der komplette Thread als HTML Code gecacht? in welchen Tabellen?

freue mich falls jemand Details hat und dem ganzen mal unter die Haube geguckt hat oder geniale Theorien hat!

itst 10.08.2005 22:56

@Gérome: Ihr habt das ja jetzt schon eine Zeit lang am laufen. Wie sind die Erfahrungen?

Gérome 11.08.2005 07:21

Durchweg positiv. Gerade bei unseren 'rechenintensiven' BBCodes wie den Syntax-Highlightern ist die Performance beeindruckend.

Aktuell ist das System so eingetellt, dass grundsätzlich alle Beiträge gecacht werden - und das ohne Verfallsdatum. Die Serverlast ging durch diese Maßnahme drastisch zurück, auch 100 gleichzeitige User verkraftet der Server ohne spürbare Wartezeiten.

Man darf nur nicht übersehen, dass sich die Größe der Datenbank schlapp verdoppelt. Wenn dieser Umstand allerdings kein Problem darstellt, so kann ich jedem nur zu dieser Vorgehensweise raten.

eBoy 11.08.2005 07:36

Ich würde sowieso hingehen und den ganze bbCode parsen und als html in der DB ablegen. Der bbCode in dem Beitrag wird ja nur beim editieren gebraucht und für diesen Fall könnte man das ganze ja wieder von html zu bbCode zurückwandeln, den dann betrifft es ja nur einen Beitrag und nicht alle in einem Thema.
Beim cachen solcher Datenmengen würde ich mir erst noch überlegen, ob ich diese nicht als Dateien ablegen würde (z.B. eine Datei pro Thread) und diese dann einfach includen. In Dateien brauchts mehr Webspace und in der DB wird diese größer und mehr belastet...
Das bringt zwar scheinbar Performace-Vorteile, sollte aber wohlüberlegt sein...
Am besten wäre diese Funktion administrierbar zu machen (nicht cachen, in Datei oder in DB), so das dies auch von "Anfängern", die diese Forensoftware nutzen, sinnvoll und mit dem größten Nutzen eingesetzt werden kann

Gérome 11.08.2005 07:52

Das Zurückwandeln von HTML zu BBCode wird spätestens dann eine aufwändige Angelegenheit, wenn Du Syntax-Highlighting betreibst. Da ist es tatsächlich einfacher, die Beiträge doppelt vorzuhalten.

Über die Verwendung von Dateien würde ich nochmal nachdenken. So gut wie keine aktuelle Foren-Software nutzt diese Methode zum Speichern von Beiträgen - und das aus guten Grund: Viele der Implementierungen, die wir in dieser Hinsicht gesehen haben, wurden furchtbar langsam, wenn die User-Zahlen stiegen. Die Serverbelastung durch eine größere Datenbank ist hier ganz eindeutig geringer - selbst bei mySQL.

eBoy 11.08.2005 08:08

Dann ist die Frage bis zu welcher Userzahl Dateien sinnvoller als der Einsatz der DB wäre...
In den Foren, in denen ich Unterwegs bin, sind vielleicht mal 20-30 User online.
Andererseits sollte man z.B. Forensoftware nie auf eine Useranzahl begrenzen...

TRS 11.08.2005 09:49

Zitat:

Zitat von Gérome
Das Zurückwandeln von HTML zu BBCode wird spätestens dann eine aufwändige Angelegenheit, wenn Du Syntax-Highlighting betreibst. Da ist es tatsächlich einfacher, die Beiträge doppelt vorzuhalten.

Wie wäre es denn, wenn du einmal den Beitrag in Rohform mit BBCOdes und einmal in HTML Form speicherst? So wäre der BBCode Parser ausschließlich beim Schreiben, Antworten und Bearbeitungen von Beiträgen nötig.

Gérome 11.08.2005 09:54

Aber genau das mache ich doch. ;-) Ist doch die doppelte Datenhaltung, von der ich sprach.

Luki 11.08.2005 12:55

Hi Gérome,

hört sich stark an! - könntest Du Deine Vorgehensweise noch etwas genauer erläutern oder Deine Files veröffentlichen? z.B. bei Aufruf Thread -> Cache erstellen bei editieren löschen...

Ist es sinnvoll vieleicht den ganzen Thread zu speichern oder sinnvoll nur die einzelnen Beiträge?

Wie macht das vB das genau?

Gérome 11.08.2005 13:55

Das kann ich gerne tun - ist allerdings etwas phpBB-lastig. Ich würde immer dafür plädieren, dies auf Beitrags-Ebene zu machen, da sich der Cache so leichter integrieren lässt. Die nötigen Änderungen am Code sind minimal.

Wie das vB dies macht, das weiß ich noch nicht.

Das Script "viewopic.php" ist für die Anzegie der Threads zuständig. Hier wird die Entscheidung getroffen, ob (a) ein gültiger Cache-Eintrag vorliegt und (b) der Cache überhaupt genutzt werden soll.

PHP-Code:

if ($board_config['post_cache_enabled'] && $postrow[$i]['post_valid_cache']) {
  
$message /*'&lt;Frisch aus dem Cache&gt;<br>' .*/ gzinflate$postrow[$i]['post_cache'] );
} else {
  
$message $postrow[$i]['post_text'];
  
$bbcode_uid $postrow[$i]['bbcode_uid'];
  
$remove_html = (!$board_config['allow_html'] && $postrow[$i]['enable_html']);
  
$allow_smilies = ($board_config['allow_smilies'] && $postrow[$i]['enable_smilies']);
  
do_parse_message$message$bbcode_uid$board_config['allow_bbcode'], $allow_smilies$remove_htmltrue );
 
  
//
  // ggf. Cache aktualisieren
  //
  
if ($board_config['post_cache_enabled']) {
    
cache_message$message$postrow[$i]['post_id'] );
  }


Die Methode 'cache_message()' macht dann nicht mehr als den HTML-Text zu komprimieren und in die DB zu schreiben. Dies wird dann beim Beitrag jeweils vermerkt und fertig ist der Cache-Eintrag. Das Schöne daran ist, dass sich der Cache automatisch neu aufbaut, wenn ich BBCodes ändere oder mich andere Umstände dazu zwingen, den Cache zu leeren.

Luki 11.08.2005 14:00

einfach cool!! - vielen Dank, das kann ich beinahe so übernehmen!
veröffentlichst Du noch die Funktion: cache_message() ?

wäre Dir riesig dankbar!

Gérome 11.08.2005 14:05

Klar, hier ist die Funktion:


PHP-Code:

function cache_message( &$message$post_id ) {
  global 
$db;
 
  
$result false;
 
  
//
  // Die Reihenfolge ist wichtig. Erst schreiben wir die Message, dann
  // erst setzen wir das Flag, dass die Msg im Cache ist.
  //
  
$sql 'INSERT IGNORE INTO ' .POSTS_CACHE_TABLE'
(cache_time, post_id, post_cache)
  VALUES (' 
.time(). ', '.intval($post_id).', \'' .mysql_real_escape_stringgzdeflate$message) ). '\')';
  if ( 
$cache_result $db->sql_query($sql) ) {
    
$sql 'UPDATE ' .POSTS_TABLE'
    SET post_valid_cache = 1
    WHERE (post_id = ' 
.intval($post_id). ')
    LIMIT 1'
;
    
$result = ($cache_result $db->sql_query($sql));
  }
 
  return 
$result;



MaMo 11.08.2005 23:54

Hi.

Interessante Angelegenheit, werde ich mir demnächst auch mal was zu überlegen. Was allerdings die Textdateien angeht, so ist das nicht ganz richtig was Ihr schreibt. Wenn man nur den geparsten HTML-Code in einzelne Dateien schreibt und direkt auf die Dateien zugreifen kann (ID als Name für die Datei o.ä.), sollte es nicht langsamer sein als die DB, wenn nicht sogar schneller. Datenverlust ist in dem Falle auch nicht tragisch, da ja einfach neu genertiert werden kann.
Das was Ihr meintet sind BB-Systeme die komplett auf Textdateien basieren und somit auch vielmehr darauf zugreifen, Sachen modifizieren, die Dateien parsen etc. In dem Zusammenhang spielt auch das gleichzeitige Schreiben mehrerer Nutzer auf eine Datei eine große Rolle.

MfG MaMo

TRS 12.08.2005 08:27

Wenn aber eine Datenbankverbindung besteht, so ist der Zugriff auf die Datenbank schneller als der Zugriff auf die Textdateien. MySQL arbeitet aus dem Arbeitsspeicher heraus und das ist wesentlich schneller als der Zugriff auf die Festplatte.

LonelyPixel 12.08.2005 16:10

Auch Dateisystemzugriffe werden im RAM gecacht, so ist das nicht. In diesem Fall würd ich sagen, macht nen Benchmark mit euren production level optimierten Implementierungen und schaut, was nun letztendlich schneller ist, und zwar unter realer Last...

Andavos 17.08.2005 18:39

Hallo,
was mich noch intressieren würde, wäre wie ihr es gelöst habt, wenn der Server _keine_ Zlib-Erweiterung besitzt.
Dies in PHP zu implementieren wäre ja deutlich zu langsam.
Wir dann der Cache komplett abgestellt, oder dann ungezipt gespeichert?

Sonst ist die Idee gar nicht so schlecht.

itst 17.08.2005 20:47

Wozu sollte man den Cache zippen, wenn man ihn in der DB speichert? Damit verliert man nur wieder Ausführungszeit beim Anzeigen, die man durch den Cache gewonnen hat.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:55 Uhr.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25