1. 程式人生 > >spring MVC、mybatis配置讀寫分離,ReplicationDriver(轉載)

spring MVC、mybatis配置讀寫分離,ReplicationDriver(轉載)

讀寫 就是 actor 只讀 完成後 方法 -o pass 執行

環境:

3臺數據庫機器,一個master,二臺slave,分別為slave1,slave2

2.要實現的目標:

①使數據寫入到master

②讀數據時,從slave1和slave2中讀取

以此來實現數據庫的讀寫分離

3.原理:

使用mysql驅動自帶的replicationDriver來實現,replicationDriver簡單來說就是存在兩個Connection,一個masterConnection,一個slaveConnection;

當setReadonly(true)就把currentConnection=slaveConnection,反之設置為masterConnection

4.實現步驟:

①jdbc.properties

  1. ## 使用ReplicationDriver而不是driver
  2. jdbc.driverClassName=com.mysql.jdbc.ReplicationDriver
  3. ## 使用的是jdbc:mysql:replication://
  4. jdbc.url=jdbc:mysql:replication://master:3306,slave1:3306,slave2:3306/test2?characterEncoding=utf8
  5. jdbc.username=root
  6. jdbc.password=123456

②使用spring的事物,把讀操作設置為readonly=true

jdbc.connection.driver=com.mysql.jdbc.ReplicationDriver jdbc.connection.url=jdbc:mysql:replication://192.168.202.190,192.168.202.190/job?useUnicode=true&characterEncoding=utf-8

  1. <!-- 配置dataSource -->
  2. <bean class="com.alibaba.druid.pool.DruidDataSource"
  3. id="dataSource">
  4. <property name="driverClassName" value="${jdbc.driverClassName}"/>
  5. <property name="username" value="${jdbc.username}"/>
  6. <property name="password" value="${jdbc.password}"/>
  7. <property name="url" value="${jdbc.url}"></property>
  8. </bean>
  9. <!-- transaction configuration-->
  10. <bean id="transactionManager"
  11. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  12. <property name="dataSource" ref="dataSource" />
  13. </bean>
  14. <!-- 定義事務通知 -->
  15. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  16. <!-- 定義方法的過濾規則 -->
  17. <tx:attributes>
  18. <!-- 所有方法都使用事務 -->
  19. <tx:method name="*" propagation="REQUIRED"/>
  20. <!-- 定義所有get開頭的方法都是只讀的 -->
  21. <tx:method name="get*" read-only="true"/>
  22. </tx:attributes>
  23. </tx:advice>
  24. <!-- 定義AOP配置 -->
  25. <aop:config>
  26. <!-- 定義一個切入點 -->
  27. <aop:pointcut expression="execution (* com.most.service.*.*(..))" id="services"/>
  28. <!-- 對切入點和事務的通知,進行適配 -->
  29. <aop:advisor advice-ref="txAdvice" pointcut-ref="services"/>
  30. </aop:config>
  31. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  32. <property name="dataSource" ref="dataSource" />
  33. <property name="configLocation" value="/WEB-INF/conf/mybatis-config.xml" />
  34. </bean>


所有以get開頭的方法被調用時,readonly = true

ps:這個只是實現了讀寫分離,master與slave之間的數據同步使用mysql replication即可

昨晚看了一晚上的MySQL文檔,主要是關於MySQL的復制方面的文檔,用的工具是MySQL的幫助文檔+金山詞霸。

終於比較大概的了解了如何通過復制來提升MySQL數據庫的高可用性和處理能力,不過還沒有經過實際的試驗,但整體的思想是清楚了,下面把思路大概的描述一下,有機會再進行實驗。

首先在服務器端采用1+N的模型來安裝和配置MySQL數據庫。1就是一個master數據庫,N就是一至多個slave數據庫。master數據 庫必須啟用binlog模式,關於這兩種數據庫的配置參見MySQL的文檔。配置完成後就形成了一個1+N的復制集群,當對master進行修改時會自動 把修改的數據更新到N個slave數據庫上。但是有一個註意的是,所有的修改操作包括添加、刪除、修改等語句必須作用在master數據庫上,這樣才能使 數據可靠的復制到其他slave服務器上。另外,由於slave服務器只用作查詢,因此選用MyISAM的存儲引擎可以提高查詢的速度。

而在客戶端呢?如何使客戶端程序能均衡的使用這些可用的服務器呢?而且更新操作只能對master進行處理。這個豈不是應用程序對數據庫的操作邏輯非常的復雜?

其實沒有那麽復雜,MySQL為我們提供了接口可以將這些復雜的操作透明化。ccccc下面主要介紹采用JDBC的客戶端如何工作在基於復制的集群環境中,其他編程語言請參照mysql的文檔。

MySQL最新的JDBC驅動程序包中提供了一個驅動類就是 com.mysql.jdbc.ReplicationDriver 。這個驅動類允許在url中設置多個mysql主機地址,例如:

jdbc:mysql://master1,slave1,slave2/dlog?autoReconnect=true&roundRobinLoadBalance=true

在上面的url中,有三個主機地址分別是master1,slave1,slave2,其中ReplicationDriver 規定第一個主機是master主機地址,剩下的全部是slave主機。另外有兩個參數必須指定為true,就是autoReconnect和roundRobinLoadBalance。

使用這個驅動和配置後還不能馬上解決所有的問題,我們還需要對程序做一些小改動。

我們必須告訴驅動程序,哪些語句的執行是作用在master數據庫,而哪些語句的執行作用在slave數據庫上。

ReplicationDriver 是通過Connection對象的readOnly屬性來判斷該操作是否為更新操作。因此我們在執行一個sql語句的時候必須調用一下 setReadOnly告訴驅動程序當前執行的操作是否是只讀。如果你是使用hibernate操作數據庫的,那可以調用 Query.setReadOnly方法。

以上就是整個思路的大概描述,猜想肯定還有存在一些問題,例如因為數據的復制過程是異步的,也是說有可能執行了某個更新操作,但是查詢的時候查不到的情況出現。當然這些問題只能在實際的過程中進行解決。

spring MVC、mybatis配置讀寫分離,ReplicationDriver(轉載)