Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Lese/Schreib-Splits mit Zend_Db

Wie Sie sagten, kann MySQlProxy eine Lösung sein, aber ich persönlich habe es nie in der Produktion getestet.

Ich verwende 2-Db-Verbindungen in meinem Code, um Schreib- und Leseanforderungen aufzuteilen. 80 % der üblichen Aufgaben werden mit der Leseverbindung erledigt. Sie könnten den Zend_Application_Resource_Multidb um das zu handhaben (Bei mir habe ich diesen Teil schon lange gemacht und speichere einfach eine zweite Db-Verbindung in der Registry).

  • Beschränken Sie zunächst Ihre Benutzerrechte nur auf den Lesebetrieb und erstellen Sie einen weiteren dbuser mit Schreibrechten.
  • verfolgen Sie dann jede Schreibanforderung in Ihrem Code ("update", "insert", "delete" ist ein guter Anfang) und versuchen Sie, all diese Aufrufe mit einem dedizierten Helfer durchzuführen.
  • Führen Sie Ihre App aus und beobachten Sie, wie sie abstürzt, und beheben Sie dann Probleme :-)

Es ist einfacher, wenn Sie dieses Problem am Anfang denken. Zum Beispiel:

  • Normalerweise habe ich eine Zend_Db_Table-Factory, die einen 'read'- oder 'write'-Parameter nimmt und mir ein Singleton der richtigen Zend_Db_Table gibt (ein duales Singleton, wenn ich eine Lese-Instanz und eine Schreib-Instanz haben kann). Dann muss ich nur sicherstellen, dass ich die richtige initialisierte Zend_Db_Table verwende, wenn ich Abfragen/Operationen mit Schreibzugriff verwende. Beachten Sie, dass die Speichernutzung viel besser ist, wenn Zend_Db_Table als Singletons verwendet wird.
  • Ich versuche, alle Schreiboperationen in einem TransactionHandler zu bekommen. Dort kann ich überprüfen, ob ich nur Objekte verwende, die mit der richtigen Verbindung verknüpft sind. Transaktionen werden dann auf Controllern verwaltet, ich versuche nie, Transaktionen in Datenbankschichten zu verwalten, alle Start-/Commit-/Rollback-Denken werden auf den Controllern (oder einer anderen konzeptionellen Schicht, aber nicht der DAO-Schicht) durchgeführt.

Dieser letzte Punkt, Transaktionen, ist wichtig. Wenn Sie Transaktionen verwalten möchten, ist es wichtig, die READ-Anforderungen INNERHALB der Transaktion zu stellen , mit der WRITE-fähigen Verbindung . Da alle Lesevorgänge, die vor der Transaktion durchgeführt wurden, als veraltet betrachtet werden sollten, und wenn Ihr Datenbank-Backend implizite Sperren durchführt, müssen Sie die Leseanforderung stellen, um die Sperren zu erhalten. Wenn Ihr Datenbank-Backend keine impliziten Lesevorgänge durchführt, müssen Sie auch die Zeilensperren in der Transaktion ausführen. Und das bedeutet, dass Sie sich nicht auf das SELECT-Schlüsselwort verlassen sollten, um diese Anfrage auf die Nur-Lese-Verbindung zu schieben.

Wenn Sie in Ihrer Anwendung eine gute DB-Layer-Nutzung haben, ist die Änderung nicht wirklich schwer vorzunehmen. Wenn Sie chaotische Dinge mit Ihrer Datenbank/DAO-Schicht gemacht haben, dann ... ist es möglicherweise schwieriger.