Daten halten ohne immer wieder eine Datei neu zu laden
Kukulkan
- php
Hallo,
Ich möchte PHP-weit eine Liste mit Daten halten die immer wieder benötigt werden und sich jederzeit ändern können. Es sind keine Sessions im Spiel und ich überlege, diese Daten in einer Datei zu speichern. Aber das bedeutet, dass jeder Aufruf meiner PHP Seite einen Dateizugriff triggert. Kann ich solche Daten nicht permanent im RAM des Servers verwalten? So, dass es allen Scripten immer zur Verfügung steht und auch durch diese geändert werden kann?
Ich stelle mir sowas vor:
<?php
SetPersistantValue('ValueName', 'Test');
// anderes Script irgendwo auf diesem Server
echo GetPersistantValue('ValueName'); // -> 'Test'
?>
Das bedeutet, dass jederzeit dieser Wert ohne Rücksicht auf Session, ClientID's etc. abzufragen und zu setzen ist.
Gibts da eine Lösung?
Kukulkan
Hi,
Kann ich solche Daten nicht permanent im RAM des Servers verwalten? So, dass es allen Scripten immer zur Verfügung steht und auch durch diese geändert werden kann?
ja, das geht mit Shared Memory
weitere Infos:
http://www.php.net/manual/de/ref.shmop.php
steht aber nicht auf allen Servern zur Verfügung
Gruß Udo
Hallo Udo,
ja, das geht mit Shared Memory
weitere Infos:
http://www.php.net/manual/de/ref.shmop.phpsteht aber nicht auf allen Servern zur Verfügung
Vielen Dank für die Info und den Link. Soweit ich das sehe, muss PHP davor speziell kompiliert werden (auch unter Windows?). Ich möchte die Anwendung auf vielen Servern (nicht meinen) betreiben (lassen) und da wird das zum Problem. Gibt es noch eine andere Lösung (ausser Globalen Variablen)?
Wie sehr wirkt sich ein dauernder Lesezugriff auf eine 2KB grosse Datei eigentlich auf die Performance aus? Geht das nicht immer über den Cache des Filesystems?
Kukulkan
Hi,
Soweit ich das sehe, muss PHP davor speziell kompiliert werden (auch unter Windows?).
ja, soweit ich weiss steht es unter Windows nicht zur Verfügung
bzw. PHP muss neu kompiliert werden ( auf meinem XAMPP auch nicht )
Ich möchte die Anwendung auf vielen Servern (nicht meinen) betreiben (lassen) und da wird das zum Problem.
eine Lösung wäre das Betriebssystem abzufragen, falls Windows, die Variablen in einer Datei speichern, unter Linux shmop benutzen
http://www.php.net/manual/de/ref.shmop.php
auf der Seite findest du Beispiele
Gibt es noch eine andere Lösung (ausser Globalen Variablen)?
mmh ? Globale Variablen ? ... die sind doch nach Scriptende futsch ?
Wie sehr wirkt sich ein dauernder Lesezugriff auf eine 2KB grosse Datei eigentlich auf die Performance aus? Geht das nicht immer über den Cache des Filesystems?
ich denke ja, um wiewiel Shared Memory schneller ist müsste man mal ausprobieren
Gruß Udo
Hallo Udo,
Ich habe mich jetzt aus Kompatibilitätsgründen für die Verwendung einer Datei entschieden. Ich habe auf meiner Kiste (VMWare auf Athlon64 3200+ mit XAMPP unter WinXP) folgendes Script getestet:
<?php
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
echo "Starte...<br>";
$start_time = getmicrotime();
for ($x=1; $x<=10000; $x++) {
$datei = fopen("c:\Testdaten.dat", "r");
$inhalt = fgets($datei);
fclose($datei);
}
$zeit = getmicrotime() - $start_time;
echo "Ende nach $zeit Sekunden";
?>
Die Testdaten.dat enthielt folgenden Text:
Zeile 1 mit einem Servernamen
Zeile 2 mit einem Servernamen
Zeile 3 mit einem Servernamen
Zeile 4 mit einem Servernamen
Ich benötige für 10'000 Zugriffe nur 0,53 Sekunden! Das ist für mich in Ordnung, denn ganz offensichtlich wird der Cache des Filesystems verwendet und ich kann 10'000 Zugriffe mit den Kosten von 0,5 Sekunden berechnen.
Dennoch Danke für deine Hilfe, Udo.
Grüsse,
Kukulkan
Ups, ein Fehler...
for ($x=1; $x<=10000; $x++) {
$datei = fopen("c:\Testdaten.dat", "r");
$inhalt = fgets($datei);
fclose($datei);
}
Der Loop muss natürlich so lauten:
for ($x=1; $x<=10000; $x++) {
$datei = file("c:\Testdaten.dat")
}
So wird die ganze Datei in das Array $datei[] eingelesen (und nicht nur die erste Zeile) und ich benötige sogar nur rund eine Sekunde für 10'000 Zugriffe. Also für mich ist das völlig ausreichend!
Kukulkan
Hi,
Ich habe mich jetzt aus Kompatibilitätsgründen für die Verwendung einer Datei entschieden.
ich denke eine gute Lösung
da es mich interessiert hat, habe ich folgendes probiert:
<?php
$shm_id = shmop_open(0x0fff, "a", 0644, 2000);
//$string = file_get_contents("string.txt");
//shmop_write($shm_id, $string, 0);
$string = shmop_read($shm_id, 0, 2000);
//print $string;
//shmop_write($shm_id, $string, 0);
//shmop_delete($shm_id);
?>
<?php
// Dateiversion
$string = file_get_contents("string.txt");
//print $string;
?>
Webclient Athlon 2800XP Win XP / Server Celeron 400 MHz Linux Apache/2.2.3 (Debian) Php 5.2 ( mein altes Schätzchen ;-) )
mit dem Apacheprogramm "ab" habe ich beide Versionen getestet
Ergebnis: die Dateiversion war praktisch immer schneller
... konnte es kaum glauben ( hab auch verschiedene Dateigrössen
100byte bis 100 kb ausprobiert )
unsere Tests sind wahrscheinlich etwas praxisfremd, da auf einem realen WebServer ja noch mehr passiert aber trotzdem hätte ich
gedacht daß die SHMOP-Variante um einiges schneller ist
Gruss Udo
Hallo Udo,
Interessant! Und gut zu wissen...
Ich denke, die File-Version ist auf einem echten Webserver nicht immer die schnellere. Da ich aber nur einen HTTP-Service betreibe (in PHP) und keine Public-Webseite dazu hoste, ist der Datei-I/O sicher nicht so hoch und diese Version akzeptabel schnell.
Grüsse,
Kukulkan