• Jeder User im Forum verpflichtet sich zur Akzeptanz und zur Einhaltung dieser Regeln:
    1. Umgangston
      Ein angemessener höflicher Umgangston, ohne Beleidigungen, Beschimpfungen und aggressive Postings ist für jedes Mitglied Pflicht.
    2. Beiträge
      Jedes Mitglied sollte sich bemühen nur sinnvolle Beiträge zum Thema zu posten. Dabei ist unbedingt vorher zu prüfen, ob das Thema vorher schon einmal diskutiert wurde und daher fortgesetzt werden kann
      • Suchfunktion benutzen!
      • offizielle Doku lesen!
    3. Haftung
      Jeder Beitragsersteller übernimmt die alleinige Verantwortung seiner Inhalte.
    4. Werbung
      Wir erlauben keine Beiträge, Signaturen, Private Nachrichten oder eMails an Benutzer, die Werbung enthalten. Ausgenommen
      sind Stellengesuche /-angebote, welche ausschließlich im Forum "Stellengesuche" veröffentlicht werden dürfen.
    5. Verstöße
      Regelwidrige Beiträge sollten dem Team gemeldet werden. Nach deren Überprüfung werden wir schnellstmöglich
      entsprechend handeln.
    6. Authorität
      Den Anweisungen der Team-Mitglieder (Administratoren und Moderatoren) sind in diesem Forum Folge zu leisten.
      Bei Fragen oder Beschwerden bitte an diese wenden.
    Wir möchten Euch darauf aufmerksam machen, dass es bei Verstößen gegen einen oder mehreren der oben genannten
    Punkte dem Team frei steht entsprechend zu handeln. Dies kann z.B. das Löschen eines Beitrags, das Ausschliessen bzw.
    Sperren von Mitgliedern oder aber lediglich eine Verwarnung sein.

    In diesem Zusammenhang sollte erwähnt werden, dass das Forum automatisch die IP-Adresse jedes Beitrag-Erstellers
    speichert. Bei schweren Vergehen, behalten wir es uns vor, die IP-Adresse zur Strafverfolgung weiterzugeben.
  • Willkommen im Zend Framework Forum

    ZF1 Zend Framework 1 + ZF2 Zend Framework 2

    Das Zend Framework Forum ist seit 2006 die erste Anlaufstelle für Zend Framework Entwickler in Deutschland. Mit über 70.000 Beiträgen und einer steigenden Nutzerzahl bietet das Forum hilfreiche Themen und ZF-Tutorials für professionelle Entwickler, fortgeschrittene Programmierer sowie Zend Framework Einsteiger.
    Wenn dies Dein erster Besuch in der Zend Framework Community ist, lies bitte zuerst die Hilfe - FAQ durch. Du musst Dich registrieren, bevor Du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um die Registrierung zu starten. Du kannst auch jetzt schon Beiträge lesen. Hier im Forum findest Du die Zend Framework Hilfe, die Du suchst!

    Grüße an alle Zend Framework Entwickler. Das Team vom Zend Framework Forum!

    Drupal Agentur

Zend_Cache Refactoring

mabe

New member
Hi,

ich habe eine komplett überarbeitete Zend_Cache Komponente in Ready for Review eingestellt. Das Ziel soll sein fehlende Funktionen in Zend_Cache zu integrieren (z.B. tagging für alle), bessere Performance zu erreichen (z.B: das file backend ist nach dem umschreiben bis zu 40% schneller - benchmaks kommen noch), und außerdem soll die Komponente einfacher benutzt werden können.

Guckts euch einfach mal an, Rückmeldung auf Zend wäre echt nett ;)
http://framework.zend.com/wiki/display/ZFPROP/Zend_Cache+refactoring+-+Marc+Bennewitz

Greets
 

KingCrunch

New member
Ein weiter Zend-Contributor im Forum, herzlich Willkommen :)
das file backend ist nach dem umschreiben bis zu 40% schneller
Wie das? Oo

Guckts euch einfach mal an, Rückmeldung auf Zend wäre echt nett
Is bookmarked ^^

ich habe eine komplett überarbeitete Zend_Cache Komponente in Ready for Review eingestellt.
Machste dann gleich mit Zend_Log weiter? Bootstrapping mit grundsätzlich verschiedenen Konstruktor-Formaten macht kein Spass :D
 

mabe

New member
@KingCrunch

Das Hauptproblem des alten File Backends ist, dass die expire time in die cache dateien geschrieben wird und dadurch beim durchsuchen bzw. lesen/testen diese erst einmal ausgelesen werden muss.
-> die neue Variante erstellt lediglich die cache datei mit dem aktuellen Zeitstempel. Beim Überprüfen kann die expire time dann berechnet werden, ohne die Datei öffnen zu müssen.

Zudem wird beim schreben der Datien mit fopen & Co. gearbeitet, aber die neue Variante kommt mit file_put_contents aus.


@Kaiuwe
Deprecatet Warnungen und Rückwärtskompatiblität könnte denke ich implementiert werden, macht aber nur sinn, wenn das noch vor 2.0 in den Code soll. Wenn erst mit den Startschuss zu 2.0, dann müssen trotzdem noch en Paar kleinigkeiten angepasst werden (z.B: Zend_Cache_Backend_Interface umbenennen zu Zend_Cache_Backend_BackendInterface)
 

robo47

New member
Wenn man sich nur auf die Zeitstempel des Dateisystems verlässt, kann es dann nicht zu Problemen kommen wenn das Dateisystem z.b. so gemountet ist dass beim lesen/ändern keine anpassungen stattfinden (hab irgendwie sowas noch im kopf wo es um APC ging und warum der unter umständen geänderte Dateien nicht erkennen kann wenn das dateisystem unter linux mit speziellen parametern gemountet ist um unnötige schreibzugriffe zu sparen)

Bin mir da gerade nicht ganz sicher wie genau das war.
 

mabe

New member
Eigentlich mountet man das Dateisystem mit "noatime" um unnötige Schreibzugriffe zu vermeiden, dass hat aber nur Auswirkungen auf die "last access time".

Ich bin der Meinung, dass wenn man einen File-Cache nutzt, das Fs auch die "last modification time" aktualisieren sollte / muss. Im übrigen fällt mir auch kein Fs ein, welches dieses Feature nicht standardmäßig nutzt.

Wenn es umbedingt ohne funktionieren muss sollte die zu nutzende Variante über eine zusätzliche Funktion ausgewählt werden können.
 

Bleistift

Moderator
Man könnte ja nach dem Schreiben des Cache-Files prüfen, ob die "last modification time" korrekt gesetzt wurde und gegebenenfalls reagieren.
 

ice-breaker

New member
Das Ziel soll sein fehlende Funktionen in Zend_Cache zu integrieren (z.B. tagging für alle)
mich würde interessieren wie du Tagging in Engines wie APC oder Memcached implementieren willst, die keine atomaren Operationen unterstützen?
Nen, Eintrag anzulegen, dass man gerade die Tags modifiziert und deswegen niemand anders den Eintrag bearbeiten darf, kostet wieder mehr Zugriffe und erhöht wiederum das Locking-Verhalten, welches in Memcached dank Mutexen ja komplett eliminiert wurde.

Ich hätte aber noch 1 Wunsch:
  1. eine loadMultiple()-Methode mit der ich aus einem Cache in einer Operation mehrere Ids holen kann (memcached kann das, spart IO-Operationen) und Backends die es nicht unterstützen simulieren es einfach durch mehrere load-Zugriffe.
Das du die Memcached-Benennung an die PHP-Extension-Benennung angepasst hast, gefällt mir sehr gut.
 

mabe

New member
@Bleistift
Das wäre eine Möglichkeit, aber diese würden auch wieder zusätzliche Fs-Operationen mit sich bringen, zudem man extra ein touch aufrufen muss, da man nicht 100%ig die genau zeit beim schreiben weiß.

@ice-breaker
Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
-> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
-> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.

-> Ein Blick in mein svn (siehe proposal) in die Klasse Zend_Cache_Frontent_Core hilft dir sicher weiter.


Was genau soll die Methode loadMultiple genau zurück geben?
-> eine Liste von Ids -> siehe getIds
-> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel
 

Bleistift

Moderator
@Bleistift
Das wäre eine Möglichkeit, aber diese würden auch wieder zusätzliche Fs-Operationen mit sich bringen, zudem man extra ein touch aufrufen muss, da man nicht 100%ig die genau zeit beim schreiben weiß.
Cache-Schreiben ist ja sowieso langsam und wird darum auch selten gemacht:
Das Schreiben auf die Platte selber ist schon langsam und ausserdem müssen die Daten, die gecacht werden sollen, dann ja auch geladen werden (DB o.Ä.)

Ich glaube viel Zeit ginge da nicht verloren. Müsste man halt testen.
 

mabe

New member
Ich glaube es wäre das beste die mtime-Funktionalität im Fs beim Konstruktor bzw. beim setzen von cache_dir zu überprüfen und trotzdem eine Option dafür bereit zu stellen.

-> Wenn Funktionalität nicht verfühgbar ist, aber die Option aktiviert ist müsste natürlich eine Exception geworfen werden.
 

robo47

New member
@ice-breaker
Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
-> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
-> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.
Im Falle von limitierten Caches wie APC die irgendwann voll sind bedeutet das dann aber wenn der Cache voll ist und anfängt Elemente zu löschen, fliegen unter umständen die einträge raus die für die Verknüpfungen zuständig sind oder ? Jenachdem wie ich auf die Einträge zugreife hab ich so unter umständen dann Leichen die noch genutzt werden die ich aber nicht mehr finden kann.

Ich würde mir da eher wünschen dass man bei Systemen die keine Tags unterstützen eine Art Adapter hat der diese Assoziation herstellt und man sich hier dann selbst entscheiden kann was man will, sei es dass man bereit ist das Risiko einzugehen und einen APC-Adapter nutzt, oder dass man die tags in einem anderen Medium speichert (dateisystem, sqlite/dbms, ... )

Ich denke da an etwas in der Richtung: http://pollinimini.net/blog/tags-emulation-zendcache
 

Bleistift

Moderator
Ich würde mir da eher wünschen dass man bei Systemen die keine Tags unterstützen eine Art Adapter hat der diese Assoziation herstellt und man sich hier dann selbst entscheiden kann was man will, sei es dass man bereit ist das Risiko einzugehen und einen APC-Adapter nutzt, oder dass man die tags in einem anderen Medium speichert (dateisystem, sqlite/dbms, ... )
Man könnte ja dafür eine Option bieten... Standard ist der eigene Adapter. Man kann allerdings auch einen eigenen Adapter definieren.
Also:
PHP:
$backendOptions = array(
    'tag_handler' => Zend_Cache::factory('Core',
                                         'File',
                                         array('lifetime' => 7200),
                                         array('cache_dir' => './tmp/'))
);
$cache = Zend_Cache::factory('Core',
                             'APC',
                             $frontendOptions,
                             $backendOptions);
 

KingCrunch

New member
Also bei sowas tendiere ich lieber zu eigenen Klassen, was die Wartung vereinfacht und den Konfigurationswahn etwas eindämmt :)
 

mabe

New member
Im Falle von limitierten Caches wie APC die irgendwann voll sind bedeutet das dann aber wenn der Cache voll ist und anfängt Elemente zu löschen, fliegen unter umständen die einträge raus die für die Verknüpfungen zuständig sind oder ? Jenachdem wie ich auf die Einträge zugreife hab ich so unter umständen dann Leichen die noch genutzt werden die ich aber nicht mehr finden kann.
Ja Richtig das ist ein Problem, wobei die evtl. entstehenden Leichen aber durch clean all bzw. durch erreichen der Laufzeit automatisch gelöscht werden.

Dafür einen Handler als Option anzubieten ist eine gute Idee. Ich würde sagen, dass ein definierter Tag-Handler das Zend_Cache_Backend_Interface implementieren muss (also ohne frontend arbeitet) und als Default-Wert das aktuelle Backend genutzt wird. Damit ist die zusätzliche Option optional und man kann die Tag-Implementierung auch auf einen eigenen Handler lenken, wenn das Backend tagging implementiert hat.
 

Bleistift

Moderator
Ich würde sagen, dass ein definierter Tag-Handler das Zend_Cache_Backend_Interface implementieren muss (also ohne frontend arbeitet) und als Default-Wert das aktuelle Backend genutzt wird. Damit ist die zusätzliche Option optional und man kann die Tag-Implementierung auch auf einen eigenen Handler lenken, wenn das Backend tagging implementiert hat.
Ja, das finde ich eine gute Idee. :)
 

ice-breaker

New member
Wenn Tagging im Backend nicht implementiert ist, dann schreibe ich die eingehenden tags als Referenz ein eine extra cache id und ein zusätzliche Info in den cache selbst (Nur wenn beim Speichern Tags angegeben wurden)
-> Beim clean/getIds kann man dann die Referenz der zu suchenden Tags durchlaufen
-> Beim löschen werden die zu dem Cache gehörenden Referenzen auch mit entfernt

Das ist natürlich lange nicht so performant und sicher, als wenn es direkt im Backend implementiert ist, aber soll ja hautsächlich die Funktionalität des Backends nacharmen.

-> Ein Blick in mein svn (siehe proposal) in die Klasse Zend_Cache_Frontent_Core hilft dir sicher weiter.
hmm, ich persönlich finde es eben nicht besonders sinnvoll dem Entwickler Tags zu versprechen, wenn es im Prinzip nur ne "halbherzige" Implementierung ist, der Cache kann sie wegwerfen oder bei parallen Schreibzugriffen ist nicht garantiert was passiert (fehlendes Locking-> Race conditions).
Also ich würde den Vorschlag, dass wenn ein Backend keine Tags unterstützt, es als extra Adapter zu implementieren deutlich besser finden.
Sonst muss ich mich bei jedem Cache informieren gehen welche Sicherheit ich bekomme (leider werden das einige nicht machen).
Mit extra Adaptern könnte man gleich angeben, welchen "Sicherheitsstandard" (Persistenz, Atomarität) dieser unterstützt, und diesen auch konfigurieren (Atomarität (de)aktivieren für Performance/Sicherheit)

Was genau soll die Methode loadMultiple genau zurück geben?
-> eine Liste von Ids -> siehe getIds
-> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel
genau das !
Und es ist sehr praktikabel ich beschreibe gerade mal eine Anwendung:
Eine Anwendung ist so groß gewachsen, das einige DB-Server schon nicht mehr reichen, die Daten müssen geshardet werden. Nun möchte das Model (Beispiel nimmt dieses Forum) welches gerade für den View die darzustellenden Informationen zusammensammelt, zu jedem Post (der eine User-Id hat) die Kurzinfo des Bernutzers laden (rechte Seite ;)).
Nach deinem Verfahren sind es hier aktuell ca. 6 Zugriffe (also 6 mal einen anderen Server kontaktieren) auf den Cache (alle Benutzer, die etwas gepostet haben), hätten wir aber eine dicke Memcached-Maschine mit viel Ram, würde ein einzelner Aufruf reichen, wir hätten uns als 10 IO-Zugriffe (versimpelt ;) 5 Senden, 5 Empfangen) gespart und zudem ordentlich Load von dem Cache genommen.
Also so unsinnig ist das nicht, es wurde nicht ohne Grund in Memcached implementiert
 
Zuletzt bearbeitet:

mabe

New member
hmm, ich persönlich finde es eben nicht besonders sinnvoll dem Entwickler Tags zu versprechen, wenn es im Prinzip nur ne "halbherzige" Implementierung ist, der Cache kann sie wegwerfen oder bei parallen Schreibzugriffen ist nicht garantiert was passiert (fehlendes Locking-> Race conditions).
Also ich würde den Vorschlag, dass wenn ein Backend keine Tags unterstützt, es als extra Adapter zu implementieren deutlich besser finden.
Sonst muss ich mich bei jedem Cache informieren gehen welche Sicherheit ich bekomme (leider werden das einige nicht machen).
Mit extra Adaptern könnte man gleich angeben, welchen "Sicherheitsstandard" (Persistenz, Atomarität) dieser unterstützt, und diesen auch konfigurieren (Atomarität (de)aktivieren für Performance/Sicherheit)
Ich hoffe, dass ist mit einer Instanz von Zend_Cache_Backend_Interface als Tag Handler (siehe oben) ok.

Zitat:
Zitat von mabe
Was genau soll die Methode loadMultiple genau zurück geben?
-> eine Liste von Ids -> siehe getIds
-> eine Liste mit allen Ids und dessen Cache-Inhalt halte ich für nicht praktikabel


genau das !
Und es ist sehr praktikabel ich beschreibe gerade mal eine Anwendung:
Eine Anwendung ist so groß gewachsen, das einige DB-Server schon nicht mehr reichen, die Daten müssen geshardet werden. Nun möchte das Model (Beispiel nimmt dieses Forum) welches gerade für den View die darzustellenden Informationen zusammensammelt, zu jedem Post (der eine User-Id hat) die Kurzinfo des Bernutzers laden (rechte Seite ;)).
Nach deinem Verfahren sind es hier aktuell ca. 6 Zugriffe (also 6 mal einen anderen Server kontaktieren) auf den Cache (alle Benutzer, die etwas gepostet haben), hätten wir aber eine dicke Memcached-Maschine mit viel Ram, würde ein einzelner Aufruf reichen, wir hätten uns als 10 IO-Zugriffe (versimpelt ;) 5 Senden, 5 Empfangen) gespart und zudem ordentlich Load von dem Cache genommen.
Also so unsinnig ist das nicht, es wurde nicht ohne Grund in Memcached implementiert
Was du meinst ist eine feste Liste (also keine Suche mittels MATCH_*), sondern etwas in der Art:
lade den Inhalt folgender Cache-Ids id1, id2 ...

-> Die Idee klingt ganz gut, finde ich aber besser, wenn man das direkt mit der load/test methode verknüpft:

Ich würde allerdings sagen, dass bei load nur valide Inhalte zurückgegeben werden, wobei mittels test alle angefragten cache-ids zurück geliefert werden.

{code}
$cache->test(array('id1', 'id2', 'id3')); // return array('id1' => [mtime], 'id2' => false, 'id3' => [mtime])
$cache->load(array('id1', 'id2', 'id3')); // return array('id1' => 'content1', 'id3' => 'content3')
{code}
 

ice-breaker

New member
Was du meinst ist eine feste Liste (also keine Suche mittels MATCH_*), sondern etwas in der Art:
lade den Inhalt folgender Cache-Ids id1, id2 ...
jup, und das eben, falls das Backend es unterstützt in einer Operation, wie bei Memcache::get mit einem Array als Parameter

-> Die Idee klingt ganz gut, finde ich aber besser, wenn man das direkt mit der load/test methode verknüpft:

Ich würde allerdings sagen, dass bei load nur valide Inhalte zurückgegeben werden, wobei mittels test alle angefragten cache-ids zurück geliefert werden.

{code}
$cache->test(array('id1', 'id2', 'id3')); // return array('id1' => [mtime], 'id2' => false, 'id3' => [mtime])
$cache->load(array('id1', 'id2', 'id3')); // return array('id1' => 'content1', 'id3' => 'content3')
{code}
ist auch ok, sofern es dann auch die nativen Funktionalitäten nutzt (und wenn nicht vorhanden die emulierten), sonst kann ich mir das gleich auch sparen.

Da fällt mir was ein, bei einem File-Backend könnte man das doch mit Partitionierung verknüpfen oder? :D
So dass die Ids "user_$username" caches bekommen wo mehrere Entrys in einem File liegen (und dann nur usernames und nicht noch andere), so dass man die Anzahl zu öffnender Dateien senken könnte.
Also nen Array übergeben nach dem partioniert wird, für Keys die nicht darauf zutreffen, nutzt man die alte Methode.
Könnte die Performance nochmal ordentlich steigern, wenn man viele Daten aus einem Cluster lädt statt aus jeweils einzelnen Files.
 
Oben