phpbar.de logo

Mailinglisten-Archive

[php] Caching & FileLocks

[php] Caching & FileLocks

Ulf Wendel php_(at)_phpcenter.de
Fri, 05 Oct 2001 10:38:55 +0200


Christian Thiele wrote:
> Gibt es Probleme wenn ich als Cache nicht eine Datei sondern
> den Shared-Memory des Servers nutze...? In dem Bereich hab
> ich noch nichts mit PHP gemacht, nur mit C....

Caching im SHM rentiert sich nur bei einer geringen, endlichen Zahl von
Einträgen. Der File-Container ist der schnellste Container des
PEAR-Cache. Dies liegt zum einem in der Implementierung von SHM im Unix
Kern (Files) zum anderem an der ineffizienten Verwaltung von
Cacheeinträgen. Files, die häufig benutzt werden kommen aus einem
Platten- oder Systemcache (Memory). Ihre Zugriffszeit unterscheidet sich
nur durch das Locking von SHM Zugriffen.

> Sollte aber doch wesentlich performanter sein...oder ??

Es ist langsamer bei einem generale Purpose Cache, wie dem PEAR-Cache.
Der Cache hat typischerweise n (0 < n < 10^5) Einträge zu verwalten. Die
Größenordnung von n kannst Du zur Laufzeit nicht vorhersagen, es ist für
Dich eine unbekannte Größe. n Einträge kannst Du mit zwei Strategien im
SHM verwalten:

(1) ein SHM Segment mit n enthaltenen Datensätzen
(2) 1 SHM Segment mit einer Lookup Table, n SHM Segmente für die n
Einträge (= n+1 Segmente)

Bei (1) wird das komplette Segment ausgelesen, deserializiert und der
gesuchte Eintrag aus den deserialisierten Daten extrahiert. Bei n = 10^m
wurde Arbeit für 10^m - 1 Einträge geleistet, deren Ergebnisse verworfen
werden also: n = 10, 9 verworfen; n = 100, 99 verworfen; usw. Für sehr
kleine n von 0 < n < 10^3 ist es in der Praxis - je nach Größe der
Einträge - noch vertretbar, schön ist es jedoch nicht. (1) ist im
PEAR-Cache SHM Container implementiert. 

(2) verwirft zwar weniger Ergebnisse, hat jedoch einen extrem hohen
Verwaltungsaufwand und kommt nur für sehr kleine 0 < n < 10^3 Werte in
Frage. Die Anzahl der SHM Segmente auf einem System ist endlich. Sofern
unser PHP nicht die einzige Software ist, die SHM Segmente verbraucht,
können wir nicht alle Einträge verbrauchen. ipcs -l verrät Dir auf einem
Linux wieviele Einträge zur Verfügung stehen (typisch: 4096). Ja, die
Zahl läßt sich im Kernel konfigurieren, aber solch ein Fine-Tuning kann
kein general purpose Cache, wie der PEAR-Cache von seinen Benutzern
verlangen.

Eine weitere Schwierigkeit besteht in der Zuordnung von Cache-ID auf
SHM-Segment(-Kennung). 

Die Cache-ID wird, wie einst die Session-ID in der PHPLib, mit dem MD5
Hashalgoritmus berechnet. Dieser hat einen Ergebnisraum von 32 Bit,
entsprechend ~ 4,2 Milliarden Werten. Kollisionen, Doppelbenutzungen
sind sehr unwahrscheinlich, die Sicherheit damit recht hoch. 

Bei nur 4096 verfügbaren Segment-ID's sollte man nicht Cache-ID =
Segment-ID definieren. Probleme sind damit garantiert. Die Zahl ist zu
gering, als daß ein Angreifer nicht alle ID's ausprobieren könnte.

Wenn man also nicht lebensmüde ist, mappt man die md5()-Ergebnisse auf
Segment-ID's. Diese Lookup-Table muß zur Verfügung stehen, um einen
Cache-Eintrag ausfindig zu machen. Da PHP requestbasiert arbeitet,
verschwindet die Lookup-Table, sofern man sie nicht sichert. Eine
Session kann nicht von mehreren Prozessen geteilt werden, drum legt man
die Tabelle ebenfalls in einem SHM-Segment ab. Jetzt ahnt man bereits,
welche Aufwand hinter (2) steckt. 

Eine weitere Problemstelle von (2) sind Überläufe. Was soll passieren,
wenn keine Segment-ID's mehr zur Verfügung stehen? Von Cache-Gruppen
will ich gar nicht erst sprechen.

Der File-Container kennt all diese Sorgen nicht: ein Directory pro
Gruppe, ein File pro Eintrag, Platten- und Systemcache liefern die Daten
aus dem Speicher, praktisch keine Begrenzung der maximalen Anzahl von
Cacheeinträgen.

Ulf

-- 
NetUSE AG              Dr.-Hell-Straße   Fon: +49 431 386 436 00 
http://www.netuse.de/  D-24107 Kiel      Fax: +49 431 386 435 99


php::bar PHP Wiki   -   Listenarchive