Voici un résumé des découvertes lorsqu'une application Java héritée avec une configuration standard il y a environ 10 ans a été rendue compatible avec la réplication de base de données. La technologie et la version utilisées sont les suivantes.
Avant d'entrer dans les détails, passons en revue la réplication.
La réplication de base de données est un concept adopté par de nombreux systèmes de gestion de base de données et signifie une relation maître-esclave entre l'original et la copie de la base de données. Le maître enregistre la mise à jour et avertit les esclaves. Le côté esclave envoie un message indiquant que la mise à jour a été reçue correctement, notifiant que la prochaine mise à jour est prête à être acceptée.
Source: [Wikipédia](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3 % 82% B7% E3% 83% A7% E3% 83% B3)
La configuration d'un DB avec un maître qui peut être visualisé et mis à jour et un esclave qui est toujours synchronisé avec le maître [^ 1] et ne peut être visualisé que s'appelle la réplication.
Un traitement de mise à jour tel que ʻINSERT et ʻUPDATE
est effectué sur le maître, et un traitement de référence tel que SELECT
est effectué sur l'esclave pour répartir la charge sur la base de données ou lorsque le maître tombe en panne pour une raison quelconque. De plus, en préparant une réplique de basculement pour remplacer le maître, les temps d'arrêt peuvent être minimisés et une haute disponibilité peut être obtenue.
En outre, il y aura une copie du maître, ce qui peut rendre les données redondantes.
[^ 1]: En fait, il y a un délai de synchronisation de plusieurs millisecondes, il peut donc être nécessaire de le considérer du côté de l'application.
Vous pouvez profiter de divers avantages en utilisant une configuration de réplication, mais l'application doit également être créée de manière appropriée, comme des requêtes distribuées et des mesures contre le décalage de synchronisation.
En spécifiant l'option readOnly
dans Spring's @ Transactional
, le contact est déterminé pour chaque transaction.
Comme mentionné précédemment, les exigences pour la mise en œuvre étaient des «requêtes distribuées» et des «contre-mesures de retard de synchronisation».
Parmi ceux-ci, ce dernier a été traité en élargissant la portée des transactions. Plus précisément, l'implémentation précédente a changé la transaction d'être créée pour chaque couche de référentiel (= 1 requête) à être créée pour chaque couche de service (= plusieurs requêtes). Cela signifie que même si les mises à jour et les références sont mélangées dans plusieurs requêtes, le contact est déterminé comme maître ou esclave pour chaque transaction. Puisque l'esclave est en lecture seule, ce sera inévitablement une requête au maître s'il existe des systèmes de mise à jour mixtes. Par conséquent, dans une transaction dans laquelle les systèmes de mise à jour sont mélangés, le système de référence interroge également le maître, ce qui signifie qu'une répartition stricte de la charge n'est pas possible, mais à la place, il n'est pas nécessaire de prendre en compte le délai de synchronisation, donc la charge Suite à la pondération de la taille et de la complexité de l'implémentation, nous avons choisi de simplifier l'implémentation.
Perspective | 1 transaction/1 Demande | 1 transaction/n Demandes de renseignements |
---|---|---|
Répartition de la charge | Peut être strictement réparti entre le système de mise à jour et le système de référence | Strictement non distribué (maître s'il y a un système de mise à jour, esclave s'il n'y a pas de système de mise à jour) |
Simplicité de mise en œuvre | Cela devient compliqué car il faut tenir compte du décalage temporel de synchronisation (dans le cas de mise à jour → référence, considérez qu'il s'agit des dernières données au moment de la référence) | Simple sans tenir compte du décalage dans le temps de synchronisation (même lors de la mise à jour → référencement, ce seront toujours les dernières données) |
Par conséquent, ce que j'écris dans cet article est ce que j'ai fait pour les «requêtes distribuées».
@ Transactional
J'avais besoin de savoir à ce sujet afin d'utiliser @ Transactional
de Spring, alors j'ai fait un peu de recherche.
@ Transactional
ajoute du code lié à la gestion des transactions tel que begin
et commit
, qui figuraient jusqu'ici dans le code source, à la méthode en tant qu'annotation, et Spring AOP autorise begin
au début de la méthode. C'est une fonction qui peut expulser la gestion des transactions du code source et améliorer la visibilité en exécutant commit
à la fin.
Vous pouvez définir diverses options pour ce @ Transactional
, mais le readOnly
utilisé cette fois peut spécifiertrue / false (default)
, ce qui fait du contact un maître ou un esclave. Tu peux décider.
La valeur par défaut est «false», ce qui interroge le maître, mais vous pouvez spécifier «true» pour interroger l'esclave.
Si la classe est gérée par bean dans le conteneur Spring (= Spring AOP peut être exécuté), ajoutez-la simplement à la méthode comme suit. Il peut également être donné à la classe elle-même, auquel cas il est synonyme de le donner à toutes les méthodes de la classe.
UserService.java
public class UserService implements Service {
@Transactional(readOnly = false) //Commencé lorsque cette méthode est appelée et validée à la sortie
public User createUser() {
// INSERT
}
@Transactional(readOnly = true) //Puisqu'il s'agit d'un système de référence, demandez à l'esclave
public User getUser() {
// SELECT
}
@Transactional(readOnly = false) //Puisqu'il s'agit d'un système de mise à jour, contactez le maître
public void updateUser() {
// UPDATE
}
@Transactional(readOnly = false)
public void deleteUser() {
// DELETE
}
}
Ajoutez la description suivante au fichier de configuration Spring et activez l'annotation.
Spring.xml
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="dataSourceTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
La connexion est établie par MySQL Connector / J, mais la source de données est décrite comme la destination de connexion comme suit. → Document officiel
Écrivez d'abord l'hôte maître, puis écrivez les hôtes esclaves séparés par des virgules.
Spring.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.ReplicationDriver"/>
<property name="url" value="jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:13306"/>
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
Puisqu'il s'agissait d'un support pour les applications héritées, il semble que la partie spécifique ne sera pas très utile à l'avenir, mais je pense que la réplication elle-même est une configuration standard, donc je connaissais le concept et le type de support nécessaire. Je pense que c'est une moisson. Je pense que DB est utilisé dans la plupart des applications, alors j'aimerais utiliser les connaissances que j'ai acquises cette fois.
Recommended Posts