MB: permanenter Zugriff auf Daten aus Datenbank?

moin,

ich möchte einen permantenten Zugriff auf die Daten die aus der Datenbank Tabellen kommen (z.B. Artikel, Benutzer (und plural) etc.) haben, sodass ich nicht jedesmal eine Verbindung zur Datenbank für nur einen HTTP-Aufruf auf und abbauen muss. Ich verwende provisorisch Klassen (z.B. ArticleStore) die das zugehörige Model aus dem Repository übergeben und als Property für jeden HTTP-Aufruf abspeichern. Natürlich kann ich das auch Cashen, aber das wird dann doch zu umständlich, wenn man die Daten nur für einen HTTP-Aufruf benötigt.

lgmb

  1. Moin,

    Dann wirst du irgend eine Zwischenschicht einbauen müssen, die die Datenbankverbindung offen hält und die entsprechenden Anfragen weiterleitet und das Ergebnis an den Webserver zurückgibt.

    m.E. würde das z.B. mit node.js gehen. Da kannst du Verbindungen zur DB offen halten und nur die entsprechenden Anfragen ausführen lassen und das Ergebnis z.B. als json z.B. an PHP zurückgeben lassen, welches dann das View erzeugt und per HTTP liefert.

    Gruß Bobby

    -- -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
    1. moin,

      Dann wirst du irgend eine Zwischenschicht einbauen müssen, die die Datenbankverbindung offen hält und die entsprechenden Anfragen weiterleitet und das Ergebnis an den Webserver zurückgibt.

      Ich will eben grade vermeiden das eine geöffnete Datenbank Verbindung entsteht. Das raushohlen was von der App temporär angefordert ist, dann in Klassen - wie du sagtest: Zwischenschicht - abspeichern und wahlweise drauf zugreifen z.B. article-Inhalt und article-Titel in unterschiedlichen Views. Da muss man zwei mal den Zugriff auf die Datenbank anstellen. Mit dieser Zwischenschicht habe ich das vermieden. Ich weis nicht ob ich dieses Daten im Repository::property abspeichern sollte oder eben eine Zwischenschicht Lösung ist.

      m.E. würde das z.B. mit node.js gehen.

      Ich verwende PDO

      lgmb

      1. Moin,

        Dann hatte ich dich falsch verstanden... warum willst du denn nicht eine Verbindung offen halten? Datenbanken sind dazu da Daten vorzuhalten. Wenn du diese jetzt nochmal extra cachest, erschließt sich mir nicht ganz der Sinn dahinter. Könntest du deine Gedanken dazu noch etwas weiter ausführen, sodass man evtl. deine Intension dahinter erkennen kann?

        Gruß Bobby

        -- -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
        1. moin,

          Dann hatte ich dich falsch verstanden...

          Kein problem. Ich drück mich wirklich in dem Forum sehr undeutlich aus 😕.

          warum willst du denn nicht eine Verbindung offen halten?

          ich hätte gern alles drin oder draußen. Sprich: je nach URL-Route holt sich die App die angeforderten Daten aus der Datenbank raus und speichert sie dann in zur Laufzeit bereitstehenden Klassen. Da alle informationen jetzt zur Laufzeit in der App enthalten sind, können sich jetzt View-Templates mit diesen gespeicherten Daten befüllen lassen.

          Datenbanken sind dazu da Daten vorzuhalten. Wenn du diese jetzt nochmal extra cachest, erschließt sich mir nicht ganz der Sinn dahinter.

          Ich sehe Datenbank und PHP-Application als zwei Einheiten an und es ist nicht immer gegeben das Datenbank + App auf dem selben Server liegen. Außerdem habe ich das gefühldas ich ein wenig unter OCD leide - wird noch geprüft.

          lgmb

          1. moin,

            Dann hatte ich dich falsch verstanden...

            Kein problem. Ich drück mich wirklich in dem Forum sehr undeutlich aus 😕.

            warum willst du denn nicht eine Verbindung offen halten?

            ich hätte gern alles drin oder draußen. Sprich: je nach URL-Route holt sich die App die angeforderten Daten aus der Datenbank raus und speichert sie dann in zur Laufzeit bereitstehenden Klassen.

            Eine solche Anforderung spricht mehr für mod_php. Dafür ist eine persistente DB Verbindung gar nicht notwendig, es genügt ja, die Daten beim Starten des Webservers in den Speicher zu laden. Wobei das auch sukzessive erfolgen kann: Bspw. so, daß das Template nur beim 1. Request auf einen URL geladen wird und bei allen weiteren Requests bereits im Hauptspeicher vorliegt.

            Da alle informationen jetzt zur Laufzeit in der App enthalten sind, können sich jetzt View-Templates mit diesen gespeicherten Daten befüllen lassen.

            Genau. Alternative zu mod_php ist fast_cgi, damit ließe sich das auch machen.

            Datenbanken sind dazu da Daten vorzuhalten. Wenn du diese jetzt nochmal extra cachest, erschließt sich mir nicht ganz der Sinn dahinter.

            Ganz einfach: Die Performance.

            Ich sehe Datenbank und PHP-Application als zwei Einheiten an und es ist nicht immer gegeben das Datenbank + App auf dem selben Server liegen.

            Ist auch gar nicht notwendig. Dem Webserver ist das völig wurst woher der seine Daten kriegt. Aber ein Benutzer freut sich, wenn sie bereits im Hauptspeicher liegen, denn das merkt er sehr deutlich!

            MfG

            1. Tach!

              ich hätte gern alles drin oder draußen. Sprich: je nach URL-Route holt sich die App die angeforderten Daten aus der Datenbank raus und speichert sie dann in zur Laufzeit bereitstehenden Klassen.

              Eine solche Anforderung spricht mehr für mod_php. Dafür ist eine persistente DB Verbindung gar nicht notwendig, es genügt ja, die Daten beim Starten des Webservers in den Speicher zu laden.

              mod_php hat keinen Shared Memory. Die Requests laufen voneinander getrennt, und die Daten stehen nicht gemeinsam zur Verfügung.

              Genau. Alternative zu mod_php ist fast_cgi, damit ließe sich das auch machen.

              Mit FCGI und auch FPM geht das ebensowenig. Wenn man einen dauerhaften Cache haben möchte, muss man sich eines anderen Dienstes bemühen, beispielsweise memcached.

              Man mag sich damit Geschwindigkeit holen, aber bekommt nun eine Menge neue Aufgaben, diesen Cache parallel zur Datenbank zu verwalten.

              dedlfix.

              1. Memcache ist ein Protokoll was Daten systemübergreifend verfügbar macht. Das meinte ich nicht. Ich bin nur davon ausgegangen, daß mod_php ähnlich wie mod_perl funktioniert. Damit ist das nämlich machbar was ich beschrieben habe: Sämtliche Templates (u.a. statische Daten) beim Starten des Webservers in den Hauptspeicher zu legen.

                Und das heißt, daß man hierzu eine etwaige DB Verbindung eben nur beim Serverstart benötigt. Ebenfalls im Hauptspeicher verbleiben kompilierte Klassen und Methoden als sog. Bytecode. So jedenfalls arbeitet mod_perl, das ist ja das was mod_perl so schnell macht.

                MfG

                1. Tach!

                  Memcache ist ein Protokoll was Daten systemübergreifend verfügbar macht.

                  memcached mit d am Ende ist kein Protokoll und Daten verfügbar machen kann nur eine Software. Genau das ist memcached, ein Service, der (vorzugsweise) lokal auf dem Server läuft.

                  dedlfix.

                  1. Tach!

                    Memcache ist ein Protokoll was Daten systemübergreifend verfügbar macht.

                    memcached mit d am Ende ist kein Protokoll und Daten verfügbar machen kann nur eine Software. Genau das ist memcached, ein Service, der (vorzugsweise) lokal auf dem Server läuft.

                    Nochmal: Ich meinte weder das Eine noch das Andere!

                    .

                    1. Hallo pl,

                      Nochmal: Ich meinte weder das Eine noch das Andere!

                      Dann solltest du dich vielleicht besser verständlich machen.

                      Bis demnächst
                      Matthias

                      -- Pantoffeltierchen haben keine Hobbys.
            2. moin,

              Eine solche Anforderung spricht mehr für mod_php. [...]

              ...und...

              [...] Alternative zu mod_php ist fast_cgi, damit ließe sich das auch machen.

              kann man das nicht per signifikanten User Token von der $_SESSION-gesteuert selber cachen? wie…

              class Cache { private static $_token; public static function init( string $token ) { self::$_token = $token; } public static function store( array $data ) : bool { // schreibt die temporären daten serialisiert mit self::$_token in PATH Konstante } public static function load() : array { // prüft ob PATH Konstante existiert und der self::$_token angehängt ist // dann öffnet und deserialöisiert die Klasse den Content und gibt ihn als array zurüch } }

              lgmb

              Folgende Nachrichten verweisen auf diesen Beitrag:

            3. moin,

              Ich mache mal nen neuen Thread auf mit dieser Frage

              lgmb

  2. ich möchte einen permantenten Zugriff auf die Daten die aus der Datenbank Tabellen kommen (z.B. Artikel, Benutzer (und plural) etc.) haben, sodass ich nicht jedesmal eine Verbindung zur Datenbank für nur einen HTTP-Aufruf auf und abbauen muss.

    Dein Stichwort lautet "Peristent Connection".

    1. Moin,

      Bei persistenten Verbindungen wird geschaut ob eine identische Verbindung besteht.

      Ich muss trotzdem jedes mal den Datenbankserver nach der Verbindung fragen. Das entfällt bei Nutzung einer Zwischenschicht wie z.B. node.JS.

      Gruß Bobby

      -- -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <- ### Henry L. Mencken ### -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <- ### Viktor Frankl ### ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Tach!

        Bei persistenten Verbindungen wird geschaut ob eine identische Verbindung besteht.

        Ich muss trotzdem jedes mal den Datenbankserver nach der Verbindung fragen.

        Mit anderen Worten: Das spart keinerlei Code. Es kommt sogar noch hinzu, dass man das Persistenzattribut angeben muss. Und dass das ganze sowieso nur funktioniert, wenn PHP als Modul im Apachen läuft (IIS und andere Webserver nicht betrachtend). Im Modul zu laufen, hat Nachteile in Webservern, in denen mehr als die eine Anwendung laufen soll, wie schlechte oder keine Separierbarkeit.

        dedlfix.

        1. Ich muss trotzdem jedes mal den Datenbankserver nach der Verbindung fragen.

          Mit anderen Worten: Das spart keinerlei Code. Es kommt sogar noch hinzu, dass man das Persistenzattribut angeben muss.

          Ich glaube, es ging MB nicht darum Code zu sparen, sondern die Effizienz zu steigern. Das eine Attribut mehr scheint mir für die geforderte Funktionalität die Lösung mit dem wenigsten Code zu sein. Oder hast du noch eine andere Idee, die mit weniger auskommt?

          Und dass das ganze sowieso nur funktioniert, wenn PHP als Modul im Apachen läuft (IIS und andere Webserver nicht betrachtend). Im Modul zu laufen, hat Nachteile in Webservern, in denen mehr als die eine Anwendung laufen soll, wie schlechte oder keine Separierbarkeit.

          Bist du da sicher? Das Handbuch sagt etwas anderes. Nur PHP als CGI scheint ein Problem zu sein, aber hat das heutzutage noch Relevanz?

          1. Tach!

            Ich muss trotzdem jedes mal den Datenbankserver nach der Verbindung fragen.

            Mit anderen Worten: Das spart keinerlei Code. Es kommt sogar noch hinzu, dass man das Persistenzattribut angeben muss.

            Ich glaube, es ging MB nicht darum Code zu sparen, sondern die Effizienz zu steigern. Das eine Attribut mehr scheint mir für die geforderte Funktionalität die Lösung mit dem wenigsten Code zu sein. Oder hast du noch eine andere Idee, die mit weniger auskommt?

            Der Verbindungsaufbau ist vernachlässigbar, wenn nicht gerade eine sehr langsame Netzwerkverbindung zwischen Webserver und DBMS besteht. Da lässt sich durch Netzwerkoptimierung mehr sparen. Zumal ein langsames Netzwerk ja auch auf Query- und Ergebnisübertragung wirkt.

            Und dass das ganze sowieso nur funktioniert, wenn PHP als Modul im Apachen läuft (IIS und andere Webserver nicht betrachtend). Im Modul zu laufen, hat Nachteile in Webservern, in denen mehr als die eine Anwendung laufen soll, wie schlechte oder keine Separierbarkeit.

            Bist du da sicher? Das Handbuch sagt etwas anderes. Nur PHP als CGI scheint ein Problem zu sein, aber hat das heutzutage noch Relevanz?

            Bei CGI wird für jeden Request ein Prozess gestartet und beendet. Da gibts nichts, was eine DBMS-Verbindung offenhalten könnte.

            Bei den Formen FCGI und FPM fehlt mir das Wissen, wie lange der Prozess bestehen bleibt und damit auch evenuell geöffnete Verbindungen. Da in diesen Szenarien mehrere PHP-Instanzen nebeneinander laufen, muss dann aber auch jede eigene ihre eigenen Verbindungen verwalten. Das hat dann keinen Effekt wenn der nächste Request an einen anderen Prozess im Pool geht, der die Verbindung noch nicht geöffnet hat. Es sei denn, die Verwaltung der Verbindungen kann von der Poolverwaltung übernommen werden. Da die Vorteile persistenter Verbindungen aber nicht wirklich merkbar sind, hab ich mich damit nicht weiter beschäftigt.

            dedlfix.

          2. Nur PHP als CGI scheint ein Problem zu sein, aber hat das heutzutage noch Relevanz?

            In Umgebungen, in denen die PHP-Skripte mit Rechten eines per Hostnamen konfigurierbaren Nutzers ausgeführt werden (shared hosting) hat PHP als CGI durchaus Relevanz.

            Und das sind verdammt viele...

            1. Tach!

              Nur PHP als CGI scheint ein Problem zu sein, aber hat das heutzutage noch Relevanz?

              In Umgebungen, in denen die PHP-Skripte mit Rechten eines per Hostnamen konfigurierbaren Nutzers ausgeführt werden (shared hosting) hat PHP als CGI durchaus Relevanz.

              Für nackiges CGI ist das keine Frage, aber wie genau verhält es sich bei FCGI und FPM? Da beide die Nachteile der langsamen Geschwindigkeit von CGI ausgleichen sind die ja eher relevant.

              dedlfix.

              1. Christoph Fischer hat eine kleine php-fcgid-Dok geschrieben.

                Demnach überleben fcgid-Prozesse eine konfigurierbare Weile (z.B. 500 Requests oder 300 Sekunden Untätigkeit + "IdleScanInterval 30") - und ja: Auch hier ist der Benutzer und die Gruppe konfigurierbar. Mein Hoster (einer der besseren) benutzt es fürs Shared Hosting.

                Die persistente Datenbankverbindung lebt maximal so lange wie der fcgid-Prozess. Das hilft also schon ...

      2. Bei persistenten Verbindungen wird geschaut ob eine identische Verbindung besteht.

        Das muss ja auch so sein. Identisch heißt, dass Server, Nutzer und Passwort übereinstimmen müssen. Es wäre ja ein Bug, wenn ich eine Verbindung max:passwort@127.0.0.1:3306 haben möchte, aber stattdessen eien Verbindung root:geheim@127.0.42:3306 bekomme. Das müsste ein Service mit Node also auch sicherstellen.

        Ich muss trotzdem jedes mal den Datenbankserver nach der Verbindung fragen.

        Nein, die Verbindung wird vom Webserver gespeichert und offen gehalten. Der Datenbankserver muss nicht erneut angefragt werden. Das wäre auch ein seltsamer Zirkelschluss, um eine Verbindung vom Datenbankserver zu bekommen, müsste ich ihn erstmal fragen, also müsste ich schon eine Verbindung haben.

        Das entfällt bei Nutzung einer Zwischenschicht wie z.B. node.JS.

        Für den Vorschlag mit Node hab ich dir auch ein Sternchen gegeben. Konzeptionell hast du aber ein ähnliches Problem: Jetzt muss sich jeder PHP-Prozess mit dem Node-Service verbinden. Ich glaube trotzdem, dass das effizienter seien kann als sich erneut mit dem DB-Server zu verbinden. Inbesondere wenn Node und PHP auf dem selben physischen Server laufen, die Datenbank aber woanders.

        Die PHP Lösung scheint mir trotzdem einfacher.

        1. Die PHP Lösung scheint mir trotzdem einfacher.

          Ich würde auch dabei bleiben wollen. Die Verfügbarkeit von Node-Js oder auch der Möglichkeit, mit Python oder PHP kleine "Serviceserver" zu installieren, ist nämlich begrenzt. Einmal schon durch die PIDs und dann die Ports. Beim Shared Hosting sind nämlich mitunter die Webseiten tausender Kunden auf einem Server. Und wenn die jetzt anfangen, wie die Weltmeister solche "Serviceworker" zu starten, dann werden je nach Konfiguration zuerst entweder die PID oder die Ports knapp.

          Außerdem muss dann (shared hosting) beim Zugriff eine Authorisierung stattfinden. Die wird so teuer, dass der Geschwindigkeitsgewinn sehr negativ ist.

          Auf einem eigenen Server kann man natürlich tun und lassen was man will. Jedenfalls bis der Access-Provider an seiner Firewall fummelt weil zu viele Beschwerden über Spamversand oder Hackversuche bei seinem abuse auflaufen…

          1. Außerdem muss dann (shared hosting) beim Zugriff eine Authorisierung stattfinden. Die wird so teuer, dass der Geschwindigkeitsgewinn sehr negativ ist.

            Oh. Und diese Verbindung ist, weil unverschlüsselt, von anderen Benutzern womöglich (z.B. tcpdump braucht er schon noch) belauschbar.

            1. Außerdem muss dann (shared hosting) beim Zugriff eine Authorisierung stattfinden. Die wird so teuer, dass der Geschwindigkeitsgewinn sehr negativ ist.

              Oh. Und diese Verbindung ist, weil unverschlüsselt, von anderen Benutzern womöglich (z.B. tcpdump braucht er schon noch) belauschbar.

              AFAIK benutzen Shared Hoster Sandboxing um Kundendaten voneinander zu isolieren. Zum Beispiel den User-mode. Damit lassen sich auch die Kommunikation zwischen Prozessen via Unix-Sockets und die Netzwerk-Kommunikation mittels TCP regulieren. Da bleibt natürlich trotzdem noch Luft für Fehler seitens der Konfiguration. Wenn schon Zweifel bei der grundlegendenden Sicherheitsarchitektur eines Shared Hosters bestehen, dann sollte man da besser gar nicht erst hosten.

              1. AFAIK benutzen Shared Hoster Sandboxing um Kundendaten voneinander zu isolieren.

                Meiner wohl nicht. Der Kernel meldet sich als Stino-Distributionskernel und ich sehe fremde Prozesse mit ps -eLF.

                Ich bin mir auch nicht ganz sicher wie das mit sehr vielen Benutzern und vor allem dem Webserver gehen soll. Hier geht es nicht um "Cloud".