[PHP5] memcache add

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [PHP5] memcache add

    Hallo,

    gleich mal vorweg: DIE NÄCHSTEN 11 FORUM-EINTRÄGE KÖNNEN
    IGNORIERT WERDEN. Interessant wird es dann erst wieder
    ab 24-09-2007 20:03.

    Ich beschäftigte mich momentan mit memcache.

    Wenn ich das richtig verstanden habe, werden bei einem add alte Einträge
    automatisch gelöscht, sofern kein freier RAM-Speicher mehr zur Verfügung
    steht.

    Habe daraufhin folgendes Testprogrämmchen laufen lassen:
    PHP-Code:
    <?php
       define
    ('STR_CNT','6400'); // Anzahl der Einträge in das RAM.
       
    define('N_CNT'  ,(int)STR_CNT); 
       
    define('N_PAD'  ,strlen(N_CNT));
       function 
    getKey($__nI)
       {  
    /**
           * Erzeugt einen Schlüssel.
           * @param $__nI: Number
           *    Index, fortlaufende Nummer, Teil des Schlüssels.
           * @return: String
           *    Der Schlüssel besteht aus dem Präfix 'k' und dem $__nI als Suffix (4stellig)
           */
          
    return 'k'.str_pad($__nI,N_PAD,'0',STR_PAD_LEFT);
       }
       
    $oRAM=new Memcache();
       if(@
    $oRAM->connect('127.0.0.1'))
       {  
    /*
           * abzuspeichernder Value:
           */
          
    $strV='';
          for(
    $nJ=0;$nJ<1024;++$nJ// 1024 * 10 => 10kB
             
    for($nI=0;$nI<10;++$nI// 10        => 10B 
                
    $strV.=$nI;
          
    /*
           * Values in RAM speichern:
           */
          
    for($nI=0;$nI<N_CNT;++$nI// 10kB * 6400 => 64MB Value (exkl. Key)
             
    echo (  $oRAM->add(getKey($nI),$strV,false,60// 1 Minute
                     
    ?  'o'
                     
    :  'n'
                  
    ).
                  
    ' '.$nI.'<br />';
          
    /*
           * Values aus RAM auslesen:
           */
          
    for($nI=0;$nI<N_CNT;++$nI
          {  
    $strKey=getKey($nI);
             echo 
    $strKey.': ';
             
    var_dump($oRAM->get($strKey));
             echo 
    '<br />';
          }
          
    /*
           * memcache-Stati auslesen:
           */
          
    $oDump=$oRAM->getStats();
          if(
    is_array($oDump))
             
    var_dump($oDump);
       }
    ?>
    add liefert leider keine Rückmeldung, falls memcache gezwungen wäre,
    Daten aus dem RAM zu löschen, um einen neuen Eintrag im RAM
    abspeichern zu können, wenn der RAM schon voll ist.

    getStats scheint auch keine Informationen zu liefern, anhand dessen man
    schon VOR einem add kontrollieren könnte, ob die Daten gepeichert
    werden können, ohne dass andere Daten aus dem RAM gelöscht werde
    müssen.

    Wie kann ich verhindern, dass Daten automatisch und ohne Meldung aus
    dem RAM gelöscht werden, wenn ich mittels add etwas ins RAM eintragen
    möchte, das RAM jedoch schon voll ist? Gibt es eine Möglichkeit, auf einen
    möglichen Datenverlust reagieren zu können?

    Hier noch Ausschnitte aus der Ausgabe des Scripts:
    Code:
    o 0
    …
    o 6399
    k0000: bool(false)
    …
    k4191: bool(false) 
    k4192: string(10240) "0123…"
    …
    k6399: string(10240) "0123…"
    array(18)
    { …
      ["curr_items"]    =>string(4) "2208"     Akt. Anz. im RAM befindlicher Einträge. Sollten 6400 sein.
      ["total_items"]   =>string(4) "6400"
      ["bytes"]         =>string(8) "22720320"
      ["cmd_get"]       =>string(4) "6400"     Hier sieht man, dass die Anzahl der Speicher- und
      ["cmd_set"]       =>string(4) "6400"     Lese-Vorgänge gleich ist.
      ["get_hits"]      =>string(4) "2208"     Anz. erfolgreicher Versuche, Daten auszulesen. Sollte 6400 sein.
      ["get_misses"]    =>string(4) "4192"     Anz. fehlgeschlagener Versuche, Daten auszulesen. Sollte 0 sein.
      ["bytes_read"]    =>string(8) "65760007"
      ["bytes_written"] =>string(8) "22743904"
      ["limit_maxbytes"]=>string(8) "67108864" Zur Verfügung stehender RAM-Speicher (64MB).
    }
    Wie man sieht, befinden sich nur 2208 statt der 6400 Daten tatsächlich im RAM.

    Mit bytes_written ist VOR einem add wohl keine Kontrolle möglich, da es
    nicht die Bytes jener Daten wiedergibt, die man abspeichern möchte
    (siehe Vergleich zu bytes).

    Auf bytes kann man sich auch nicht verlassen, da es schon bei wesentlich
    weniger als den 64MB zu Datenverlusten gekommen ist.

    cmd_set gibt leider nur an, wie oft ein add ausgeführt wurde.

    cur_items kann auch nicht für die Kontrolle herangezogen werden, da
    Daten ja auch kontrolliert (nach Ablauf einer gewissen Dauer - im meinem
    Beispiel 1 Minute) automatisch aus dem RAM gelöscht werden könnten.

    Hintergrundinfo: Ich möchte ein RAM-Caching für den laufenden Text eines
    Chats verwenden. Diese Texte sollen ausschließlich nur im RAM
    zwischengespeichert werden. Alle anderen Sachen, wie z. B.
    Authentifizierung oder Profile läufen dann über MySQL oder LDAP(BDB).

    Würde mich freuen, von Leuten Hilfe zu bekommen, die schon mal mit
    memcache oder RAM-Caching zu tun hatten.
    Zuletzt geändert von sch-forum; 24.09.2007, 21:05.

  • #2
    http://www.danga.com/memcached/
    http://de2.php.net/memcache



    manchmal frage ich mich warum sich die Entwickler hinsetzen und Manuals schreiben/schreiben lassen
    "Nicht jeder Mensch kann und soll Programmieren[...]".

    Kommentar


    • #3
      Das war leider absolut gar keine Hilfe.

      Kommentar


      • #4
        Vielleicht verwendest du mal ein paar Tags, um den Code und die Ausgabe zu markieren...
        Durch dein Eröffnungspost in der aktuellen Struktur (gar keine) will ich mich nicht wühlen, erkennt man nämlich spontan gar nix.

        Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

        bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
        Wie man Fragen richtig stellt

        Kommentar


        • #5
          Sorry, ich bin so selten in Foren. Habe das jetzt geändert.

          Kommentar


          • #6
            hm... gut dokumentiert ist das irgendwie nicht...

            Womit ich anfangen würde ist, expires weg zu lassen (die 60 Sekunden).
            Danach bei jedem Schleifendurchgang abfragen, wann curr_items != total_items ist und dann mal gucken, eventuell geht einem da schon ein Licht auf...
            Problem halt in Teilprobleme zerlegen, bei 4 verschachtelten Schleifen kann man jetzt spontan nicht von einer Eingrenzung des Problems sprechen.

            Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

            bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
            Wie man Fragen richtig stellt

            Kommentar


            • #7
              hm? Vielleicht hatte ich meine Frage falsch formuliert. Mich hätte interessiert, ob es im memcache eine Möglichkeit gibt, zu erfahren, wann ein Datenverlust droht.

              (Dass in meinem Beispiel die Daten nach 60 Sekunden gelöscht werden, ist ja auch so gewollt. Das ist ja ein bewusstes Löschen der Daten aus dem RAM. Das Problem besteht ja schon vor diesen 60 Sekunden. Ich hätte auch den Wert weglassen können. Dann hätte ich rein theoretisch eine permanente Speicherung im RAM. Aber das ist für mein Problem ohne Belangen.)

              Angenommen der reservierte RAM-Bereich ist bereits voll belegt und man möchte nun mittels add weitere Daten im RAM ablegen. add löscht zuerst brutal und ohne Rückmeldung oder Hinweis die älteste Information und fügt erst danach den neuen Eintrag im RAM ein. D. h. es sind Daten verloren gegangen, ohne dass man in irgeneiner Form dies hätte verhindern können oder man hierzu eine Information bekommen hätte.

              Und ich versuche eine Möglichkeit zu finden, unkontrollierten Datenverlust zu verhindern.

              Ich mache noch ein paar Kommentare in den Quellcode und füge noch Ausschnitte aus der Ausgabe des Scripts hinzu. Mein Script funktioniert grundsätzlich tadellos. Nur fehlt mir eine Kontrolle über memcache, um Datenverlust zu verhindern.

              cur_items kann übrigens deshalb nicht für die Kontrolle herangezogen werden, da Daten ja auch kontrolliert (nach Ablauf einer gewissen Dauer - im meinem Beispiel 1 Minute) automatisch aus dem RAM gelöscht werden könnten. cur_items bezieht sich übrigens auf den aktuellen Stand, total_items auf alle Items seit dem Start des memcache-Dämons.
              Zuletzt geändert von sch-forum; 24.09.2007, 18:11.

              Kommentar


              • #8
                Dafür ist Memcache, nach kurzem Blick in die Doku, nicht konzipiert.

                Im Endeffekt ist Memcache wirklich rein als Cache zu verstehen. Und ein Cache muss nur möglichst viele Daten fassen, einen Mechanismus zum Prioritäten setzen, welche der Daten auf jeden Fall behalten werden sollen, oder Mechanismen um einen garantierten Bestand von Daten zu sichern, stellt memcache selbst nicht bereit. Dafür gibt es Datenbanken.

                Im einfachsten Fall[list=a][*] Memcache abfragen - Daten da, ja, gut[*] nein, Datenbank abfragen, Daten in memcache speichern[/list=a]
                mehr bietet Memcache von Haus aus nicht.

                Wenn dir das nicht reicht, solltest du dich entweder mit den Interna von Memcache selbst beschäftigen, oder dich mal an die dortige Mailingliste wenden, bzw. erstmal das Archiv durchsuchen.


                Wenn du natürlich die Ungereimtheiten in der Status-Ausgabe irgendwie erklären/lösen kannst, könntest du versuchen anhand dessen zumindest begrenzt Einfluss auf die Speicherung zu nehmen.

                Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                Wie man Fragen richtig stellt

                Kommentar


                • #9
                  memcache mit einer Datenbank zu kombinieren, würde memcache ad absurdum führen. Die Daten im RAM immer nach einem add wieder auszulesen, um zu kontrollieren, ob noch alle gewünschten Daten vorhanden sind, wird wohl auch nicht klappen, oder? Womit sollte ich denn vergleiche, ob noch alle Daten da sind?

                  Kommentar


                  • #10
                    Oh, ich glaube, jetzt habe ich den Eintrag mit der Datebank verstanden. Hatte in eine ganz andere Richtung gedacht. Sorry.

                    Vielleicht sollte ich erklären, wie ich auf das Thema RAM-Caching gekommen bin. Ich würde das ev. für die laufenden Texte eines Chats verwenden wollen. Da gibt es dann keinerlei Berührungspunkte zu Datenbanken.

                    Bei den Profilen würde dann natürlich eine Datenbank, für die Authentifizierung LDAP verwendet werden.

                    Also in meinen Augen ist unkontrollierbarer Datenverlust der Supergau der Programmierung. Es muss hier doch irgendeinen Trick geben. Mit den memcache-interna kann ich mich nicht beschäftigen. Hier läuft ein Dämon im Hintergrund. Dafür reichen meine Kenntnisse nicht aus, dass ich den in irgendeiner Form ummodeln könnte.
                    Zuletzt geändert von sch-forum; 24.09.2007, 18:20.

                    Kommentar


                    • #11
                      Was ist das Problem, beim Posten den Post 1. an Memcache und 2. an eine Tabelle anzuhängen und beim Auslesen zuerst zu versuchen den Text aus Memcache und wenn er dort nicht vorhanden ist, aus der Datenbank auszulesen (und in dem Fall dann auch gleich in Memcache zwischen zu speichern)?

                      Wenn du den ganzen Ballast in der Tabelle später nicht brauchst, kann man diese über einen Cronjob leeren lassen.
                      So oder so, musst du auf eine alternative Variante ausweichen, wenn du die Chat-Gespräche z.B. nach einem Serverneustart noch zur Verfügung stellen willst, weil spätestens dann ist Memcache leer - ob mit Überschreibschutz seitens PHP oder nicht.

                      Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                      bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                      Wie man Fragen richtig stellt

                      Kommentar


                      • #12
                        Eigentlich wollte ich hier nicht darauf eingehen, wie ich mir die Struktur des Chats vorstelle. Das lenkt nur vom Problem ab.

                        Zurück zum Problem: Wie kann ich verhindern, dass Daten automatisch und ohne Meldung aus dem RAM gelöscht werden, wenn ich mittels add etwas ins RAM eintragen möchte, das RAM jedoch schon voll ist?

                        Kommentar


                        • #13
                          Original geschrieben von sch-forum
                          Zurück zum Problem: Wie kann ich verhindern, dass Daten automatisch und ohne Meldung aus dem RAM gelöscht werden, wenn ich mittels add etwas ins RAM eintragen möchte, das RAM jedoch schon voll ist?
                          Gar nicht, ohne etwas am Memcache-Server zu ändern, oder vorher über die Status-Variablen raus zu finden, ob für die Daten noch Platz ist (vorausgesetzt du kriegst die Fehler aus den Statistiken).

                          Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                          bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                          Wie man Fragen richtig stellt

                          Kommentar


                          • #14
                            Den memcache-Dämon kann ich nicht ändern.

                            Und die Status-Infos helfen mir auch nicht weiter (aber vielleicht anderen).
                            Vielleicht gibts ja irgendwelche Konfigurationsmöglichkeiten oder irgeneine
                            Art von debugging, die ich nicht kenne. Vielleicht gibts ja einen Trick, wenn
                            ich irgendwie mit sockets, ev. über telnet arbeite. Oder was weiß ich, was
                            da vielleicht alles möglich wäre.

                            Wäre schön, wenn ich von jemand Feedback bekommen könnte, der
                            schon mit memcache gearbeitet hat.
                            Zuletzt geändert von sch-forum; 24.09.2007, 21:09.

                            Kommentar


                            • #15
                              Vielleicht gibts ja einen Trick, wenn
                              ich irgendwie mit sockets, ev. über telnet arbeite. Oder was weiß ich, was
                              da vielleicht alles möglich wäre.
                              Du ließt die Antworten? Du weißt was Memcache macht?
                              Die Regeln | rtfm | register_globals | strings | SQL-Injections | [COLOR=silver][[/COLOR][COLOR=royalblue]–[/COLOR][COLOR=silver]][/COLOR]

                              Kommentar

                              Lädt...
                              X