zoukankan      html  css  js  c++  java
  • PHP实现的Mysql读写分离

    为什么需要读写分离?PHP实现的Mysql读写分离主要特性:

    主要是数据库压力过大的情况下的解决方案。写操作会把表锁定,而导致很多查询相继锁定而等候,导致程序处于等候状态。
    读写分离是建立在mysql的replication基础上的,master服务器仅负责写操作,slave机器仅提读操作,相对而言提高了读写性能,也可以增加mysql的承受能力。

    1. 简单的读写分离
    2. 一个主数据库,可以添加更多的只读数据库
    3. 读写分离但不用担心某些特性不支持
    4. 缺点:同时连接两个数据库
    5. 可能的bug:请反馈

    为了方便,试试建立了google的一个项目
    http://code.google.com/p/mysql-rw-php/

    PHP代码

    mysql_rw_php.class.php

    代码
    1 <?php
    2  /****************************************
    3 *** mysql-rw-php version 0.1 @ 2009-4-16
    4 *** code by hqlulu#gmail.com
    5 *** http://www.aslibra.com
    6 *** http://code.google.com/p/mysql-rw-php/
    7 *** code modify from class_mysql.php (uchome)
    8 ****************************************/
    9  class mysql_rw_php {
    10 //查询个数
    11   var $querynum = 0;
    12 //当前操作的数据库连接
    13 var $link = null;
    14 //字符集
    15 var $charset;
    16 //当前数据库
    17 var $cur_db = '';
    18 //是否存在有效的只读数据库连接
    19 var $ro_exist = false;
    20 //只读数据库连接
    21 var $link_ro = null;
    22 //读写数据库连接
    23 var $link_rw = null;
    24 function mysql_rw_php(){
    25 }
    26 function connect($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0, $halt = TRUE) {
    27 if($pconnect) {
    28 if(!$this->link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) {
    29 $halt && $this->halt('Can not connect to MySQL server');
    30 }
    31 } else {
    32 if(!$this->link = @mysql_connect($dbhost, $dbuser, $dbpw)) {
    33 $halt && $this->halt('Can not connect to MySQL server');
    34 }
    35 }
    36
    37 //只读连接失败
    38 if(!$this->link && !$halt) return false;
    39
    40 //未初始化rw时,第一个连接作为rw
    41 if($this->link_rw == null)
    42 $this->link_rw = $this->link;
    43 if($this->version() > '4.1') {
    44 if($this->charset) {
    45 @mysql_query("SET character_set_connection=$this->charset, character_set_results=$this->charset, character_set_client=binary", $this->link);
    46 }
    47 if($this->version() > '5.0.1') {
    48 @mysql_query("SET sql_mode=''", $this->link);
    49 }
    50 }
    51 if($dbname) {
    52 $this->select_db($dbname);
    53 }
    54 }
    55 //连接一个只读的mysql数据库
    56 function connect_ro($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0){
    57 if($this->link_rw == null)
    58 $this->link_rw = $this->link;
    59 $this->link = null;
    60 //不产生halt错误
    61 $this->connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect, false);
    62 if($this->link){
    63 //连接成功
    64 //echo "link ro sussess!<br>";
    65 $this->ro_exist = true;
    66 $this->link_ro = $this->link;
    67 if($this->cur_db){
    68 //如果已经选择过数据库则需要操作一次
    69 @mysql_select_db($this->cur_db, $this->link_ro);
    70 }
    71 }else{
    72 //连接失败
    73 //echo "link ro failed!<br>";
    74 $this->link = &$this->link_rw;
    75 }
    76 }
    77 //设置一系列只读数据库并且连接其中一个
    78 function set_ro_list($ro_list){
    79 if(is_array($ro_list)){
    80 //随机选择其中一个
    81 $link_ro = $ro_list[array_rand($ro_list)];
    82 $this->connect_ro($link_ro['dbhost'], $link_ro['dbuser'], $link_ro['dbpw']);
    83 }
    84 }
    85 function select_db($dbname) {
    86 //同时操作两个数据库连接
    87 $this->cur_db = $dbname;
    88 if($this->ro_exist){
    89 @mysql_select_db($dbname, $this->link_ro);
    90 }
    91 return @mysql_select_db($dbname, $this->link_rw);
    92 }
    93 function fetch_array($query, $result_type = MYSQL_ASSOC) {
    94 return mysql_fetch_array($query, $result_type);
    95 }
    96 function fetch_one_array($sql, $type = '') {
    97 $qr = $this->query($sql, $type);
    98 return $this->fetch_array($qr);
    99 }
    100 function query($sql, $type = '') {
    101 $this->link = &$this->link_rw;
    102 //判断是否select语句
    103 if($this->ro_exist && preg_match ("/^(\s*)select/i", $sql)){
    104 $this->link = &$this->link_ro;
    105 }
    106 $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
    107 'mysql_unbuffered_query' : 'mysql_query';
    108 if(!($query = $func($sql, $this->link)) && $type != 'SILENT') {
    109 $this->halt('MySQL Query Error', $sql);
    110 }
    111 $this->querynum++;
    112 return $query;
    113 }
    114 function affected_rows() {
    115 return mysql_affected_rows($this->link);
    116 }
    117 function error() {
    118 return (($this->link) ? mysql_error($this->link) : mysql_error());
    119 }
    120 function errno() {
    121 return intval(($this->link) ? mysql_errno($this->link) : mysql_errno());
    122 }
    123 function result($query, $row) {
    124 $query = @mysql_result($query, $row);
    125 return $query;
    126 }
    127 function num_rows($query) {
    128 $query = mysql_num_rows($query);
    129 return $query;
    130 }
    131 function num_fields($query) {
    132 return mysql_num_fields($query);
    133 }
    134 function free_result($query) {
    135 return mysql_free_result($query);
    136 }
    137 function insert_id() {
    138 return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
    139 }
    140 function fetch_row($query) {
    141 $query = mysql_fetch_row($query);
    142 return $query;
    143 }
    144 function fetch_fields($query) {
    145 return mysql_fetch_field($query);
    146 }
    147 function version() {
    148 return mysql_get_server_info($this->link);
    149 }
    150 function close() {
    151 return mysql_close($this->link);
    152 }
    153 function halt($message = '', $sql = '') {
    154 $dberror = $this->error();
    155 $dberrno = $this->errno();
    156 echo "<div style=\"position:absolute;font-size:11px;font-family:verdana,arial;background:#EBEBEB;padding:0.5em;\">
    157 <b>MySQL Error</b><br>
    158 <b>Message</b>: $message<br>
    159 <b>SQL</b>: $sql<br>
    160 <b>Error</b>: $dberror<br>
    161 <b>Errno.</b>: $dberrno<br>
    162 </div>";
    163 exit();
    164 }
    165 }
    166 ?>

    example.php

    代码
    <?php
    /****************************************
    *** mysql-rw-php version 0.1 @ 2009-4-16
    *** code by hqlulu#gmail.com
    *** http://www.aslibra.com
    *** http://code.google.com/p/mysql-rw-php/
    *** code modify from class_mysql.php (uchome)
    ***************************************
    */
    require_once('mysql_rw_php.class.php');
    //rw info
    $db_rw = array(
    'dbhost'=>'www.aslibra.com',
    'dbuser'=>'aslibra',
    'dbpw'=>'www.aslibra.com',
    'dbname'=>'test'
    );
    $db_ro = array(
    array(
    'dbhost'=>'www.aslibra.com:4306',
    'dbuser'=>'aslibra',
    'dbpw'=>'www.aslibra.com'
    )
    );
    $DB = new mysql_rw_php;
    //connect Master
    $DB->connect($db_rw[dbhost], $db_rw[dbuser], $db_rw[dbpw], $db_rw[dbname]);
    //Method 1: connect one server
    $DB->connect_ro($db_ro[0][dbhost], $db_ro[0][dbuser], $db_ro[0][dbpw]);
    //Method 2: connect one server from a list by rand
    $DB->set_ro_list($db_ro);
    //send to rw
    $sql = "insert into a set a='test'";
    $DB->query($sql);
    //send to ro
    $sql = "select * from a";
    $qr = $DB->query($sql);
    while($row = $DB->fetch_array($qr)){
    echo $row[a];
    }
    ?>

  • 相关阅读:
    Spring 实例化bean的三种方式
    Mybatis和Hibernate比较
    MyBatis学习总结(一)——MyBatis快速入门
    Java EE的十三个规范
    Python 测试代码覆盖率统计工具 coverage.py
    mysql explain执行计划详解
    Django模型的Field Types
    使程序在Linux下后台运行,程序运行前后台切换
    ubuntu中将本地文件上传到服务器
    Python-内置函数小结
  • 原文地址:https://www.cnblogs.com/softwaredevelop/p/1706306.html
Copyright © 2011-2022 走看看