MySQL 数据库的读写分离和负载均衡一般是通过第三方软件来实现的,也可以通过mysql驱动程序来实现,如com.mysql.jdbc.ReplicationDriver.
详细文档参见:http://dev.mysql.com/doc/refman/5.5/en/connector-j-info.html,代码如下:
- importjava.sql.Connection;
- importjava.sql.ResultSet;
- importjava.util.Properties;
- importcom.mysql.jdbc.ReplicationDriver;
- publicclassReplicationDriverDemo{
- publicstaticvoidmain(String[]args)throwsException{
- ReplicationDriverdriver=newReplicationDriver();
- Propertiesprops=newProperties();
- //Wewantthisforfailoverontheslaves
- props.put("autoReconnect","true");
- //Wewanttoloadbalancebetweentheslaves
- props.put("roundRobinLoadBalance","true");
- props.put("user","foo");
- props.put("password","bar");
- //
- //LookslikeanormalMySQLJDBCurl,witha
- //comma-separatedlistofhosts,thefirst
- //beingthe'master',therestbeinganynumber
- //ofslavesthatthedriverwillloadbalanceagainst
- //
- Connectionconn=
- driver.connect("jdbc:mysql:replication://master,slave1,slave2,slave3/test",
- props);
- //
- //Performread/writeworkonthemaster
- //bysettingtheread-onlyflagto"false"
- //
- conn.setReadOnly(false);
- conn.setAutoCommit(false);
- conn.createStatement().executeUpdate("UPDATEsome_table....");
- conn.commit();
- //
- //Now,doaqueryfromaslave,thedriverautomaticallypicksone
- //fromthelist--phpfensi.com
- //
- conn.setReadOnly(true);
- ResultSetrs=
- conn.createStatement().executeQuery("SELECTa,bFROMalt_table");
- .......
- }
- }
读写分离:
- jdbc:mysql:replication://master:3306,slave1:3306,slave2:3306/dbname
- Whenusingthefollowingconnectionstring:jdbc:mysql:replication://dbmaster:3306,dbslave1:3306,dbslave2:3306/dbname
- dbmasterisusedforallwriteconnectionsasexpectedanddbslave1isusedforallreadconnections,butdbslave2isneverused.Iwouldhaveexpecteddistributedreadsbetweendbslave1anddbslave2.
原理是:ReplicationDriver生成代理的connection对象,当设置这个connection.readOnly=true时,连接slave,当connection.readOnly=false时,连接master
负载均衡:
- jdbc:mysql:loadbalance://master:3306,slave1:3306,slave2:3306/dbname
- Whenusingthefollowingconnectionstring:jdbc:mysql:loadbalance://dbmaster:3306,dbslave1:3306,dbslave2:3306/dbname
- connectionsareload-balancedbetweenallthreeserversforbothreadandwriteconnections.
问题:读写分离时可能会碰到刚写完master,再马上到slave进行查询的情况,而主从复制的时候有延迟,这时怎么解决呢?有两个办法.
1.比如增加页面保存数据后马上跳转到列表页面,这时可能出不来数据,因为复制还没完成,这时可以在前台添加一些成功的提示,成功页面等进行一些页面跳转延迟处理,让服务器有时间去复制,复制延迟一般在毫秒级,而这种提示处理在秒级,所以时间上一般是足够的.
2.第1种办法可能部分场景是可行的,但是有些场景要求比较高,需要实时的,这时可以在读取的时候进行处理,强制从master中读取,可以通过注解,加参数/标识等来指定从master读取数据.