mmofacts.com

Bild in MySQL BLOB

gepostet vor 17 Jahre, 10 Monate von Amun Ra
Ich habe eine kurze Frage:
Ich möchte ein Bild in ein MySQL BLOB Feld speichern
und es wieder ausgeben.
Das ist an sich auch kein Thema.
Hab genug darüber bei Google gefunden:
www.phpbuilder.com/columns/florian19991014.php3
Aber:
Ich hätte gern, das ich ein von PHP erzeugtes Bild
direkt und ohne zwischenspeichern und anschließendes löschen
in die DB schreiben kann.
$img = imagecreatefromjpeg('test.jpg');
mysql_query("INSERT INTO bin_data (data) VALUES ('$img')");
Das funktioniert aber bis jetzt nicht.
Ich muss das erzeugte Bild speichern,
nach dem Schema aus dem Artikel einlesen,
in MySQL speichern und das Bild löschen.
Hat jemand eine Idee.
Wäre eine große Hilfe !
Danke im Vorraus !
MfG
gepostet vor 17 Jahre, 10 Monate von Toby
Wie wärs mit sowas?
ob_start(); // start a new output buffer

imagejpeg( $img);
$ImageData = ob_get_contents();
$ImageDataLength = ob_get_length();
ob_end_clean(); // stop this output buffer
Direkt auf $img kannst du eh nicht zugreifen, das ist nur eine Ressource, ein "Zeiger" auf das Bild.
Evt. könnte da auch noch was mit Streams oder so klappen, also das du das Bild in einen Stream zwischenspeichern lässt.
Wieso willst du eigentlich überhaupt Bilder in der DB speichern? Eigentlich wird davon generell abgeraten.
gepostet vor 17 Jahre, 10 Monate von exe
Ausserdem solltest du mit addslashes() oder mysql_*_escape() die Daten entschärfen. Denn bei einer Binärdatei weisst du nicht, ob nicht ein paar Bytes in einem Textkontext nicht doch als Anführungszeichen interpretierbar sind ..
Nebenbei: gibts bei MySQL keine Möglichkeit, BLOBs seperat zu übertragen, so dass man ein Binärdatei in einen Textquery packen muss?
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Danke erstmal für die Antworten !
Ich bin zwischenzeitig zum Ziel gelangt:
$img = imagecreatefromjpeg('mysql_test.jpg');
ob_start();
imagejpeg($img);
$data = mysql_real_escape_string(ob_get_contents());
ob_end_clean();
mysql_query("INSERT INTO bin_data (data) VALUES ('$data')");
Funktioniert wunderbar.
Ich sage mal, die müssen einfach in die Datenbank.
Außerdem sind das extrem kleine Files und eine
absehbar kleine Menge an Files.
MfG
gepostet vor 17 Jahre, 10 Monate von progs
Ich sage mal, die müssen einfach in die Datenbank.
Außerdem sind das extrem kleine Files und eine
absehbar kleine Menge an Files.

Kein Bild muss in die Datenbank. Aus meiner Meinung extrem ungeschickt, auch wenn die Bilder noch so klein sind oder wenige. Lieber nur eine URL oder Verweis auf ein Bild, als das Bild selber speichern. Eine Datenbank ist bei sowas ziemlich langsam und nicht dafür gedacht.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Okay, sicher ist diese Lösung in den meisten Fällen ungünstig.
Aber mal angenommen, die Applikation erfährt gewisse Resonanz
und hat viel Last und Traffic.
Und man möchte dann mehrere Apaches und Mysql auf
verschiedenen Rechnern betreiben.
Wäre es dann nicht günstiger,
die Bilder in der DB abzulegen,
als auf den einzelnen Apachenodes ?
Performanceprobleme gibts da denke ich nicht,
gibt ja auch noch Partitionierung und Replikation.
gepostet vor 17 Jahre, 10 Monate von exe
Bilder transferieren, auch wenn sie klein sind, verursacht Traffic in deiner Datenbankverbindung. Traffic der nicht sein muss. Ich würde die Bilder nur zu Archivierungszwecken in einer Datenbank speichern. In einer Webanwendung wo sie stark frequentiert werden ist das Dateisystem besser.
Im Sinne von Clustering geben sich die Methoden nichts. Wenn du die Dateien in der Datenbank speicherst muss die Datenbank diese auch im Cluster replizieren. Das gleiche musst du machen, wenn du sie direkt vom Dateisystem aus "servierst". Im einfachsten Fall legst du die statischen Bilder auf einen zentralen Server und mountest sie von da in die einzelnen Apachenodes. Wenn das zu langsam ist kannst du sie immernoch regelmäßig vom zentralen Server auf die Festplatte des Apachenodes kopieren um die IO-Performance zu verbessern.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Anmerkung: die Bilder ändern sich im Extremfall alle paar Sekunden.
Meine Überlegung war, das man dann auch alle paar Sekunden
für die Aktualität auf allen Nodes sorgen muss
und das sich das mit einer DB besser handhaben lässt.
Wenn man natürlich eine Node nur fürs Bilder servieren nutzt,
macht das die Sache natürlich auch wieder praktischer.
Dann hat man natürlich die Apaches, den MySQL Daemon
und zusätzlich einen Imageserver.
Ich wäre für weitere Gedanken / Anregungen zum Thema dankbar !
MfG
gepostet vor 17 Jahre, 10 Monate von mifritscher
Wie viel Bilder sind's denn? 100 MB? 200 MB?
Wie viel Trafik erzeugen die Bilder?
Ich würde sie auch eher auf die HDD speichern. Wenn sie verändert werden überträgst du die per nfs oder sowas auf die anderen Rechner.
Oder du speicherst die zentral auf einem Server und greifst per nfs darauf zu, wohl wissend dass wenn du es mountest der FS-Cache von Linux das meiste abfängt.
Für die Aktualität müssen dann der nfs-Client und der FS-Cache sorgen, die ja gansu auf slche Aufgaben spezialisiert sind.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Also, momentan sind es gerade einmal 20 Bilder,
mit je 1 - 2 KB Größe.
Also sehr klein.
Die Anzahl ist sehr langsam steigend
und wird die 1000er Marke wohl nicht durchbrechen.
Es geht also um weniger als 2 MB.
Ich denke, das bei jedem Aufruf eines großen
und gut frequentierten Forums,
MySQL mehr Daten ausliefern muss.
Weitere Gedanken / Meinungen / Anregungen ?
gepostet vor 17 Jahre, 10 Monate von Agmemon
Bei vielen und großen Binärdaten bietet sich der Weg über NFS natürlich eher an, würde aber Binärdaten in der Datenbank nicht grundsätzlich verteufeln. Kommt halt immer aus Anzahl, Größe und das Datenbankdesign an. Wenn die Bilder z.B. in einer Tabelle liegen, die ständig mit SELECT * abgefragt wird, schaffst Du unnötigen Traffic. Fragst Du die Daten aber selektiv ab, wird es bei kleinen Daten kaum merklich höheren Traffic geben, so dass es verschmerzbar ist.
gepostet vor 17 Jahre, 10 Monate von Klaus
Neben den ganzen hier genannten Nachteilen gibt es 2 Vorteile:
- Eine Zwischenspeicherung beim Klienten kann unterbunden werden. Aber ein Zugriff per Skript auf das Dateisystem erledigt den gleichen Job, nur besser.
- Dank SQL kann mit der ganzen Sprachgewalt nach dem richtigen Bild gesucht und gefiltert werden. Wenn du aber sowieso nur nach einer ID suchst hat sich das erledigt.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Ich finde es sehr gut, das der Thread ein paar Antworten bekommen hat.
Ist in der letzten Zeit recht ruhig hier in den Entwicklerforen.
Ich frage die Daten selektiv ab.
Die Tabelle hat außerdem nur die 2 Spalten id und bin_data.
gepostet vor 17 Jahre, 10 Monate von Freshman
Die bilder solltest du auf keinem Fall in der Datenbank speicher, da du dein System unnötig belastest.
Es ist ja so, wenn ein Bild nich neu und, dann lädt der User es auch nicht runter, da die browser es aus dem Cache nehmen.
Auch wenn sich manche alle paar Sekunden ändern können in den paar Sekunden 10 User doppel klicken, wodurch du 10 Bilder aus der Datenbank lädst, die du dir sparen könntest.
Da du von Clusterlösungen sprichst gehe ich davon aus, dass die Bilder auf einem vernünftigen NAS liegen, weshalb das auf jeden Fall performanter als die MySql Datenbank ist, vor allem weil sie von dort auch nur gelesen werden, wenn sie benötigt werden ( abgesehen von den "zuletzt geändert" Daten )
Mein Tipp.... einfach auf Festplatte speichern.
gepostet vor 17 Jahre, 10 Monate von None
Binärdaten in eine Datenbank legen... *grussel*
Das müssen schon verdammt wichtige Gründe sein, bevor man sowas macht und unter uns... in über 10 Jahren Berufserfahrung im IT-Bereich einer Großbank ist mir SOWAS noch NIE untergekommen.
*Grussel*
Alleine die möglichen Sicherheitsrisiken...
Erkläre uns doch bitte mal genau wieso du gerade Binärdaten in einer Datenbank ablegen willst und nicht im Filesystem.
Auf DIE Begründung bin ich gespannt. Bisher habe ich halt wirklich noch keine gute gehört.
gepostet vor 17 Jahre, 10 Monate von Kampfhoernchen
Datenunabhängigkeit is der einzige Grund der mir einfällt.
Aber wo bitte soll da ein Sicherheitsrisiko liegen?
gepostet vor 17 Jahre, 10 Monate von None
Du mußt durch mehrere Datenschichten hindurch.
Frontend, Businesslayer, Database.
Tip:
Sicherheitsrisiko Web-Anwendungen
Bin im Moment noch ein bissle verpennt, von daher verweise ich einfach ma da drauf.
gepostet vor 17 Jahre, 10 Monate von exception
Original von woodworker
dazu kann ich nur sagen: mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html
So, most of the “I want images in MySQL” conversations are terminated with “Don’t.”

Und dennoch kann es in einigen Fällen die beste Lösung sein:
zum Beispiel:
geringer Implementierungsaufwand
es mus keine Extra-Backup-Lösung für Bilder im Dateisystem eingerichtet werden
Bilder automatisch im Cluster verfügbar ohne NFS, AFS oder andere verteilte Dateisysteme
bei kleinen Datenmengen würde ich sogar Performance-Vorteile vermuten
gepostet vor 17 Jahre, 10 Monate von woodworker
mhh glaub ich nicht
vorallem nicht bei mysql - denn mysql ist für datensätze mit geringer größe konzipiert und es kann nur zufällig mit LOBs umgehen.
ok ne DB die extra für LOBs ausgelegt ist kann das so sein aber nicht mysql
und vorallem wenn mysql auch noch mit anderen sachen beschäftigt ist
gepostet vor 17 Jahre, 10 Monate von Agmemon
Original von woodworker
dazu kann ich nur sagen: mysqldump.azundris.com/archives/36-Serving-Images-From-A-Database.html

Die Überlegungen des Autors sind nicht verkehrt. Er bedenkt aber zwei Sachen nicht, die hier gefragt bzw. besprochen wurden:
1. Der Autor geht von großen Datenmengen aus, was man daran sieht, dass er die Größe der Netzwerkpakete mit beachtet.
2. Die Überlegungen gehen davon aus, dass sich alles auf der selben Maschine befindet. Was aber, wenn es sich um eine Cluster-Lösung handelt? SMB oder NFS verschlingen auch Performance und sorgen für Prozesswechsel Und Wechsel zwischen kernel und user mode.
Ich meine, es steht ausser Frage, dass Grafiken mit ein paar hundert KB nix in der DB zu suchen haben. Aber wo bitte ist der Unterschied, ob ich 1 KB Text in einem Textfeld speichere oder eine 1KB große Grafik?
gepostet vor 17 Jahre, 10 Monate von None
Du umgehst die Cachingmechanismen der Browser/Proxys.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
@woodworker
Ich hoffe du hast nicht nur den ersten Satz des Artikels gelesen ??!
Der Autor schreibt nämlich auch:
"As I've said many many times, you can't just blindly follow a rule, you have to *think*."
"Therefore, it's not *always put large data in a db*, nor is is *never put large data in a db*,
it's *do what's right for you, and your system, in your environment, with your skillset*"
"In the end, the filesystem is always the best container for information you don't plan on changing a lot."
Auch die anderen Kommentare sollte man mal lesen:
"Point taken that it's maybe not as fast (and so on),
then serving directly from a filesystem (using a small httpd),
yet, the features (clustering, backup) easily outrule the loss
of performance you encounter."
"Yep, so you have a background script which runs every 2 minutes
and pulls new images out of the database and writes them to disk."
"darix has hit it right - using the database not as a delivery mechanism,
but as a distribition mechanism is quite simple and elegant."
Und noch ein kurze Frage:
ifbdppi.infobolsanet.com/serverdatapumpdb/dbag/chart.srf?module=M_ChartSmall&wp=DE0008469008〈=de
Was meint ihr, wo kommt das Bild her ?
FS oder DB oder eine Kombination von beidem ?
Oder immer on the Fly neu gezeichnet ?
MrMarco du arbeitest bei einer Großbank...
Was meinst wie handhaben die das mit den Charts ?
gepostet vor 17 Jahre, 10 Monate von exe
Original von MrMarco
Du umgehst die Cachingmechanismen der Browser/Proxys.

Sicher? Ob das Bild innerhalb des Servers vom Dateisystem oder der Datenbank kommt kriegt ein Browser/Proxy doch gar nicht mit ...
gepostet vor 17 Jahre, 10 Monate von None
Die Charts werden meines Wissens nach auf mehreren Wegen bereit gestellt.
Zum einen als Java-Applet, welches die Daten in komprimierter Form erhält, direkt aus der Datenbank (Börsen-Liveticker) oder als auf Raid gespeicherte Images.
Letzteres zum Beispiel bei Grafiken, welche nur sehr selten einer Veränderung unterliegen, aber eine sehr hohe Zugriffsmenge haben.
Aber Grafiken in einer Datenbank ablegen? Die Daten dafür ja um sie zu erzeugen auf dem Client, aber als fertige Grafiken? Eher nicht.
gepostet vor 17 Jahre, 10 Monate von None
Original von exe
Original von MrMarco
Du umgehst die Cachingmechanismen der Browser/Proxys.

Sicher? Ob das Bild innerhalb des Servers vom Dateisystem oder der Datenbank kommt kriegt ein Browser/Proxy doch gar nicht mit ...
Wie überträgst du das Bild? Kannst du sicherstellen das die für den Browser wichtigen Informationen die das Caching ermöglichen, auch in diesen Grafiken enthalten sind?
Schreibst du das Bild erst auf die Platte und überträgst es dann, damit der Filename immer gleich bleibt?
Wenn du sie auf die Platte schreibst, wieso dann den Umweg über die Datenbank?
Oder wenn du direkt per Encoding die Daten im HTML-Context auslieferst, wo ist dann die Ersparnis? Du brauchst sowohl mehr CPU-Power als auch mehr Datenvolumen für das Übertragen. Und genau bei so einer Lösung umgehst du das Caching!
Nimm es mir nicht übel, aber Bilder in einer Datenbank sind in meinen Augen der absolut größte Schwachsinn (ok, neben Samples), die man mit einer Datenbank machen kann. Nur weil man sowas in einer Datenbank speichern kann, muß man es noch lange nicht machen. Für sowas ist und bleibt das Filesystem der beste und schnellste Aufbewahrungsort von allen.
gepostet vor 17 Jahre, 10 Monate von TheUndeadable
> Kannst du sicherstellen das die für den Browser wichtigen Informationen die das Caching ermöglichen, auch in diesen Grafiken enthalten sind?
Dafür gibt es HTTP-Header. Wenn man diese korrekt setzt, dann ist es dem Browser egal, ob sie von der Datenbank kommen oder von der Festplatte direkt.
> Für sowas ist und bleibt das Filesystem der beste und schnellste Aufbewahrungsort von allen.
Mit dem einen Nachteil, dass man den dazugehörigen Datensatz löschen kann und man die Grafik von der Platte selbst löschen muss. Hat man das Bild in der Db, so verschwindet die Grafik automatisch mit dem dazugehörigen Datensatz.
Aber um eine Grafik in der Datenbank zu speichern, bräuchte ich schon verdammt gute Gründe. Man sollte zumindest darauf achten, dass durch diese großen Bilddaten und deren Löschungen die Datenbank nicht zu sehr fragmentiert.
gepostet vor 17 Jahre, 10 Monate von exe
Original von MrMarco
Original von exe
Original von MrMarco
Du umgehst die Cachingmechanismen der Browser/Proxys.

Sicher? Ob das Bild innerhalb des Servers vom Dateisystem oder der Datenbank kommt kriegt ein Browser/Proxy doch gar nicht mit ...
Wie überträgst du das Bild? Kannst du sicherstellen das die für den Browser wichtigen Informationen die das Caching ermöglichen, auch in diesen Grafiken enthalten sind?
Schreibst du das Bild erst auf die Platte und überträgst es dann, damit der Filename immer gleich bleibt?
Wie Undeadable schon erwähnt hat: das sind eine Sache der HTTP-Header. Das hat mit der serverinternen Quelle der Bilddaten reichlich wenig zu tun.
Das soll aber keine Rechtfertigung sein um die Bilder in einer Datenbank zu speichern. Ich sehe da ebenfalls keine Gründe für. Vorallem nicht wenn sich die Grafiken so häufig ändern wie das hier angedeutet wurde.
Das Argument mit dem Clustering zieht IMHO auch nicht. Wenn das Spiel soviel Last erzeugt, dass ich einen Datenbankcluster aufsetzen muss bin ich auch schnell an dem Punkt wo ich auch einen Webservercluster aufsetzen muss. Und dann hab ich auch auf Frontendseite einen Cluster der den Quellcode und statische Dateien wie die Bilder replizieren kann.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Ein "einfacher" Cluster im Round Robin Verfahren
muss gar nichts replizieren ??!
gepostet vor 17 Jahre, 10 Monate von None
Original von Amun Ra
Ein "einfacher" Cluster im Round Robin Verfahren
muss gar nichts replizieren ??!

Du gehst hier dabei davon aus, daß die anzuzeigenden Informationen auf allen Servern im Cluster vorhanden sind.
Ok... und wie kommen sie da hin? Per Replikation.
Entweder bei Datenbanken im Push/Pull Verfahren oder per Copy-Strecken im Filesystem.
Man kann hier auch Hooks verankern welche bei Änderungen getriggert werden und die Dateien dann per Replikationsverfahren auf die anderen Server verteilen.
gepostet vor 17 Jahre, 10 Monate von exe
Original von Amun Ra
Ein "einfacher" Cluster im Round Robin Verfahren
muss gar nichts replizieren ??!

Round Robin ist eine Art der Lastverteilung bei der Anfragen einfach Reihum im Cluster verteilt werden. Wenn du im Round Robin Verfahren dein Loadbalancing machst musst du erst recht Replikation betreiben. Stell dir vor Anfragen an das Frontend werden so auf die einzelnen Server im Frontendcluster deligiert. Im ersten Request landet der User auf Server1 und kriegt da seine Session. Im zweiten Request landet er dann auf Server3 wo seine Session nicht existiert. Also ist er plötzlich ausgeloggt. Abhilfe schafft Sessionreplikation womit eine Session auf alle Clusternodes verteilt wird, es also keine Rolle spielt auf welchem Node ein Request landet.
Das ist ein ähnliches Thema im Datenbankcluster. Wenn eine Datenänderung an einem Clusternode (oder einem Replikationsserver) durchgeführt wird muss diese Änderung auf alle Clusternodes verteilt werden. Sonst laufen dir die Datenbanken auseinander und jenachdem auf welchem Node ein Query landet bekommst du unterschiedliche Ergebnisse.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Nein, ich gehe davon aus, das alles was auf den Nodes liegt statisch ist.
Es ist egal wo der Request landet.
Meine Sessions liegen in einer Memory Tabelle,
also ist es auch hier egal wo der Request landet.
Mal zur Erklärung:
Ich bin noch Student, Winfo.
Ich mach das hier als Hobby, um meine Skills in Sachen Web
und Datenbanken zu verbessern.
Ich suche nach einer Lösung für mich, die ich, falls es jemals
zum Release oder sogar Erfolg kommt, fast selbst betreiben kann,
ohne jetzt nebenbei noch Linuxadministrator zu werden.
Ich denke also ein wenig vorraus.
Ein späteres Redesign der ganzen Applikation hatte ich nicht vor.
gepostet vor 17 Jahre, 10 Monate von None
Dein Vorhaben in Ehren, aber ohne ausreichende Kenntnisse des jeweiligen Betriebssystems kommst du definitiv nicht weiter.
Gerade bei Themen wie LoadBalancing und Co. spielen noch mehr Sachen mit als nur die Einstellungen im Datenbankserver.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
Ich arbeite zur Zeit im Praxissemster auf und mit Linux.
Habe mich wegen dem Thread hier auch mit
NFS, rsync, pound, memchached befasst.
Also ich sag nicht das ich das nicht raffen würde,
aber irgendwann erliegt jeder dem Information Overload...
Ich suche nach einer performanten und zugleich bequemen
Lösung, sofern es die gibt
Vorschlag:
"darix has hit it right - using the database not as a delivery mechanism,
but as a distribition mechanism is quite simple and elegant."
User 1 sendet Request 1 an Server 1
-> Server schaut im FS nach ob das Bild vorhanden und aktuell ist
-> wenn nein holt er das Bild aus der DB ins FS und liefert es aus
User 1 sendet Request 2 an Server 2
-> selbes Spiel...
User 2 sendet unterdessen Request 3 an Server 1
-> das Bild ist nun für einen gewissen Intervall aktuell
und wird statisch ausgeliefert
Was meint ihr ?
Wäre quasi ein Kompromiss aus beiden Lösungen.
gepostet vor 17 Jahre, 10 Monate von None
Ich verstehe immer noch nicht, wieso du so krampfhaft an deiner Datenbanklösung festhälst.
gepostet vor 17 Jahre, 10 Monate von Todi42
Original von Amun Ra
Vorschlag:
"darix has hit it right - using the database not as a delivery mechanism,
but as a distribition mechanism is quite simple and elegant."
User 1 sendet Request 1 an Server 1
-> Server schaut im FS nach ob das Bild vorhanden und aktuell ist
-> wenn nein holt er das Bild aus der DB ins FS und liefert es aus
User 1 sendet Request 2 an Server 2
-> selbes Spiel...
User 2 sendet unterdessen Request 3 an Server 1
-> das Bild ist nun für einen gewissen Intervall aktuell
und wird statisch ausgeliefert
Was meint ihr ?
Wäre quasi ein Kompromiss aus beiden Lösungen.

Bei nebenläufigen Anfragen, die auf das gleiche Bild zugreifen, must Du sicher stellen, das nicht versucht wird, ein Bild auszuliefern, das gerade aus der Datenbank gelesen wird und auf die Platte geschrieben wird. Also z.B. die Bilddatei erst unter einem "zufälligen" Namen erstellen und dann umbennen, dann muß die Software natürlich auch damit umkönnen, das das Ziel der Umbennung schon vorhanden ist, weil ein anderer Prozess genau das gleiche gemacht hat. Um sicher zu stellen, das das auch garantiert funktioniert, muß man wahrscheinlich einiges an Doku lesen, da einfaches "Testen" nicht reicht. Die Lösung ist dann recht Plattformabhängig.
Wenn die Datenmengen eh kein Brott fressen würde ich ganz klar nach dem KISS Prinzip vorgehen. Bau die eine Schnittstelle zu diesen Dateien, die Du dann später einfach anders implementierst, wenn sie Performanzproblem zeigen.
gepostet vor 17 Jahre, 10 Monate von exe
"Performant" und "Bequem" sind eigentlich zwei sich beissende Begriffe Clustering ist keine einfache Sache, ich steh da selbst noch ziemlich am Anfang.
Ich sehe bei dir ein Problem. Nach deinen letzten Beiträgen zu urteilen, stellst du dir eine Lösung vor, bei der du mehrere Frontendserver, also einen Cluster aus Webservern, hast und einen Datenbankserver. Wenn du dann alle Daten, also auch die Session, in der Datenbank hälst musst du dir tatsächlich keine Gedanken um Replikation machen. Schliesslich gibt es nur einen einzelnen Datenbankserver ...
Wenn du aber davon ausgehst, dass du soviel Last auf deiner Anwendung hast, dass ein Frontendcluster nötig wird, dann bezweifle ich ob du mit einem einzelnen Datenbankserver noch zurecht kommst. Gerade bei einer datenbanklastigen Anwendung wie einem Browserspiel wird die Datenbank schnell zum Flaschenhals. Vorallem wenn bei jedem Request auf ein Bild Abfragen an die Datenbank fällig werden (irgendwie muss die Aktualitätsprüfung des Bildes im Dateisystem ja funktionieren). Diese Abfragen sind für sich genommen kein Performanceproblem, wenn du aber aus Clusteringgründen restlos alle Daten in der Datenbank lagerst um von einem fertigen Replikationssystem zu profitieren (oder nicht im Frontendcluster replizieren zu müssen), dann wirst du noch mehr solcher Themen erleben. Dann hast du irgendwann halt pro Request eine Abfrage für ein Bild, zwei für die Session (auslesen und Ausführungszeit notieren), eine für den User, eine für Konfigurationseinstellungen etc.pp.
Kurz: je mehr Last du auf die Datenbank abwälzt desto schneller wird dir ein einzelner Datenbankserver nicht reichen. Und wenn du die Datenbank clusterst dann clusterst du die Stelle wo deine Änderungen eingehen. Und dann geht das Thema mit Replikation los. Und auch wenn es fertige Lösungen dafür gibt sind diese oft auch mit Vorsicht zu geniessen. Reine SQL-Relays funktionieren oft nicht (angenommen ein Trigger hat ein zufälliges Verhalten und eine Abfrage die den Trigger auslöst wird im Cluster verteilt dann können auf jedem Knoten im Cluster andere Ergebnisse zustande kommen und die Datenbanken laufen auseinander) und Replikationssysteme sind nicht immer kostenlos oder performant. Denn selbst wenn du 50 Datenbankserver hast muss jedes UPDATE/INSERT/DELETE auf jeden Knoten im Cluster repliziert werden. Du sparst für diese Statements also nicht zwingend Last in deinem Cluster.
Kurz gesagt mag dir die komplett datenbankbasierte Lösung auf den ersten Blick charmant vorkommen da "es ja irgendwie funktionierende Clusterlösungen gibt". Wenn du dir die Lösungen aber im Detail ansiehst wirst du viele Probleme die Clustering verbunden mit Replikation mit sich bringen sehen. Denn die Lösungen funktionieren selten so reibungslos für alle Zwecke und ich nehme nicht an dass du ein "Full-Blown" Replikations-/Clusteringsystem für mehrere Tausend $ lizensieren willst.
Deiner letzten Idee nach willst du die Datei auf den Nodes im Frontendcluster cachen und alle x Sekunden/Minuten/Stunden aus der Datenbank aktualisieren. Nur: wozu brauchst du dann noch die Datenbank? Du kannst die Grafiken doch auch auf einem zentralen Server lagern und das Verzeichnis in dem die Grafiken lagern via SMB/NFS/Whatever in den einzelnen Nodes einbinden. Und wenn eine Grafik abgelaufen ist kopierst du sie einfach schnell von dem "Referenzverzeichnis" rüber. Kurz und Simpel und du missbrauchst eine Datenbank (die zufällig auch LOBs unterstützt) nicht für die Verteilung von Dateien ...
Todi42: die Nebenläufigkeit ist nicht immer ein Problem. Unter Linux ist es (je nach Dateisystem) möglich eine Datei zu löschen und neu anzulegen während ein anderer Prozess noch daraus liest. Der andere Prozess liest mit seinem Filehandle noch aus der (bereits gelöschten) Datei während jeder neue Prozess dann eben ein Filehandle auf die neue Datei aufmacht.
gepostet vor 17 Jahre, 10 Monate von HSINC
ich halte die lösung kleinere bilder fertig in der datenbank zu speichern gar nicht mal für so blöd.
begründung: solange man nur einen db server hat, sollte es performancemässig völlig egal sein ob die daten nun aus der db kommen und über das netz übertragen werden oder smb/nfs/whatever die übers netz überträgt.
die db sollte die daten schnell liefern und ein paar zusätzliche selects sind schlicht und ergreifend irrelevant (keys, richtige db konfig,etc vorrausgesetzt)
bei mehreren db servern/clustern hat man bei der db einen update zyklus pro cluster mehr, welcher beim filesystem nicht wäre. da muss man sehen wo dann der punkt erreicht ist, wo das fs signifikant schneller ist. allerdings glaube ich das das erst bei einer höheren anzahl von clustern passiert
persönlich muss ich sagen das man tendenziell mehr webserver haben wird als db server, aber das kommt auch sehr stark auf die programierung an und wohin man die logik verlagert. und das es hier wohl um ein problem geht das nie über 2 oder 3 db cluster hinausgehen wird, spricht somit eigentlich gar nix gegen das speichern von solchen daten in der datenbank (für das aktuell angebrachte problem).
und nein bis jetzt habe ich hier auch noch keine wirkliche begründung gelesen die ein kategorisches nein zum speichen von fertigen bilderdaten in der db rechtfertigen würde.
gepostet vor 17 Jahre, 10 Monate von None
Dann gehe ich es mal von der gemeinen Seite her an.
Datenweg rein:
Webserver->Script->Prüft->Wandelt um->Per Netz an Datenbank->Datenbank erhält und speichert.
Leichter Overhead, zumal das Netz benutzt wird um die Daten zu übertragen. Ich gehe mal davon aus das er einen Vertrag hat, wo er eine 2. Netzwerkkarte nutzen kann, welche (da interner Traffic) nicht zum normalen Trafficvolumen hinzugerechnet wird.
Datenweg raus:
Webserver->Script->Select->Per Netz an Datenbank->Datenbank ermittelt->Schickt an Webserver->Script->Bereitet Daten auf->Raus zum Client.
Und wieder Overhead.
gepostet vor 17 Jahre, 10 Monate von exe
Von der Funktionsweise unterscheiden sich die Datenbank und Dateisystem in dem Fall tatsächlich nicht wirklich.
Datenbank:
Anfrage => Schauen ob Datei noch aktuell ist => Wenn nicht aus der DB auffrischen => Ausliefern
Dateisystem:
Anfrage => Schauen ob die Datei noch aktuell ist => Wenn nicht aus dem SMB/NFS/Whatever auffrischen => Ausliefern
Deswegen frage ich mich eigentlich warum hier eine Datenbank benutzt werden soll? Von der Funktionsweise und der Komplexität gibt sich das nicht viel, Performance wird vermutlich auch erst bei einem größeren Setup (wovon man aber wiederrum auch ausgehen kann wenn hier von Frontendclustern geredet wird) eine Rolle.
Also wozu eine Datenbank hierfür benutzen? IMHO macht das hier weder Sinn noch bietet es einen Vorteil. Eine datenbanklose Lösung ist IMHO der natürliche Weg das Problem anzugehen - von dem her was hier bislang geschildert wurde.
gepostet vor 17 Jahre, 10 Monate von Amun Ra
So danke nochmal für die rege Beteiligung an diesem Thema.
Das hilft mir wirklich sehr bei meinen Überlegungen !
Irgendwo wurde schon mal kurz gefragt,
wo denn der Unterschied für die DB liegt ein 1 KB Text
oder 1 KB BLOB auszuliefern ??!
Das frag ich mich nämlich auch.
Ich will mal behaupten das bei jedem Hit auf Galaxy News
mehr Last auf die DB wirkt als bei mir,
rein vom Datenvolumen, Anzahl der Queries und Traffic gesehen.
Zur Erklärung:
Eine Komponente meines Projekts ist eine realistische Börse.
Das ganze würde natürlich auch komplett ohne die Bilder auskommen !
Die Bilder um die es mir geht, sind also absolut irrelevant
für die Applikation an sich, sondern nur was für die Optik.
Die Charts werden momentan in einem Intervall
von 60 Sekunden aktualisiert und sind am Ende des
Tages voll gezeichnet nur knappe 2 - 3 KB groß.
Deswegen frage ich mich halt, ob es Sinn macht sich
beispielsweise in rsync einzulesen und dieser extra Applikation
auch noch eine extra Maschine zu spendieren
und noch einen weiteren point of failure in die Applikation zu holen.
Für 100 Dateien und 200 - 300 KB Speicherverbrauch ??
Ich mein bei Applikationen wie Flickr ist das schon klar,
das die Bilder nicht in die DB gehören !
Deshalb meine Suche nach einer Lösung mit der ich jetzt auf
einer Box auskomme und später einfach horizontal skalieren kann.
Ohne Rearchitektur der Applikation, einfach durch
Implemtieren von Replikation und Partitionierung
und zuschalten neuer Hardware.
Oder falls alle Stricke reissen, durch Implementieren
eines MySQL Clusters.
gepostet vor 17 Jahre, 10 Monate von exe
Original von Amun Ra
Irgendwo wurde schon mal kurz gefragt,
wo denn der Unterschied für die DB liegt ein 1 KB Text
oder 1 KB BLOB auszuliefern ??!

Nirgends. Der Unterschied liegt erst zwischen "kein SELECT und auch nichts ausliefern" und "ein SELECT und irgendwas ausliefern". Bei ein paar kleinen Bildchen ist das vernachlässigbar. Wenn du aber tatsächlich alle Daten die irgendwie zwischen Rechnern geteilt werden über die Datenbank verteilst vielleicht nicht mehr. Hängt davon ab was du sonst noch so treibst
Deswegen frage ich mich halt, ob es Sinn macht sich

beispielsweise in rsync einzulesen und dieser extra Applikation
auch noch eine extra Maschine zu spendieren
und noch einen weiteren point of failure in die Applikation zu holen.
Für 100 Dateien und 200 - 300 KB Speicherverbrauch ??
Von rsync redet auch keiner, und von einem eigenen Server um 100 Bildchen auszuliefern schon gar nicht.
Deshalb meine Suche nach einer Lösung mit der ich jetzt auf

einer Box auskomme und später einfach horizontal skalieren kann.
Ohne Rearchitektur der Applikation, einfach durch
Implemtieren von Repliaktion und Partitionierung
und zuschalten neuer Hardware.
Oder falls alle Stricke reissen, durch Implementieren
eines MySQL Clusters.
Wo hast du nur die ganzen Begriffe her mit denen du daum dich schmeisst? DasAine hat mit dem Anderen nicht unbedingt was zu tun ...
Replikation hängt schon mit Clustering zusammen. Entweder du replizierst deine Datenbank um einen zweiten Datenbankserver als Failover auf dem gleichen Datenstand wie die benutzte Datenbank zu halten oder du replizierst weil du einen Cluster mit X Datenbankservern hast die alle auf dem gleichen Datenstand sein müssen.
Partitionierung im Zusammenhang mit Datenbanken heisst erstmal eine Tabelle physikalisch in verschiedene Teile aufzuteilen. Unter Umständen auch in verschiedene Tabelspaces, also auch unterschiedliche physikalische Laufwerke. Damit erreichst du unter Umständen tatsächlich einen höheren Datendurchsatz, bei ein paar kleinen Bildchen bringt dir das aber nicht wirklich was 150mB Disc IO während nur ein paar 2-3 kB große Bildchen gelesen werden - naja, nicht sehr sinnig.
Zuschalten neuer Hardware - was soll das bedeuten? Ein paar neue Festplatten und RAM reinstecken und der Server läuft gleich 5 mal so schnell? So einfach ist das dann auch wieder nicht ...
Und vorallem Clustering: ich glaube du stellst dir das zu einfach vor. Denkst du du setzt einfach "use_cluster = yes" in der Datenbankkonfiguration und hast ohne weitere Zicken ein skalierendes System wo du nur in regelmäßigen Abständen einen neuen Server reinstöppselst? Auch das ist etwas zu einfach vorgestellt.
Also ich würde dir empfehlen dir nicht die Haare auszureissen nur weil du ein paar Bildchen ausliefern willst. Schreib dir halt eine Funktion names "getImage" die das Bild zurückliefert. Die kann dann am Anfang einfach die Datei vom Dateisystem lesen. Und wenn du in ein paar Jahren dann das Killerspiel mit 50.000 Request/Sekunde und einen Datenbank- und Frontendcluster der eBay vor Neid erblassen lässt hast, dann kannst du immernoch darüber nachdenken, ob du in dieser Funktion statt
fpassthru(fopen($filename));

nicht doch lieber
$row = mysql_fetch_assoc(mysql_query("SELECT data FROM images WHERE name = '$filename'"));

echo $row['data'];
schreibst...
gepostet vor 17 Jahre, 10 Monate von None
Da es dir scheinbar NUR um die Darstellung geht... ei schick halt dem Client die Rohdaten und lass sie per JavaScript, Java-Applet, Flash oder SVG anzeigen.
Aber die Diskussion zeigt mir, daß du und einige andere sich hier wirklich Gedanken machen und nicht einfach immer alles so hinnehmen wie es gesagt wird.

Auf diese Diskussion antworten