ecshop改造读写分离

前两天配置好了mysql主从方式,今天就拿ecshop练习读写分离。以下代码仅供学习参考,不成熟的地方,还需完善。

config.php

<?php

$db_name   = "ecshop";

$prefix    = "ecs_";

$timezone    = "Europe/Berlin";

$cookie_path    = "/";

$cookie_domain    = "";

$session = "1440";

$_config = array();

//数据库主服务器设置, 支持多组服务器设置, 当设置多组服务器时, 则会随机使用某个服务器
$_config[‘master‘][1][‘dbhost‘] = "192.168.2.175:3306";
$_config[‘master‘][1][‘dbname‘] = "ecshop";
$_config[‘master‘][1][‘dbuser‘] = "dragon";
$_config[‘master‘][1][‘dbpw‘] = "loong";

/*
 *$_config[‘master‘][2][‘dbhost‘] = "";
 *...
 */

//数据库从服务器设置( slave, 只读 ), 支持多组服务器设置, 当设置多组服务器时, 系统每次随机使用
$_config[‘slave‘][1][‘dbhost‘] = "192.168.2.176:3306";
$_config[‘slave‘][1][‘dbname‘] = "ecshop";
$_config[‘slave‘][1][‘dbuser‘] = "ivan";
$_config[‘slave‘][1][‘dbpw‘] = "loong";

$_config[‘slave‘][2][‘dbhost‘] = "192.168.2.177:3306";
$_config[‘slave‘][2][‘dbname‘] = "ecshop";
$_config[‘slave‘][2][‘dbuser‘] = "ivan";
$_config[‘slave‘][2][‘dbpw‘] = "loong";

define(‘EC_CHARSET‘,‘utf-8‘);

define(‘ADMIN_PATH‘,‘admin‘);

define(‘AUTH_KEY‘, ‘this is a key‘);

define(‘OLD_AUTH_KEY‘, ‘‘);

define(‘API_TIME‘, ‘‘);

?>

初始化数据连接类

    /* 初始化数据库类
     * 如果配置了从服务器,则初始化从库类
    */
    if(count($_config[‘slave‘])) {
        require(ROOT_PATH . ‘includes/cls_mysql_slave.php‘);
        $db = new cls_mysql_slave($_config);
    }else{
        require(ROOT_PATH . ‘includes/cls_mysql.php‘);
        $db = new cls_mysql($_config);
    }  

增加cls_mysql_slave.php从库类

<?php

require(ROOT_PATH . ‘includes/cls_mysql.php‘);
class cls_mysql_slave extends cls_mysql
{
    var $slaveid = null;

    function set_config($config){
        if(!empty($this->config[‘slave‘])) {
            $this->slaveid = array_rand($this->config[‘slave‘]);
        }
        parent::set_config($config);
    }

    /* 随机分配从库连接 */
    function set_slave_config() {
        $this->settings = $this->config[‘slave‘][$this->slaveid];
        $this->settings[‘charset‘] = $this->config[‘charset‘];
        $this->settings[‘pconnect‘] = $this->config[‘pconnect‘];
    }

    function slave_connect() {
        $this->set_slave_config();
        $dbhost = $this->settings[‘dbhost‘];
        $dbuser = $this->settings[‘dbuser‘];
        $dbpw = $this->settings[‘dbpw‘];
        $dbname = $this->settings[‘dbname‘];
        $this->connect($dbhost, $dbuser, $dbpw, $dbname);

    }

    function query($sql, $type = ‘‘) {
        // 如果执行查询操作,则执行从库连接
        if($this->slaveid && strtoupper(substr($sql, 0 , 6)) == ‘SELECT‘) {
            $this->slave_connect();
        }else{
            parent::set_config($this->config);
            $dbhost = $this->settings[‘dbhost‘];
            $dbuser = $this->settings[‘dbuser‘];
            $dbpw = $this->settings[‘dbpw‘];
            $dbname = $this->settings[‘dbname‘];
            $this->connect($dbhost, $dbuser, $dbpw, $dbname);
        }
        return parent::query($sql, $type);
    }

    /* 删除失败连接*/
    function del_error_link(){
        unset($this->config[‘slave‘][$this->slaveid]);
        $this->set_config($this->config);
        $this->set_slave_config();
        $dbhost = $this->settings[‘dbhost‘];
        $dbuser = $this->settings[‘dbuser‘];
        $dbpw = $this->settings[‘dbpw‘];
        $dbname = $this->settings[‘dbname‘];
        $this->connect($dbhost, $dbuser, $dbpw, $dbname);
    }

}

cls_mysql.php文件类修改

<?php

if (!defined(‘IN_ECS‘))
{
    die(‘Hacking attempt‘);
}

class cls_mysql
{
    var $link_id    = NULL;

    var $settings   = array();

    var $queryCount = 0;
    var $linkCount = 0;
    var $queryTime  = ‘‘;
    var $queryLog   = array();

    var $max_cache_time = 300; // 最大的缓存时间,以秒为单位

    var $cache_data_dir = ‘temp/query_caches/‘;
    var $root_path      = ‘‘;

    var $error_message  = array();
    var $platform       = ‘‘;
    var $version        = ‘‘;
    var $dbhash         = ‘‘;
    var $starttime      = 0;
    var $timeline       = 0;
    var $timezone       = 0;

    var $mysql_config_cache_file_time = 0;

    var $mysql_disable_cache_tables = array(); // 不允许被缓存的表,遇到将不会进行缓存
    var $config = array();

    function __construct($config, $charset = ‘utf8‘, $pconnect = 0, $quiet = 0)
    {
        $this->cls_mysql($config, $charset, $pconnect, $quiet);
    }

    function cls_mysql($config, $charset = ‘utf8‘, $pconnect = 0, $quiet = 0)
    {
        if(!empty($config)) {
            $config[‘charset‘] = $charset;
            $config[‘pconnect‘] = $pconnect;
            $this->config = $config;
        }

        if (defined(‘EC_CHARSET‘))
        {
            $charset = strtolower(str_replace(‘-‘, ‘‘, EC_CHARSET));
        }

        if (defined(‘ROOT_PATH‘) && !$this->root_path)
        {
            $this->root_path = ROOT_PATH;
        }

        $this->set_config($this->config);

        if ($quiet)
        {
            $dbhost = $this->settings[‘dbhost‘];
            $dbuser = $this->settings[‘dbuser‘];
            $dbpw = $this->settings[‘dbpw‘];
            $dbname = $this->settings[‘dbname‘];
            $this->connect($dbhost, $dbuser, $dbpw, $dbname, $charset, $pconnect, $quiet);
        }
    }

    //随机分配数据库连接
    function set_config($config) {
        $sid = array_rand($config[‘master‘]);
        $settings = $config[‘master‘][$sid];
        $settings[‘sid‘] = $sid;
        $settings[‘charset‘] = $this->config[‘charset‘];
        $settings[‘pconnect‘] = $this->config[‘pconnect‘];
        $this->settings = $settings;
    }

    function connect($dbhost, $dbuser, $dbpw, $dbname = ‘‘, $charset = ‘utf8‘, $pconnect = 0, $quiet = 0)
    {
        if ($pconnect)
        {
            if (!($this->link_id = @mysql_pconnect($dbhost, $dbuser, $dbpw)))
            {
                if (!$quiet)
                {
                    $this->ErrorMsg("Can‘t pConnect MySQL Server!");
                }

                return false;
            }
        }
        else
        {
            if (PHP_VERSION >= ‘4.2‘)
            {
                $this->link_id = @mysql_connect($dbhost, $dbuser, $dbpw, true);
            }
            else
            {
                $this->link_id = @mysql_connect($dbhost, $dbuser, $dbpw);

                mt_srand((double)microtime() * 1000000); // 对 PHP 4.2 以下的版本进行随机数函数的初始化工作
            }
            if (!$this->link_id)
            {
                if (!$quiet)
                {
                    //连接超过10次,中断连接,抛出错误
                    if($this->linkCount>9){
                        $this->ErrorMsg("Can‘t Connect MySQL Server!");
                    }
                    $this->linkCount++;
                    $this->del_error_link();
                }

                return false;
            }
        }

        $this->dbhash  = md5($this->root_path . $dbhost . $dbuser . $dbpw . $dbname);
        $this->version = mysql_get_server_info($this->link_id);

        /* 如果mysql 版本是 4.1+ 以上,需要对字符集进行初始化 */
        if ($this->version > ‘4.1‘)
        {
            if ($charset != ‘latin1‘)
            {
                mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->link_id);
            }
            if ($this->version > ‘5.0.1‘)
            {
                mysql_query("SET sql_mode=‘‘", $this->link_id);
            }
        }

        $sqlcache_config_file = $this->root_path . $this->cache_data_dir . ‘sqlcache_config_file_‘ . $this->dbhash . ‘.php‘;

        @include($sqlcache_config_file);

        $this->starttime = time();

        if ($this->max_cache_time && $this->starttime > $this->mysql_config_cache_file_time + $this->max_cache_time)
        {
            if ($dbhost != ‘.‘)
            {
                $result = mysql_query("SHOW VARIABLES LIKE ‘basedir‘", $this->link_id);
                $row    = mysql_fetch_assoc($result);
                if (!empty($row[‘Value‘]{1}) && $row[‘Value‘]{1} == ‘:‘ && !empty($row[‘Value‘]{2}) && $row[‘Value‘]{2} == "\\")
                {
                    $this->platform = ‘WINDOWS‘;
                }
                else
                {
                    $this->platform = ‘OTHER‘;
                }
            }
            else
            {
                $this->platform = ‘WINDOWS‘;
            }

            if ($this->platform == ‘OTHER‘ &&
                ($dbhost != ‘.‘ && strtolower($dbhost) != ‘localhost:3306‘ && $dbhost != ‘127.0.0.1:3306‘) ||
                (PHP_VERSION >= ‘5.1‘ && date_default_timezone_get() == ‘UTC‘))
            {
                $result = mysql_query("SELECT UNIX_TIMESTAMP() AS timeline, UNIX_TIMESTAMP(‘" . date(‘Y-m-d H:i:s‘, $this->starttime) . "‘) AS timezone", $this->link_id);
                $row    = mysql_fetch_assoc($result);

                if ($dbhost != ‘.‘ && strtolower($dbhost) != ‘localhost:3306‘ && $dbhost != ‘127.0.0.1:3306‘)
                {
                    $this->timeline = $this->starttime - $row[‘timeline‘];
                }

                if (PHP_VERSION >= ‘5.1‘ && date_default_timezone_get() == ‘UTC‘)
                {
                    $this->timezone = $this->starttime - $row[‘timezone‘];
                }
            }

            $content = ‘<‘ . "?php\r\n" .
                       ‘$this->mysql_config_cache_file_time = ‘ . $this->starttime . ";\r\n" .
                       ‘$this->timeline = ‘ . $this->timeline . ";\r\n" .
                       ‘$this->timezone = ‘ . $this->timezone . ";\r\n" .
                       ‘$this->platform = ‘ . "‘" . $this->platform . "‘;\r\n?" . ‘>‘;

            @file_put_contents($sqlcache_config_file, $content);
        }

        /* 选择数据库 */
        if ($dbname)
        {
            if (mysql_select_db($dbname, $this->link_id) === false )
            {
                if (!$quiet)
                {
                    $this->ErrorMsg("Can‘t select MySQL database!");
                }

                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return true;
        }
    }

    ......

    /* 删除失败连接*/
    function del_error_link(){
        unset($this->config[‘master‘][$this->settings[‘sid‘]]);
        $this->set_config($this->config);
        $dbhost = $this->settings[‘dbhost‘];
        $dbuser = $this->settings[‘dbuser‘];
        $dbpw = $this->settings[‘dbpw‘];
        $dbname = $this->settings[‘dbname‘];
        $this->connect($dbhost, $dbuser, $dbpw, $dbname);
    }
}

转载:http://blog.csdn.net/very_loong/article/details/7999895

时间: 2024-10-11 06:25:03

ecshop改造读写分离的相关文章

ecshop改造读写分离配置与改造

前两天配置好了mysql主从方式,今天就拿ecshop练习读写分离.以下代码仅供学习参考,不成熟的地方,还需完善. <?php $db_name = "ecshop"; $prefix = "ecs_"; $timezone = "Europe/Berlin"; $cookie_path = "/"; $cookie_domain = ""; $session = "1440";

spring-data-redis读写分离

在对Redis进行性能优化时,一直想对Redis进行读写分离.但由于项目底层采用spring-data-redis对redis进行操作,参考spring官网却发现spring-data-redis目前(1.7.0.RELEASE)及以前的版本并不支持读写分离.  一.源码分析 spring-data-redis中关于JedisConnectionFactory的配置如下: <?xml version="1.0" encoding="UTF-8"?> &l

EF通用数据层封装类(支持读写分离,一主多从)

浅谈orm 记得四年前在学校第一次接触到 Ling to Sql,那时候瞬间发现不用手写sql语句是多么的方便,后面慢慢的接触了许多orm框架,像 EF,Dapper,Hibernate,ServiceStack.OrmLite 等.当然每种orm都有各自的优势,也有不足的地方.园子里也有很多大神开源了他们写的orm,如SqlSugar,Chloe.ORM,CYQ.Data 等.先不说这些开源的orm使用度怎么样,我觉得起码从开源的精神上就很可嘉了,我也曾下载过这几位大神的源码进行学习. 所有o

SqlServer 并发系列之读写分离

数据库处理高并发两种方式 垂直和水平 区分 垂直区分[分布式数据库]: 按模块独立出单独数据库. 缺点:对系统各个模块设计要较高要求,高内聚低耦合,改造难度较大. 同时如果数据达到一个新的临界点,还是会存在访问性能低下的可能,比如一个订单数据库,订单数量达到1000万单. 水平区分[读写分离]: 剑圣分身的方式,分为 主数据库(真身)和多个查询数据库(镜像),主数据库承担 增删改和实时性查询 功能, 查询服务器承担带条件的大数据量的查询. 读写分离好处1.将读和写操作分离到不同的数据库服务器上.

SQL的读写分离与负载均衡问题设想。

首先,我们可以了解一下,SQL的读写分离的工作方式,如下图所示: 总得来说,三种方案,现阶段来说,都是单节点写,多节点读.SQL 2012 的Always On还实现了读负载均衡,但方案投入相对来说较大. 所以用得最多的应还是第二种方案,表级同步,数据差异几秒.但有个问题,当只读的节点多了时,要如何实现负载均衡? 真正的负载均衡,需要计算的东西太多,要计算连接线程数,要计算CPU使用率等,而这一切都需要你在程序中体现.实现难度相对来说会好大! 除非你用第三方服务软件来实现,SQL现阶段来说,这样

读写分离提高 SQL Server 并发性

转自:http://www.canway.net/Lists/CanwayOriginalArticels/DispForm.aspx?ID=476 在一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡.遗憾的是,SQL Server 的所有版本,包括2012年3月发布的SQL Server 2012,也未提供该功能. 扩展单台SQL Server 服务器,解决性能瓶颈,有两种方法: 一.分

SQL Server数据库读写分离提高并发性

在一些大型的网站或者应用中,单台的SQL Server 服务器可能难以支撑非常大的访问压力.很多人在这时候,第一个想到的就是一个解决性能问题的利器——负载均衡.遗憾的是,SQL Server 的所有版本,包括2012年3月发布的SQL Server 2012,也未提供该功能. 扩展单台SQL Server 服务器,解决性能瓶颈,有两种方法: 一.分布式数据库.扩展和分布数据库到多台服务器,由多台服务器分布存储不同的数据,通过将数据和访问压力分布到多台服务器来解决性能瓶颈.以一个大型电子商务网站数

mysql高可用架构方案之二(keepalived+lvs+读写分离+负载均衡)

mysql主从复制与lvs+keepalived实现负载高可用 目录 1.前言    4 2.原理    4 2.1.概要介绍    4 2.2.工作原理    4 2.3.实际作用    4 3方案    4 3.1.环境    4 3.2.架构图    5 3.3.设计原理    6 4.相关软件安装    6 4.配置mysql的主从    7 5.通过lvs+keepalived实现负载与热备,并实现读写分离    8 1.前言 最近研究了下高可用的东西,这里总结一下mysql主从复制读

MMM架构实现MySQL高可用读写分离(进阶版,包含Amoeba)

前两天逛博客偶然发现了某大神写的关于MMM的文章,看完就迫不及待的自己试了一下,大神写的很顺畅,以为自己也能操作的很顺畅,但是实际情况是手脚太不麻利,碰到很多坑,如果大神的文章是"平地起高楼",那我这篇则是"平房起别墅",因为我生产环境中已经有两台Mysql做双主同步,这篇文章说的是如何改造升级现有架构! 环境介绍: IP 操作系统 数据库 软件 角色/VIP 192.168.6.109 CentOS7.2 Mysql5.6-34 mysql-mmm2.2.1-15