Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.comp.lang.php > #4132 > unrolled thread
| Started by | Michael Vogel <ike@spamfence.net> |
|---|---|
| First post | 2017-06-24 07:37 +0200 |
| Last post | 2017-07-20 14:14 +0200 |
| Articles | 11 — 5 participants |
Back to article view | Back to de.comp.lang.php
Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Michael Vogel <ike@spamfence.net> - 2017-06-24 07:37 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Markus Grob <snoopy@ilnet.ch> - 2017-06-24 15:58 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Michael Vogel <ike@spamfence.de> - 2017-06-27 16:06 +0000
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) "Peter J. Holzer" <hjp-usenet3@hjp.at> - 2017-06-24 20:50 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Michael Vogel <ike@spamfence.de> - 2017-06-27 16:17 +0000
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) "Peter J. Holzer" <hjp-usenet3@hjp.at> - 2017-06-28 11:30 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Michael Vogel <ike@spamfence.net> - 2017-06-30 06:56 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) "Peter J. Holzer" <hjp-usenet3@hjp.at> - 2017-06-30 16:02 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Markus Grob <snoopy@ilnet.ch> - 2017-07-19 13:07 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) Claus Reibenstein <4spamersonly@kabelmail.de> - 2017-07-19 16:44 +0200
Re: Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) "Peter J. Holzer" <hjp-usenet3@hjp.at> - 2017-07-20 14:14 +0200
| From | Michael Vogel <ike@spamfence.net> |
|---|---|
| Date | 2017-06-24 07:37 +0200 |
| Subject | Ersatz für SQL bei Prozessverwaltung gesucht (Viele zeitgleiche Schreibzugriffe) |
| Message-ID | <1498282631.618627@alpaka.in-berlin.de> |
Moin! Die Software an der ich schreibe, enthält auch einen Scheduler der Hintergrundjobs auf eine Anzahl von sogenannten Workern verteilt. Genau läuft es so ab, dass jeder Worker schaut, was ganz oben auf der Liste ist, dann wird dort notiert, dass der Worker dran ist - und nachdem der Auftrag erledigt ist, wird er als "erledigt" gekennzeichnet. Derzeit geschieht die Ablage der Jobs in einer MySQL-Tabelle. Das Problem ist nun, dass die vielen parallelen Schreibzugriffe dazu führen, dass mit steigender Anzahl der Worker immer mehr davon unproduktiv auf neue Jobs warten, weil sie sich beim Schreibzugriff gegenseitig sperren. Die Frage ist nun, welche Alternativen zu SQL existieren. Womit habt Ihr Erfahrung? Ich weiß, dass es Prozessverwaltungen gibt, die das Ganze im Hauptspeicher erledigen und regelmäßig den Stand zurückschreiben. Das ist mir aber nicht robust genug. Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien pro Tag angelegt und gelöscht werden. Wie gut ist "Berkeley DB" dafür geeignet? Siehe http://php.net/manual/de/intro.dba.php Wie gut ist SQLite in solchen Fällen? Was gibt es sonst noch für Möglichkeiten? Michael
[toc] | [next] | [standalone]
| From | Markus Grob <snoopy@ilnet.ch> |
|---|---|
| Date | 2017-06-24 15:58 +0200 |
| Message-ID | <oilquf$t29$1@dont-email.me> |
| In reply to | #4132 |
Michael Vogel schrieb: > Derzeit geschieht die Ablage der Jobs in einer MySQL-Tabelle. > > Das Problem ist nun, dass die vielen parallelen Schreibzugriffe dazu > führen, dass mit steigender Anzahl der Worker immer mehr davon > unproduktiv auf neue Jobs warten, weil sie sich beim Schreibzugriff > gegenseitig sperren. Dann liegt es nicht am MySQL sondern an der Programmierung. Wenn ein Zugriff eine Tabelle exklusiv beansprucht, dann kann kein anderer darauf zugreifen, da sonst die Integrität gefährdet ist. Wenn Du etwa einen Wert schreibst, während ein anderer Thread das Gleiche will. Entweder brauchst Du nun einen Buffer, welcher die Daten serialisiert abarbeitet oder Du verwendest mehrere Tabellen. > Erfahrung? Ich weiß, dass es Prozessverwaltungen gibt, die das Ganze im > Hauptspeicher erledigen und regelmäßig den Stand zurückschreiben. Das > ist mir aber nicht robust genug. Natürlich muss es nicht im Speicher bleiben, doch Schreibcache ist seit Jahren möglich. > Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem > Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit > schon 100.000 bis 200.000 Jobs pro Tag. Das ist für MySQL ein lächerlicher Betrag und zeigt, dass der Engpass nicht am System, sondern am Zugriff liegt. > Die Frage ist also, wie gut ein > Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien > pro Tag angelegt und gelöscht werden. Solange das System so viele Dateien pro Verzeichnis zulässt, kein Problem, obwohl ich hier pro Worker ein eigenes Unterverzeichnis erstellen würde. Du könntest dann einen Worker nehmen, der alle Dateien, welche als erledigt gekennzeichnet sind ausliest und in die Tabelle schreibt und anschliessend die Datei löscht. So hast Du einen Puffer und danach alles in der DB. Bei einem Problem sind aber noch alle Daten als Dateien da. > Wie gut ist "Berkeley DB" dafür geeignet? Siehe > http://php.net/manual/de/intro.dba.php Ähnlich wie MySQL. Gruss, Markus
[toc] | [prev] | [next] | [standalone]
| From | Michael Vogel <ike@spamfence.de> |
|---|---|
| Date | 2017-06-27 16:06 +0000 |
| Message-ID | <1498579369.430766@alpaka.in-berlin.de> |
| In reply to | #4133 |
Markus Grob wrote: > Michael Vogel schrieb: > >> Derzeit geschieht die Ablage der Jobs in einer MySQL-Tabelle. >> >> Das Problem ist nun, dass die vielen parallelen Schreibzugriffe dazu >> führen, dass mit steigender Anzahl der Worker immer mehr davon >> unproduktiv auf neue Jobs warten, weil sie sich beim Schreibzugriff >> gegenseitig sperren. > > Dann liegt es nicht am MySQL sondern an der Programmierung. Wenn ein > Zugriff eine Tabelle exklusiv beansprucht, dann kann kein anderer darauf > zugreifen, da sonst die Integrität gefährdet ist. Ja, es ist ja auch nicht so, dass hier zwei Prozesse zeitgleich schreiben würden. Es ist nur so, dass wenn viele Prozesse zeitgleich schreiben wollen, sie natürlich darauf warten müssen, dass die Sperre aufgehoben wird - und dann auf einmal Wartezeiten zweistelligen Sekundenbereich auftreten. > Natürlich muss es nicht im Speicher bleiben, doch Schreibcache ist seit > Jahren möglich. Schreibcache gefällt mir nicht, da die Konsistenz nicht sichergestellt ist. >> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem >> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit >> schon 100.000 bis 200.000 Jobs pro Tag. > > Das ist für MySQL ein lächerlicher Betrag und zeigt, dass der Engpass > nicht am System, sondern am Zugriff liegt. Auf diesem Server läuft mehr als ein System und es läuft per Standard mit einer Load von 5-8. Das I/O ist der absolute Flaschenhals. Das ist aber für das Entwickeln gar nicht mal so schlecht, da ich hier sehr gut feststelle, was wirklich Peformance bringt. > Du könntest dann einen Worker nehmen, der alle Dateien, welche als > erledigt gekennzeichnet sind ausliest und in die Tabelle schreibt und > anschliessend die Datei löscht. So hast Du einen Puffer und danach alles > in der DB. Bei einem Problem sind aber noch alle Daten als Dateien da. Ich war auch schon am Überlegen, pro Worker eine eigene Tabelle (z.B. als Berkeley DB) anzulegen und einen Scheduler zu haben, der diese Tabellen befüllt. Das würde weitgehend vermeiden, dass sich Prozesse gegenseitig sperren. >> Wie gut ist "Berkeley DB" dafür geeignet? Siehe >> http://php.net/manual/de/intro.dba.php > > Ähnlich wie MySQL. Arbeitet das auch mit Sperren? Michael
[toc] | [prev] | [next] | [standalone]
| From | "Peter J. Holzer" <hjp-usenet3@hjp.at> |
|---|---|
| Date | 2017-06-24 20:50 +0200 |
| Message-ID | <slrnoktd45.uh7.hjp-usenet3@hrunkner.hjp.at> |
| In reply to | #4132 |
On 2017-06-24 05:37, Michael Vogel <ike@spamfence.net> wrote:
> Die Software an der ich schreibe, enthält auch einen Scheduler der
> Hintergrundjobs auf eine Anzahl von sogenannten Workern verteilt.
>
> Genau läuft es so ab, dass jeder Worker schaut, was ganz oben auf der
> Liste ist, dann wird dort notiert, dass der Worker dran ist - und
> nachdem der Auftrag erledigt ist, wird er als "erledigt" gekennzeichnet.
>
> Derzeit geschieht die Ablage der Jobs in einer MySQL-Tabelle.
>
> Das Problem ist nun, dass die vielen parallelen Schreibzugriffe dazu
> führen, dass mit steigender Anzahl der Worker immer mehr davon
> unproduktiv auf neue Jobs warten, weil sie sich beim Schreibzugriff
> gegenseitig sperren.
Hast Du Messwerte, die das belegen? Das scheint mir bei der eher
geringen Zahl von Operationen (200000 Jobs pro Tag sind weniger als 3
pro Sekunde: Da ein Job-Eintrag schlimmstenfalls 3 mal geschrieben
werden muss (wenn er angelegt wird, wenn er einem Worker zugewiesen wird
und wenn er fertig ist), sind das also unter 9 Schreibzugriffe pro
Sekunde. Und die meisten davon sollten sich gegenseitig nicht
beeinflussen.
Ich habe einen kleinen Benchmark geschrieben (in Perl, also hier
off-topic) und bei 3 Producern (die jeweils durchschnittlich 2 Jobs pro
Sekunde einwerfen) und 20 Workern (die jeweils durchschnittlich 2.5
Sekunden zum "Abarbeiten" eines Jobs brauchen), waren 90% der Locks
kürzer als 83 Millisekunden, 90% der Queue-Zeiten unter 276
Millisekunden. Der Durchsatz ist nicht ganz 3 mal so hoch wie mit einem
Producer, kann also sein, dass man hier schön langsam in die Sättigung
kommt (die MySQL-Db liegt auf einer Consumer-Festplatte). Müsste man mal
mit wachsender Anzahl Producer und Worker laufen lassen und schauen, was
dabei rauskommt.
> Die Frage ist nun, welche Alternativen zu SQL existieren. Womit habt Ihr
> Erfahrung? Ich weiß, dass es Prozessverwaltungen gibt, die das Ganze im
> Hauptspeicher erledigen und regelmäßig den Stand zurückschreiben. Das
> ist mir aber nicht robust genug.
>
> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem
> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit
> schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein
> Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien
> pro Tag angelegt und gelöscht werden.
Damit sollten so ziemlich alle Filesysteme auf halbwegs aktueller
Hardware zurechtkommen. Sind ja nur eine Handvoll Operationen pro
Sekunde. Wenn Du allerdings wirklich absturzsicher sein willst, musst Du
bei modernen Filesystemen (zumindest unter Linux) einen ziemlichen
Aufwand treiben. Einen Performance-Vorteil gegenüber einer Datenbank
hast Du damit vermutlich nicht (ich habe es allerdings nicht gemessen).
> Wie gut ist "Berkeley DB" dafür geeignet? Siehe
> http://php.net/manual/de/intro.dba.php
BDB war einmal eine der MySQL-Engines. Wurde zugunsten von InnoDB
entfernt (hatte WIMRE auch Lizenzgründe). Seitdem wurde es offenbar
recht kräftig weiterentwickelt, ich kann also zum aktuellen Status
nichts sagen. Bauchgefühl sagt: Wird wohl nicht viel anders als InnoDB
sein.
> Wie gut ist SQLite in solchen Fällen?
Schrecklich. SQLite sperrt bei Schreibzugriffen die ganze Datenbank. Das
ist völlig ungeeignet, wenn mehrere Prozesse darauf zugreifen wollen. Es
ist nett, wenn man einen einzelnen Prozess hat, der Daten in
strukturierter Form speichern will, aber für alles andere nimmt man
besser ein richtiges RDBMS (oder eben keine relationale Datenbank
sondern was anderes). Mittlerweile würde ich selbst im Fall von kleinen
Standalone-Applikationen eher PostgreSQL verwenden - ist am Anfang mehr
Aufwand, aber ich erspare mir das Umschreiben, wenn ich später
draufkomme, dass SQLite doch nicht reicht (was irgendwie meistens der
Fall ist).
>
> Was gibt es sonst noch für Möglichkeiten?
Ich nehme an,
https://en.wikipedia.org/wiki/Message_broker
hast Du Dir schon angeschaut. Ich kann leider keine Empfehlung abgeben,
weil ich entweder Datenbanktabellen verwendet habe, wenn ich Persistenz
wollte, oder RPCs programmiert habe, wenn das nicht der Fall war.
hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | hjp@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
[toc] | [prev] | [next] | [standalone]
| From | Michael Vogel <ike@spamfence.de> |
|---|---|
| Date | 2017-06-27 16:17 +0000 |
| Message-ID | <1498580009.540185@alpaka.in-berlin.de> |
| In reply to | #4135 |
Peter J. Holzer wrote: > On 2017-06-24 05:37, Michael Vogel <ike@spamfence.net> wrote: >> Das Problem ist nun, dass die vielen parallelen Schreibzugriffe dazu >> führen, dass mit steigender Anzahl der Worker immer mehr davon >> unproduktiv auf neue Jobs warten, weil sie sich beim Schreibzugriff >> gegenseitig sperren. > > Hast Du Messwerte, die das belegen? Jepp. Das habe ich alles ausgetestet. Das System ist an sich überlastet, deswegen wirken sich kleine Änderungen massiv aus. > Ich habe einen kleinen Benchmark geschrieben (in Perl, also hier > off-topic) und bei 3 Producern (die jeweils durchschnittlich 2 Jobs pro > Sekunde einwerfen) und 20 Workern (die jeweils durchschnittlich 2.5 > Sekunden zum "Abarbeiten" eines Jobs brauchen), waren 90% der Locks > kürzer als 83 Millisekunden, 90% der Queue-Zeiten unter 276 > Millisekunden. Ein einfaches Update dauert bei dem System auf dieser Tabelle etwa 200 bis 400 Millisekunden - und wenn das System extrem ausgelastet ist, geht das durch die Sperren teilweise auf 10 Sekunden hoch. > Der Durchsatz ist nicht ganz 3 mal so hoch wie mit einem > Producer, kann also sein, dass man hier schön langsam in die Sättigung > kommt (die MySQL-Db liegt auf einer Consumer-Festplatte). Müsste man mal > mit wachsender Anzahl Producer und Worker laufen lassen und schauen, was > dabei rauskommt. Mein Server liegt auf einem Server, der eindeutig im I/O-Bereich überlastet ist. Die Ursache liegt dabei nicht an einer Fehlkonfiguration des Servers, sondern an den Prozessen. Es laufen dort vier soziale Netzwerke parallel. >> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem >> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit >> schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein >> Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien >> pro Tag angelegt und gelöscht werden. > > Damit sollten so ziemlich alle Filesysteme auf halbwegs aktueller > Hardware zurechtkommen. Sind ja nur eine Handvoll Operationen pro > Sekunde. Wenn Du allerdings wirklich absturzsicher sein willst, musst Du > bei modernen Filesystemen (zumindest unter Linux) einen ziemlichen > Aufwand treiben. Einen Performance-Vorteil gegenüber einer Datenbank > hast Du damit vermutlich nicht (ich habe es allerdings nicht gemessen). Ich frage mich halt, wie gut es ist, Tausende von Dateien in einem Ordner anzulegen und zu löschen. Zumindest früher führte das gerne zu Problemen mit den Dateisystemen. >> Wie gut ist "Berkeley DB" dafür geeignet? Siehe >> http://php.net/manual/de/intro.dba.php > > BDB war einmal eine der MySQL-Engines. Wurde zugunsten von InnoDB > entfernt (hatte WIMRE auch Lizenzgründe). Seitdem wurde es offenbar > recht kräftig weiterentwickelt, ich kann also zum aktuellen Status > nichts sagen. Bauchgefühl sagt: Wird wohl nicht viel anders als InnoDB > sein. Sperren gehen auch? >> Wie gut ist SQLite in solchen Fällen? > > Schrecklich. SQLite sperrt bei Schreibzugriffen die ganze Datenbank. Das > ist völlig ungeeignet, wenn mehrere Prozesse darauf zugreifen wollen. Ah, okay. >> Was gibt es sonst noch für Möglichkeiten? > > Ich nehme an, > https://en.wikipedia.org/wiki/Message_broker > hast Du Dir schon angeschaut. Ich kann leider keine Empfehlung abgeben, > weil ich entweder Datenbanktabellen verwendet habe, wenn ich Persistenz > wollte, oder RPCs programmiert habe, wenn das nicht der Fall war. Mir het jemand jetzt auch SHM empfohlen. ggf. kann ich auch was mit Semaphoren machen, das bin ich gerade am Planen. Michael
[toc] | [prev] | [next] | [standalone]
| From | "Peter J. Holzer" <hjp-usenet3@hjp.at> |
|---|---|
| Date | 2017-06-28 11:30 +0200 |
| Message-ID | <slrnol6tor.6c9.hjp-usenet3@hrunkner.hjp.at> |
| In reply to | #4141 |
On 2017-06-27 16:17, Michael Vogel <ike@spamfence.de> wrote:
> Peter J. Holzer wrote:
>> Ich habe einen kleinen Benchmark geschrieben (in Perl, also hier
>> off-topic) und bei 3 Producern (die jeweils durchschnittlich 2 Jobs pro
>> Sekunde einwerfen) und 20 Workern (die jeweils durchschnittlich 2.5
>> Sekunden zum "Abarbeiten" eines Jobs brauchen), waren 90% der Locks
>> kürzer als 83 Millisekunden, 90% der Queue-Zeiten unter 276
>> Millisekunden.
>
> Ein einfaches Update dauert bei dem System auf dieser Tabelle etwa 200
> bis 400 Millisekunden - und wenn das System extrem ausgelastet ist, geht
> das durch die Sperren teilweise auf 10 Sekunden hoch.
>
>> Der Durchsatz ist nicht ganz 3 mal so hoch wie mit einem
>> Producer, kann also sein, dass man hier schön langsam in die Sättigung
>> kommt (die MySQL-Db liegt auf einer Consumer-Festplatte). Müsste man mal
>> mit wachsender Anzahl Producer und Worker laufen lassen und schauen, was
>> dabei rauskommt.
>
> Mein Server liegt auf einem Server, der eindeutig im I/O-Bereich
> überlastet ist. Die Ursache liegt dabei nicht an einer Fehlkonfiguration
> des Servers, sondern an den Prozessen. Es laufen dort vier soziale
> Netzwerke parallel.
Einen Server, die "eindeutig im I/O-Bereich überlastet" ist, würde ich
als Systemadministrator schon als "Fehlkonfiguration" bezeichnen. Kann
natürlich sein, dass man wenig dagegen tun kann, weil das Budget knapp
ist. Aber Arbeitszeit ist auch nicht gratis - auch nicht bei einem
Freizeitprojekt.
>>> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem
>>> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit
>>> schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein
>>> Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien
>>> pro Tag angelegt und gelöscht werden.
>>
>> Damit sollten so ziemlich alle Filesysteme auf halbwegs aktueller
>> Hardware zurechtkommen. Sind ja nur eine Handvoll Operationen pro
>> Sekunde. Wenn Du allerdings wirklich absturzsicher sein willst, musst Du
>> bei modernen Filesystemen (zumindest unter Linux) einen ziemlichen
>> Aufwand treiben. Einen Performance-Vorteil gegenüber einer Datenbank
>> hast Du damit vermutlich nicht (ich habe es allerdings nicht gemessen).
>
> Ich frage mich halt, wie gut es ist, Tausende von Dateien in einem
> Ordner anzulegen und zu löschen. Zumindest früher führte das gerne zu
> Problemen mit den Dateisystemen.
Früher hatten Dateisystme hauptsächlich Probleme mit vielen
*gleichzeitig* existierenden Files in einem Directory. Aber das hast Du
bei einem Queue-System nicht - Deine Jobs bleiben hoffentlich nicht
stundenlang in der Queue. Bei manchen Systemen waren außerdem
Directory-Operationen synchron: Da konnte das Anlegen oder Löschen eines
Files schon mal 100 ms oder so dauern. Aber beides sollte auf einem
Filesystem aus diesem Jahrtausend nicht mehr der Fall sein.
Trotzdem: Ich würde nicht damit rechnen, dass das wesentlich schneller
ist als in einer Datenbank.
>>> Wie gut ist "Berkeley DB" dafür geeignet? Siehe
>>> http://php.net/manual/de/intro.dba.php
>>
>> BDB war einmal eine der MySQL-Engines. Wurde zugunsten von InnoDB
>> entfernt (hatte WIMRE auch Lizenzgründe). Seitdem wurde es offenbar
>> recht kräftig weiterentwickelt, ich kann also zum aktuellen Status
>> nichts sagen. Bauchgefühl sagt: Wird wohl nicht viel anders als InnoDB
>> sein.
>
> Sperren gehen auch?
Eigentlich willst Du da keine Sperren, Die sind eher eine unerwünschte
Nebenwirkung.
Ansonsten wiederhole ich: "Ich kann zum aktuellen Status von BDB nichts
sagen."
PostgreSQL kennt "select for update ... skip locked", das für Job-Queues
und ähnliche Anwendungen ideal sein sollte. Schon vorher wurden damit
recht ansehnliche Durchsatzzahlen erreicht:
https://gist.github.com/chanks/7585810
>> Ich nehme an,
>> https://en.wikipedia.org/wiki/Message_broker
>> hast Du Dir schon angeschaut. Ich kann leider keine Empfehlung abgeben,
>> weil ich entweder Datenbanktabellen verwendet habe, wenn ich Persistenz
>> wollte, oder RPCs programmiert habe, wenn das nicht der Fall war.
>
> Mir het jemand jetzt auch SHM empfohlen. ggf. kann ich auch was mit
> Semaphoren machen, das bin ich gerade am Planen.
Hattest Du nicht geschrieben, dass Lösungen, die nur im RAM arbeiten,
für Dich nicht in Frage kommen?
hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | hjp@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
[toc] | [prev] | [next] | [standalone]
| From | Michael Vogel <ike@spamfence.net> |
|---|---|
| Date | 2017-06-30 06:56 +0200 |
| Message-ID | <1498798586.181883@alpaka.in-berlin.de> |
| In reply to | #4142 |
Am 28.06.2017 um 11:30 schrieb Peter J. Holzer: > On 2017-06-27 16:17, Michael Vogel <ike@spamfence.de> wrote: >> Mein Server liegt auf einem Server, der eindeutig im I/O-Bereich >> überlastet ist. Die Ursache liegt dabei nicht an einer Fehlkonfiguration >> des Servers, sondern an den Prozessen. Es laufen dort vier soziale >> Netzwerke parallel. > > Einen Server, die "eindeutig im I/O-Bereich überlastet" ist, würde ich > als Systemadministrator schon als "Fehlkonfiguration" bezeichnen. Kann > natürlich sein, dass man wenig dagegen tun kann, weil das Budget knapp > ist. Aber Arbeitszeit ist auch nicht gratis - auch nicht bei einem > Freizeitprojekt. Ich bin nur "Freizeitadmin", aber nach allem, was ich zum Server sagen kann, ist er nicht fehlkonfiguriert, sondern einfach nur überlastet. Ich könnte mir natürlich einen (noch) größeren Server besorgen. Allerdings läuft die Software an der ich arbeite ja nicht nur auf meinem Rechner, sondern noch auf hunderten anderer Systeme. Dadurch, dass mein System relativ langsam ist, kann ich viel besser erkennen, welche Programmierungen welche Auswirkungen in Bezug auf Performance haben. Das sehe ich als Vorteil. >> Ich frage mich halt, wie gut es ist, Tausende von Dateien in einem >> Ordner anzulegen und zu löschen. Zumindest früher führte das gerne zu >> Problemen mit den Dateisystemen. (...) > Trotzdem: Ich würde nicht damit rechnen, dass das wesentlich schneller > ist als in einer Datenbank. Ja, wahrscheinlich. >>>> Wie gut ist "Berkeley DB" dafür geeignet? Siehe >>>> http://php.net/manual/de/intro.dba.php >>> >>> BDB war einmal eine der MySQL-Engines. Wurde zugunsten von InnoDB >>> entfernt (hatte WIMRE auch Lizenzgründe). Seitdem wurde es offenbar >>> recht kräftig weiterentwickelt, ich kann also zum aktuellen Status >>> nichts sagen. Bauchgefühl sagt: Wird wohl nicht viel anders als InnoDB >>> sein. >> >> Sperren gehen auch? > > Eigentlich willst Du da keine Sperren, Die sind eher eine unerwünschte > Nebenwirkung. Wenn ein Worker gerade die Queue abarbeitet, während der Scheduler die Queue auffüllt, muss das ja schon irgendwie synchronisiert werden, damit kein Chaos entsteht. > Ansonsten wiederhole ich: "Ich kann zum aktuellen Status von BDB nichts > sagen." Ja, okay. > PostgreSQL kennt "select for update ... skip locked", das für Job-Queues > und ähnliche Anwendungen ideal sein sollte. Schon vorher wurden damit > recht ansehnliche Durchsatzzahlen erreicht: > https://gist.github.com/chanks/7585810 Es ist auf alle Fälle bei uns auf dem Plan, dass wir auch Postgres unterstützen, aber soweit sind wir noch nicht - und vor allem können wir es unseren Usern nicht vorschreiben. Da gab es ja sogar schon vereinzelt Proteste, da wir die Leute endlich dazu bringen wollen, von MyISAM wegzukommen. >>> Ich nehme an, >>> https://en.wikipedia.org/wiki/Message_broker >>> hast Du Dir schon angeschaut. Ich kann leider keine Empfehlung abgeben, >>> weil ich entweder Datenbanktabellen verwendet habe, wenn ich Persistenz >>> wollte, oder RPCs programmiert habe, wenn das nicht der Fall war. >> >> Mir het jemand jetzt auch SHM empfohlen. ggf. kann ich auch was mit >> Semaphoren machen, das bin ich gerade am Planen. > > Hattest Du nicht geschrieben, dass Lösungen, die nur im RAM arbeiten, > für Dich nicht in Frage kommen? Semaphoren und SHM dienen ja nur der Kommunikation und Koordination der Prozesse. Mir geht es darum, dass ich vermeiden möchte, dass Jobs gar nicht oder mehrfach ausgeführt werden, weil Schreiboperationen im Speicher gehalten werden und nur gelegentlich weggeschrieben werden. Michael
[toc] | [prev] | [next] | [standalone]
| From | "Peter J. Holzer" <hjp-usenet3@hjp.at> |
|---|---|
| Date | 2017-06-30 16:02 +0200 |
| Message-ID | <slrnolcmfq.tuh.hjp-usenet3@hrunkner.hjp.at> |
| In reply to | #4145 |
[Ich lenke mal auf de.comp.datenbanken.misc um - mit PHP hat das gar
nichts mehr zu tun]
On 2017-06-30 04:56, Michael Vogel <ike@spamfence.net> wrote:
> Am 28.06.2017 um 11:30 schrieb Peter J. Holzer:
>> On 2017-06-27 16:17, Michael Vogel <ike@spamfence.de> wrote:
>>> Mein Server liegt auf einem Server, der eindeutig im I/O-Bereich
>>> überlastet ist. Die Ursache liegt dabei nicht an einer Fehlkonfiguration
>>> des Servers, sondern an den Prozessen. Es laufen dort vier soziale
>>> Netzwerke parallel.
>>
>> Einen Server, die "eindeutig im I/O-Bereich überlastet" ist, würde ich
>> als Systemadministrator schon als "Fehlkonfiguration" bezeichnen. Kann
>> natürlich sein, dass man wenig dagegen tun kann, weil das Budget knapp
>> ist. Aber Arbeitszeit ist auch nicht gratis - auch nicht bei einem
>> Freizeitprojekt.
>
> Ich bin nur "Freizeitadmin", aber nach allem, was ich zum Server sagen
> kann, ist er nicht fehlkonfiguriert, sondern einfach nur überlastet.
Wenn Du (z.B.) 4 Services, die jeweils 100 Requests pro Sekunde
bearbeiten sollen, auf einem Host installierst, der nur 300 Requests
pro Sekunde schafft, dann ist das für mich eine Fehlkonfiguration.
Konfigurationsänderungen, die das Problem beheben könnten, wären z.B.:
* Verlagern mindestens eines der Services auf einen anderen Host
* Ausbau des vorhandenen Hosts (zusätzliche und/oder schnellere Disks,
mehr RAM, ...), damit er mehr Requests pro Sekunde abarbeiten kann.
* Reorganisation der Disks: Anderes RAID-Level, bestimmte "heiße"
Tabellen besser verteilen, ...
Die Konfiguration eines Systems besteht nicht nur aus Config-Files.
> Ich könnte mir natürlich einen (noch) größeren Server besorgen.
> Allerdings läuft die Software an der ich arbeite ja nicht nur auf
> meinem Rechner, sondern noch auf hunderten anderer Systeme. Dadurch,
> dass mein System relativ langsam ist, kann ich viel besser erkennen,
> welche Programmierungen welche Auswirkungen in Bezug auf Performance
> haben. Das sehe ich als Vorteil.
Ob Deine User das auch so sehen? Aber egal. Das ist Deine Entscheidung.
>>>>> Wie gut ist "Berkeley DB" dafür geeignet? Siehe
>>>>> http://php.net/manual/de/intro.dba.php
>>>>
>>>> BDB war einmal eine der MySQL-Engines. Wurde zugunsten von InnoDB
>>>> entfernt (hatte WIMRE auch Lizenzgründe). Seitdem wurde es offenbar
>>>> recht kräftig weiterentwickelt, ich kann also zum aktuellen Status
>>>> nichts sagen. Bauchgefühl sagt: Wird wohl nicht viel anders als InnoDB
>>>> sein.
>>>
>>> Sperren gehen auch?
>>
>> Eigentlich willst Du da keine Sperren, Die sind eher eine unerwünschte
>> Nebenwirkung.
>
> Wenn ein Worker gerade die Queue abarbeitet, während der Scheduler die
> Queue auffüllt, muss das ja schon irgendwie synchronisiert werden, damit
> kein Chaos entsteht.
Richtig. Du willst, dass das "irgendwie synchronisiert" wird. Locks sind
eine Methode zur Synchronisation. Du schließt daraus, dass Du Locks
willst. Das ist aber ein Fehlschluss. Locks sind nicht das Ziel, sondern
ein Weg zum Ziel. Wenn Du das Ziel auf anderem Weg erreichen kannst, ist
das genauso gut und vielleicht sogar besser.
Konkret hast Du das Problem, dass Deine Locks entweder zu lange dauern
oder zu viel locken. Prozesse warten daher darauf, dass ein anderer
Prozess endlich einen Lock freigibt, statt sinnvolle Arbeit zu
verrichten. So habe ich Deine Beschreibung zumindest verstanden (wobei
das ein bisschen im Widerspruch zur Beobachtung steht, dass das System
jetzt bereits überlastet ist - wenn die Prozesse weniger warten würden,
wäre das System ja noch stärker belastet).
Du willst also Locks möglichst minimieren. Idealerweise willst Du sie
ganz loswerden, das wirst Du allerdings mit einem RDBMS eher nicht
schaffen, weil jedes RDBMS intern Locks verwendet - allerdings
(hoffentlich) sehr viel feinere, als Du das als Applikations-
programmierer kannst.
Gehen wir mal ein paar Möglichkeiten durch:
1. Die Worst-Practice Methode:
Du hast eine Queue-Tabelle. Wenn ein Worker einen Job abarbeiten
will, sperrt er die ganze Tabelle, schaut nach, ob er einen Job
findet, wenn ja, arbeitet er ihn ab und löscht ihn aus der Tabelle.
Ganz zum Schluss gibt er die Tabelle wieder frei.
Das ist offensichtlich kompletter Unsinn: Es kann immer nur ein
Worker gleichzeitig arbeiten und man kann nicht einmal neue Jobs
einwerfen, solange ein Job arbeitet.
Das muss besser gehen.
2. select for update
Der obige Ansatz sperrt die Tabelle länger als notwendig (während
der Job abgearbeitet wird, muss sie nicht gesperrt sein) und er
sperrt mehr als notwendig (die ganze Tabelle, es müsste aber nur
eine Zeile gesperrt werden. Das lässt sich leicht verbessern:
Job holen:
select id, ...
from job_queue
where status = 'new'
limit 1
for update;
update job_queue set status = 'in progress' where id=...;
commit;
Job löschen:
delete from job_queue where id=...;
commit;
Damit ist der Lock sehr viel kürzer (er existiert nur mehr für die
Zeit zwischen select und update, und sehr viel feiner granuliert
(nur mehr eine Zeile).
Aber es gibt da immer noch ein Problem: Wenn zwei Worker
gleichzeitig einen neuen Job suchen, werden sie wahrscheinlich den
gleichen finden, und der zweite wird auf den ersten warten, nur um
festzustellen, dass die Zeile, die er gerade locken wollte, die
where-Klausel nicht mehr erfüllt.
3. select for update skip locked
PostgreSQL löst das Problem mit der Option skip locked. Der zweite
Worker wird in dem Fall einfach die bereits vom ersten gelockte
Zeile auslassen und die nächste Zeile, die die where-Klausel
erfüllt, sperren. Aus Sicht des Anwendungsprogrammiers ist das
Lock-Frei: Er wartet nie, sondern bekommt immer "sofort" eine
Antwort: Entweder einen Job oder eben keinen, wenn nichts zu tun
ist.
4. Andere Ansätze:
Das Hauptproblem bei Ansatz 2 ist, dass es zu deterministisch ist:
Alle Worker versuchen sich auf den gleichen Job zu stürzen, auch
wenn mehrere in der Queue sind. Das könnte man z.B. durch Zuordnung
zu verschiedenen Worker-Klassen (eventuell sogar in getrennten
Queue-Tabellen!), zufällige Sortierung, o.ä. umgehen.
Oder man könnte einen optimistischen Update machen:
update job_queue
set status='in progress', worker_id=...
where status = 'new'
limit 1;
commit;
select * from job_queue where worker_id=...;
Keine Garantie, dass das besser ist als select for update, aber es
ist einen Versuch wert.
>> PostgreSQL kennt "select for update ... skip locked", das für Job-Queues
>> und ähnliche Anwendungen ideal sein sollte. Schon vorher wurden damit
>> recht ansehnliche Durchsatzzahlen erreicht:
>> https://gist.github.com/chanks/7585810
>
> Es ist auf alle Fälle bei uns auf dem Plan, dass wir auch Postgres
> unterstützen, aber soweit sind wir noch nicht - und vor allem können wir
> es unseren Usern nicht vorschreiben.
Nein, aber "auch PostgreSQL unterstützen" heißt ja nicht, den Usern
vorzuschreiben, dass sie das nützen müssen. Und selbst wenn in der Doku
steht "für Sites mit vielen Benutzern empfehlen wir PostgreSQL", ist das
immer noch nur ein Rat und kein Zwang. Wenn Du ein komplett anderes
Datenbanksystem für die Queues verwendest (BDB oder Redis oder was auch
immer), dann ist das eher ein Zwang, denn das müssen die Leute dann
wahrscheinlich installieren, außer Du willst mehrere Varianten
unterstützen.
>>> Mir het jemand jetzt auch SHM empfohlen. ggf. kann ich auch was mit
>>> Semaphoren machen, das bin ich gerade am Planen.
>>
>> Hattest Du nicht geschrieben, dass Lösungen, die nur im RAM arbeiten,
>> für Dich nicht in Frage kommen?
>
> Semaphoren und SHM dienen ja nur der Kommunikation und Koordination der
> Prozesse.
Probieren kann man viel, aber ich sehe keinen Grund zur Annahme, dass
es besser ist, wenn Du in der Applikation noch einen zweiten
Synchronisationslayer um den bereits in der Datenbank existierenden
herumbaust, wenn Du dann die Daten doch in der Datenbank speicherst.
Sieht für mich nur nach zusätzlichem Overhead aus - inklusive der Gefahr
heftige Bugs einzubauen - das ist nämlich nicht trivial.
hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | hjp@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
[toc] | [prev] | [next] | [standalone]
| From | Markus Grob <snoopy@ilnet.ch> |
|---|---|
| Date | 2017-07-19 13:07 +0200 |
| Message-ID | <okneal$kg7$1@dont-email.me> |
| In reply to | #4135 |
Peter J. Holzer schrieb: > On 2017-06-24 05:37, Michael Vogel <ike@spamfence.net> wrote: >> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem >> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit >> schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein >> Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien >> pro Tag angelegt und gelöscht werden. > > Damit sollten so ziemlich alle Filesysteme auf halbwegs aktueller > Hardware zurechtkommen. Sind ja nur eine Handvoll Operationen pro > Sekunde. Wenn Du allerdings wirklich absturzsicher sein willst, musst Du > bei modernen Filesystemen (zumindest unter Linux) einen ziemlichen > Aufwand treiben. Einen Performance-Vorteil gegenüber einer Datenbank > hast Du damit vermutlich nicht (ich habe es allerdings nicht gemessen). Letzthin habe ich eine Artikel gelesen zum neuen Kernel 4.13. Da geht es anscheinend um eine Möglichkeit, irgendwie Dateien im Terra-Bereich in einem Verzeichnis unter ext4 abzubilden. Daher sollten die paar 100k Dateien kein Problem sein :-) Da jedes DB-System schlussendlich auf Dateien zugreift (ausser es läuft nur im RAM), sollten bei einer idealen Programmierung, ein reiner Dateizugriff schneller sein, da dann keine SQL-Zwischenschicht verarbeitet werden muss. Allerdings ist das sehr theoretisch, denn ich vermute, dass die MySQL Programmierer ihre Arbeit gut gemacht haben und es daher nicht viel Performance Verlust beim Übersetzen gibt ;-) Es stellt sich daher die Frage, wo der genaue Flaschenhals liegt. Greifen alle Threads auf eine Tabelle zu, obwohl sie das nicht müssten? Falls ja, dann müsste man schauen, wie man dort den Engpass beseitigt und ob man dort mit einer Bulkabfrage nicht Zeit sparen könnte? Etwa: hole die nächsten 100 Jobs und setze den Status auf "in Arbeit", dann werden die Jobs lokal den Workern übergeben und jeder setzt ihn dann selber auf "erledigt". Sobald die Jobs dann verteilt sind, werden die nächsten geholt usw. Gruss, Markus, der sich nicht ganz sich ist, wo das genaue Problem liegt und daher auch nicht genauere Hinweise geben kann ;-)
[toc] | [prev] | [next] | [standalone]
| From | Claus Reibenstein <4spamersonly@kabelmail.de> |
|---|---|
| Date | 2017-07-19 16:44 +0200 |
| Message-ID | <et99j3Fod5nU2@mid.individual.net> |
| In reply to | #4167 |
Markus Grob schrieb am 19.07.2017 um 13:07: > Letzthin habe ich eine Artikel gelesen zum neuen Kernel 4.13. Da geht > es anscheinend um eine Möglichkeit, irgendwie Dateien im > Terra-Bereich in einem Verzeichnis unter ext4 abzubilden. Eigentlich konnte Linux - es geht doch um Linux, oder? - schon immer Dateien von der Erde speichern. Interessant wird es erst, wenn außerirdische Dateien gespeichert werden sollen ;-) Gruß Claus
[toc] | [prev] | [next] | [standalone]
| From | "Peter J. Holzer" <hjp-usenet3@hjp.at> |
|---|---|
| Date | 2017-07-20 14:14 +0200 |
| Message-ID | <slrnon17ll.q2u.hjp-usenet3@hrunkner.hjp.at> |
| In reply to | #4167 |
On 2017-07-19 11:07, Markus Grob <snoopy@ilnet.ch> wrote:
> Peter J. Holzer schrieb:
>> On 2017-06-24 05:37, Michael Vogel <ike@spamfence.net> wrote:
>>> Eine Möglichkeit wäre es, die Jobs als einzelne Dateien in einem
>>> Spoolverzeichnis abzulegen. Allerdings verarbeitet das System derzeit
>>> schon 100.000 bis 200.000 Jobs pro Tag. Die Frage ist also, wie gut ein
>>> Dateisystem dafür geeignet ist, dass in einem Ordner so viele Dateien
>>> pro Tag angelegt und gelöscht werden.
>>
>> Damit sollten so ziemlich alle Filesysteme auf halbwegs aktueller
>> Hardware zurechtkommen. Sind ja nur eine Handvoll Operationen pro
>> Sekunde. Wenn Du allerdings wirklich absturzsicher sein willst, musst Du
>> bei modernen Filesystemen (zumindest unter Linux) einen ziemlichen
>> Aufwand treiben. Einen Performance-Vorteil gegenüber einer Datenbank
>> hast Du damit vermutlich nicht (ich habe es allerdings nicht gemessen).
>
> Letzthin habe ich eine Artikel gelesen zum neuen Kernel 4.13. Da geht es
> anscheinend um eine Möglichkeit, irgendwie Dateien im Terra-Bereich in
> einem Verzeichnis unter ext4 abzubilden.
Was auch immer "Dateien im Terra-Bereich in einem Verzeichnis" genau
heißen mag ...
Das Limit für die Anzahl der Dateien in einem (ext4) Verzeichnis wurde
in Linux 4.13 von ca. 10 Millionen auf ca. 2 Milliarden angehoben.
Allerdings wurde auch darauf hingewiesen, dass man wahrscheinlich
Performance-Probleme bekommt, bevor man an diesem Limit anstößt.
> Daher sollten die paar 100k Dateien kein Problem sein :-)
Wie gesagt, normalerweise keine Problem, und in diesem Anwendungsfall
ohnehin nicht, da hier ja die Files nicht gleichzeitig existieren.
> Da jedes DB-System schlussendlich auf Dateien zugreift (ausser es läuft
> nur im RAM), sollten bei einer idealen Programmierung, ein reiner
> Dateizugriff schneller sein, da dann keine SQL-Zwischenschicht
> verarbeitet werden muss. Allerdings ist das sehr theoretisch, denn ich
> vermute, dass die MySQL Programmierer ihre Arbeit gut gemacht haben und
> es daher nicht viel Performance Verlust beim Übersetzen gibt ;-)
Das übersetzen ist (in einfachen Fällen wie diesem) nicht das Problem.
Die Organisation der Daten ist es. Mit einer klassischen Queue im
Filesystem (ein Incoming-Directory, ein Work-In-Progress-Directory, 1
File pro Job), wie es Michael vermutlich vorhatte, sehen die Operationen
(vereinfacht) so aus:
* Job anlegen:
File anlegen
Inhalt schreiben
fsync auf File
File schließen
fsync auf Directory incoming.
* Job-Bearbeitung beginnen:
Directory incoming öffnen
Directory lesen, bis ein passender Job gefunden ist
File von incoming nach wip verschieben
fsync auf wip
fsync auf incoming
File öffnen
Inhalt lesen
* Job-Abarbeitung beenden:
File in wip löschen
fsync auf wip
Das sind also mindestens 5 fsyncs und damit synchrone Schreibzugriffe,
wobei jeder mindestens 2 Blöcke betrifft, die nicht eng beisammen
liegen. Also mindestens 10 random Seeks.
Ein Datenbanksystem hat insgesamt sicher höheren Aufwand (es müssen auch
Indizes etc. aktualisiert werden), aber wenn es geschickt gemacht ist,
muss pro Transaktion nur ein Block synchron geschrieben werden, also pro
Job 3 statt 10. Die restlichen Blöcke können geschrieben werden "wenn
Zeit ist".
Ob MySQL in diesem Sinne "geschickt gemacht" ist, weiß ich nicht. Ich
fürchte eher nein, aber zumindest theoretisch könnte eine Queue auf
Basis eines RDBMS schneller sein also ein Queue-Verzeichnis, wenn man
bei letzterem die gleiche Absturzsicherheit haben möchte,
In der Praxis müsste man das (wie immer) testen.
> Es stellt sich daher die Frage, wo der genaue Flaschenhals liegt.
Michael hat leider sehr wenig dazu geschrieben, was er eigentlich macht,
also ist es schwer zu erkennen, was er besser machen könnte. Da er mit
einem zusätzlichen Lock außerhalb der Datenbank das Problem deutlich
entschärfen konnte (was unintuitiv ist, weil er damit genau die Ursache,
die er vermutet hat, verstärkt), vermute ich, dass entweder seine Querys
nicht ideal sind oder er in ein MySQL-internes Performance-Problem
gelaufen ist.
hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | hjp@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
[toc] | [prev] | [standalone]
Back to top | Article view | de.comp.lang.php
csiph-web