expertenaustausch > comp.lang.* > comp.lang.php.datenbanken

Ulf Wendel (18.02.2011, 12:49)
.... der Betreff sagt es.

Ich würde mich freuen, wenn jemand etwas aus dem Nähkästchen plaudert
und verrät wie die Anfrageverteilung vorgenommen wird, ob es ein
Flaschenhals ist, wie komplex die Regeln sind, wo der Schuh drückt usw.

Danke,
Ulf
Axel Schwenke (24.02.2011, 02:16)
Moin Ulf :)

> Ich würde mich freuen, wenn jemand etwas aus dem Nähkästchen plaudert
> und verrät wie die Anfrageverteilung vorgenommen wird, ob es ein
> Flaschenhals ist, wie komplex die Regeln sind, wo der Schuh drückt usw.


Marktforschung?

Nach meiner Erfahrung kann man das Read/Write-Splitting nicht
zuverlässig automatisieren. Die Applikation muß bei jeder Query
wissen, ob die auf den Master gehen muß (es ist ein Write oder
wenn es ein Read ist, müssen die Daten aktuell sein) oder ob es
ein Slave sein darf.

Und dann ist das einfachste, zwei Connection-Objekte zu benutzen.

XL
Ulf Wendel (24.02.2011, 23:19)
XL!

Ich dachte Du bist nur drüben im MySQL-Bereich ?! Ich habe mich hier
ewig nicht rumgetrieben. Ich trauere noch den MLs nach. Bin etwas
rückständig...

Am 24.02.2011 01:16, schrieb Axel Schwenke:
>> Ich würde mich freuen, wenn jemand etwas aus dem Nähkästchen plaudert
>> und verrät wie die Anfrageverteilung vorgenommen wird, ob es ein
>> Flaschenhals ist, wie komplex die Regeln sind, wo der Schuh drückt usw.

> Marktforschung?


Och, so direkt... was sonst!

> Nach meiner Erfahrung kann man das Read/Write-Splitting nicht
> zuverlässig automatisieren. Die Applikation muß bei jeder Query
> wissen, ob die auf den Master gehen muß (es ist ein Write oder
> wenn es ein Read ist, müssen die Daten aktuell sein) oder ob es
> ein Slave sein darf.


Glaubst Du wir haben nichts abzugrasen im "start small"-Bereich? Im
Moment stehen wir hier:

[x] benutzerdefinierte Verteilung
[x] automatische Verteilung - SELECT Erkennung, sonst Master
[x] Verteilung: random, round-robin [, benutzerdefiniert]

> Und dann ist das einfachste, zwei Connection-Objekte zu benutzen.


Wieso zwei und nicht 1 + n, n >= 1. Hä? Will sagen: Du hast n >= 1 Slaves.

Weißt Du, woran ich scheitere ist die Frage wie transparent eine Lösung
sein könnte und soll, wenn sie Bestandteil des Treibers wäre. C/J
überzeugt mich nicht so richtig. Die stopfen das eine Lösung auf ein
Problem und irgendwann bricht der Turm zusammen. Ich lasse mich immer
wieder blenden von irgendwelchen Automatismen, die vermeintliche
Lösungen bringen.

Ulf
Axel Schwenke (25.02.2011, 14:45)
Moin,

Ulf Wendel <ulf.wendel> wrote:
> Ich dachte Du bist nur drüben im MySQL-Bereich ?!


Ich lurke hier meistens nur.

> Ich habe mich hier
> ewig nicht rumgetrieben. Ich trauere noch den MLs nach. Bin etwas
> rückständig...


Dann genieße den Augenblick. Wie ich erfahren habe, ist diese Gruppe
ein Zombie. Der RfD zum löschen ist wohl schon raus.

>> Nach meiner Erfahrung kann man das Read/Write-Splitting nicht
>> zuverlässig automatisieren. Die Applikation muß bei jeder Query
>> wissen, ob die auf den Master gehen muß (es ist ein Write oder
>> wenn es ein Read ist, müssen die Daten aktuell sein) oder ob es
>> ein Slave sein darf.


> Im Moment stehen wir hier:
> [x] benutzerdefinierte Verteilung
> [x] automatische Verteilung - SELECT Erkennung, sonst Master
> [x] Verteilung: random, round-robin [, benutzerdefiniert]


Das sind nicht direkt alle möglichen Kombinationen. Ich würde
benutzerdefiniert und automatich als eine Koordinate ansehen.
Und die Verteilung auf mehrere Slaves als eine zweite,
unabhängige Koordinate.

>> Und dann ist das einfachste, zwei Connection-Objekte zu benutzen.

> Wieso zwei und nicht 1 + n, n >= 1. Hä? Will sagen: Du hast n >= 1 Slaves.


Weil das auf diesem Level transparent ist. Bei PHP hältst du die
Connections ja ohnehin nur für eine Seite. Also kannst du genauso
gut am Anfang der Arbeit einen der n Slaves picken und dem Rest
des Skripts nur zwei Objekte zeigen (1 Master + 1 Slave).

Alternativ kann man das Load-Balancing in das Slave-Objekt packen
und dann per Query einen Slave picken. Allerdings gibt es gute
Gründe dafür, während der Abarbeitung eines Skripts konsistent
immer den gleichen Slave zu verwenden:

- die Caches des Slave sind dann konsistent (warm)
- der Connection-Scope (User-Variablen, Session-Variablen, temporäre
Tabellen, Read-Snapshot) ist konsistent

> Weißt Du, woran ich scheitere ist die Frage wie transparent eine Lösung
> sein könnte und soll, wenn sie Bestandteil des Treibers wäre.


Da vollautomatisch nicht geht, brauchst du immer eine Möglichkeit,
zusätzliche Information (muß zu Master/kann zu Slave) von der Stelle
im Code, wo das Statement losgeschickt wird, zum Treiber zu bringen.

Entweder macht man das explizit: zwei DB-Objekte. Oder ein Objekt mit
entsprechenden Methoden (db->query_master() vs. db->query_master()).
Oder inline, z.B. mit magischen SQL-Kommentaren in der Query.

SELECT /* FROM MASTER */ foo ...

Die Wahl sieht mir sehr nach Pest (zusätzliche Variable zum Treiber)
vs. Cholera (inband signaling) aus.

> überzeugt mich nicht so richtig. Die stopfen das eine Lösung auf ein
> Problem und irgendwann bricht der Turm zusammen. Ich lasse mich immer
> wieder blenden von irgendwelchen Automatismen, die vermeintliche
> Lösungen bringen.


Ein paar einfache Sachen, wo der Automatismus in Grübeln kommt:

CALL my_procedure() - Master oder Slave?
CREATE TEMPORARY TABLE ... - Master oder Slave?
SET SESSION ... - Master oder Slave?
SET @foo=42 - Master oder Slave?
BEGIN - Master oder Slave?

All diese Dinge können vollkommen legal (und sehr sinnvoll!) für
die Slave-Connection sein. Ein Automatismus hätte aber keine
Möglichkeit, sauber zu entscheiden ob das jeweils sicher ist.

Enthält my_procedure() DML-Statements? Ist die temporäre Tabelle
für einen Report oder wird nachher INSERT ... SELECT aus dieser
Tabelle gemacht? Werden die Session- oder User-Variablen von
zukünftigen Statements auf dem Master oder dem Slave gebraucht?
Dient die Transaktion nur dazu, einen stabilen Snapshot zu
bekommen (REPEATABLE-READ) oder wird da später auch geschrieben?

Natürlich kann man sicherheitshalber alle fraglichen Sachen auf
den Master schicken. Aber das kann u.U. dazu führen, daß deine
Slaves arbeitslos werden.

XL
Claus Reibenstein (26.02.2011, 12:34)
Axel Schwenke schrieb:

> Der RfD zum löschen ist wohl schon raus.


Guten Morgen :-)

<Result-de.comp.lang.php-reorg-21.02.2011>

Der RfD zum Löschen war am 13.12.2010 raus, also vor über 2 Monaten.

Gruß. Claus
Ulf Wendel (28.02.2011, 18:32)
XL, das ist hilfreich!

Am 25.02.2011 13:45, schrieb Axel Schwenke:
> Ulf Wendel<ulf.wendel> wrote:
> Das sind nicht direkt alle möglichen Kombinationen. Ich würde
> benutzerdefiniert und automatich als eine Koordinate ansehen.
> Und die Verteilung auf mehrere Slaves als eine zweite,
> unabhängige Koordinate.


Ich habe keine Kombinationen genannt. Ich habe ein paar "Funktionen"
aufgelistet. Was ich schrieb erhebt nicht den Anspruch logisch zu
gruppieren oder "Koordinaten" zu benennen.

[..]
> - die Caches des Slave sind dann konsistent (warm)
> - der Connection-Scope (User-Variablen, Session-Variablen, temporäre
> Tabellen, Read-Snapshot) ist konsistent


Fairer Einwand.

> Da vollautomatisch nicht geht, brauchst du immer eine Möglichkeit,
> zusätzliche Information (muß zu Master/kann zu Slave) von der Stelle
> im Code, wo das Statement losgeschickt wird, zum Treiber zu bringen.
> Entweder macht man das explizit: zwei DB-Objekte. Oder ein Objekt mit
> entsprechenden Methoden (db->query_master() vs. db->query_master()).
> Oder inline, z.B. mit magischen SQL-Kommentaren in der Query.
> SELECT /* FROM MASTER */ foo ...
> Die Wahl sieht mir sehr nach Pest (zusätzliche Variable zum Treiber)
> vs. Cholera (inband signaling) aus.


Das kommt darauf an von wo man kommt. Kommt man von Deinem zwei
DB-Objekte Seite, ist es keine schöne Lösung.

> Ein paar einfache Sachen, wo der Automatismus in Grübeln kommt:
> CALL my_procedure() - Master oder Slave?
> CREATE TEMPORARY TABLE ... - Master oder Slave?
> SET SESSION ... - Master oder Slave?
> SET @foo=42 - Master oder Slave?
> BEGIN - Master oder Slave?
> All diese Dinge können vollkommen legal (und sehr sinnvoll!) für
> die Slave-Connection sein. Ein Automatismus hätte aber keine
> Möglichkeit, sauber zu entscheiden ob das jeweils sicher ist.


Genau.

> Enthält my_procedure() DML-Statements? Ist die temporäre Tabelle
> für einen Report oder wird nachher INSERT ... SELECT aus dieser
> Tabelle gemacht? Werden die Session- oder User-Variablen von
> zukünftigen Statements auf dem Master oder dem Slave gebraucht?
> Dient die Transaktion nur dazu, einen stabilen Snapshot zu
> bekommen (REPEATABLE-READ) oder wird da später auch geschrieben?


Ein paar coole Randfälle an die ich noch nicht gedacht habe.

Danke!

Ulf
Ähnliche Themen