当前位置:首页 > Mysql教程 > 列表

MySQL数据库实现读写分离与负载均衡

发布:smiling 来源: PHP粉丝网  添加日期:2015-04-20 11:18:11 浏览: 评论:0 

最近在一个群里老看到有一个朋友问游戏数据充值如何实现读写分享了,在此小编正好看到了一篇文章下面整理与各位看看,MySQL 数据库的读写分离和负载均衡一般是通过第三方软件来实现的,也可以通过mysql驱动程序来实现,如com.mysql.jdbc.ReplicationDriver.

详细文档参见:http://dev.mysql.com/doc/refman/5.5/en/connector-j-info.html

代码如下:

  1. import java.sql.Connection; 
  2. import java.sql.ResultSet; 
  3. import java.util.Properties; 
  4.    
  5. import com.mysql.jdbc.ReplicationDriver; 
  6.    
  7. public class ReplicationDriverDemo { 
  8.   //开源软件:phpfensi.com 
  9.   public static void main(String[] args) throws Exception { 
  10.     ReplicationDriver driver = new ReplicationDriver(); 
  11.    
  12.     Properties props = new Properties(); 
  13.    
  14.      
  15. // We want this for failover on the slaves 
  16.     props.put("autoReconnect""true"); 
  17.    
  18.      
  19. // We want to load balance between the slaves 
  20.     props.put("roundRobinLoadBalance""true"); 
  21.    
  22.     props.put("user""foo"); 
  23.     props.put("password""bar"); 
  24.    
  25.      
  26. // 
  27.      
  28. // Looks like a normal MySQL JDBC url, with a 
  29.      
  30. // comma-separated list of hosts, the first 
  31.      
  32. // being the 'master', the rest being any number 
  33.      
  34. // of slaves that the driver will load balance against 
  35.      
  36. // 
  37.    
  38.     Connection conn = 
  39.         driver.connect("jdbc:mysql:replication://master,slave1,slave2,slave3/test"
  40.             props); 
  41.    
  42.      
  43. // 
  44.      
  45. // Perform read/write work on the master 
  46.      
  47. // by setting the read-only flag to "false" 
  48.      
  49. // 
  50.    
  51.     conn.setReadOnly(false); 
  52.     conn.setAutoCommit(false); 
  53.     conn.createStatement().executeUpdate("UPDATE some_table ...."); 
  54.     conn.commit(); 
  55.    
  56.      
  57. // 
  58.      
  59. // Now, do a query from a slave, the driver automatically picks one 
  60.      
  61. // from the list 
  62.      
  63. // 
  64.    
  65.     conn.setReadOnly(true); 
  66.    
  67.     ResultSet rs = 
  68.       conn.createStatement().executeQuery("SELECT a,b FROM alt_table"); 
  69.    
  70.      ....... 
  71.   } 

读写分离,代码如下:

  1. jdbc:mysql:replication: 
  2. //master:3306,slave1:3306,slave2:3306/dbname 
  3. When using the following connection string: jdbc:mysql:replication://dbmaster:3306,dbslave1:3306,dbslave2:3306/dbname 
  4. dbmaster is used for all write connections as expected and dbslave1 is used for all read connections, but dbslave2 is never used. I would have expected distributed reads between dbslave1 and dbslave2. 

原理是:ReplicationDriver生成代理的connection对象,当设置这个connection.readOnly=true时,连接slave,当connection.readOnly=false时,连接master.

负载均衡:

  1. jdbc:mysql:loadbalance: 
  2. //master:3306,slave1:3306,slave2:3306/dbname 
  3. When using the following connection string: jdbc:mysql:loadbalance://dbmaster:3306,dbslave1:3306,dbslave2:3306/dbname 
  4. connections are load-balanced between all three servers for both read and write connections. 

问题:读写分离时可能会碰到刚写完master,再马上到slave进行查询的情况,而主从复制的时候有延迟,这时怎么解决呢?有两个办法:

1.比如增加页面保存数据后马上跳转到列表页面,这时可能出不来数据,因为复制还没完成,这时可以在前台添加一些成功的提示,成功页面等进行一些页面跳转延迟处理,让服务器有时间去复制,复制延迟一般在毫秒级,而这种提示处理在秒级,所以时间上一般是足够的.

2.第1种办法可能部分场景是可行的,但是有些场景要求比较高,需要实时的,这时可以在读取的时候进行处理,强制从master中读取,可以通过注解,加参数/标识等来指定从master读取数据.

ps 这种做法小编觉得还不是最好的要实现负载均衡我们可以实现服务器集群来实现.

Tags: MySQL读写分离 MySQL负载均衡

分享到: