数据库配置读写分离后如何方便地从主库中读取数据

浏览:7988 发布日期:2015/10/12 分类:站务建议 关键字: 主从分离 主库读取 master slave
最近项目在数据库层面上快达到瓶颈的情况下,优先启用了数据库主从分离配置。

在项止中启用数据库主从配置、读写分离后发现了一些问题,经过漫长的分析,测试最终发现是有一些业务处理中,在向数据库插入数据之后立即需要从数据库读取相关的信息导致,在调用查询方法时数据库主从还未同步完成。

当然,出现了类似问题一般是由于业务逻辑书写不规范导致,最直接的方式应该是在将某些数据存入数据库后如果需要其中的数据可以直接从当前方法中获得。但凡事必然有例外~

这时就出现了一个需求,可不可以在这些例外的情况下让程序直接从主库中读取呢?

在翻阅了thinkphp官方文档,查看了数据库配置及相应的模型层方法后发现当前框架中并未提供相应的方法。

所以自己在核心代码中做了一些调整如下(ThinkPHP v3.2.3版本):

修改ThinkPHP->Library->Think->Model.class.php

1、第62行    // 链操作方法列表
    protected $methods          =   array('strict','order','alias','having','group','lock','distinct','auto','filter','validate','result','token','index','force','master');
在array中加入了最后一个 master 值,使连贯制作时支持 master

2、文件末尾加入新方法    /**
     * 是否从主库读取数据
     * @param string $type
     * @return \Think\Model
     * @auth byron sampson
     */
    public function master($type=false){
        // 分布式数据库支持
        $deploy    = C('DB_DEPLOY_TYPE');
        // 如果手动指定主库读取,并且开启了分布式数据库支持
        if ($type && !empty($deploy)){
    
            // 分布式数据库配置解析
            $_config['username']    =   explode(',',C('DB_USER'));
            $_config['password']    =   explode(',',C('DB_PWD'));
            $_config['hostname']    =   explode(',',C('DB_HOST'));
            $_config['hostport']    =   explode(',',C('DB_PORT'));
            $_config['database']    =   explode(',',C('DB_NAME'));
            $_config['charset']     =   explode(',',C('DB_CHARSET'));
                
            $m     =   floor(mt_rand(0,C('DB_MASTER_NUM')-1));
                
            $db_master  =   array(
                    'DB_TYPE'    =>  C('DB_TYPE'),
                    'DB_USER'    =>  isset($_config['username'][$m])?$_config['username'][$m]:$_config['username'][0],
                    'DB_PWD'    =>  isset($_config['password'][$m])?$_config['password'][$m]:$_config['password'][0],
                    'DB_HOST'    =>  isset($_config['hostname'][$m])?$_config['hostname'][$m]:$_config['hostname'][0],
                    'DB_PORT'    =>  isset($_config['hostport'][$m])?$_config['hostport'][$m]:$_config['hostport'][0],
                    'DB_NAME'    =>  isset($_config['database'][$m])?$_config['database'][$m]:$_config['database'][0],
                    'DB_CHARSET'   =>  isset($_config['charset'][$m])?$_config['charset'][$m]:$_config['charset'][0],
            );
    
            $this->db(0, $db_master, true);
        }
        return $this;
    }
即可,调用方式为 M()->master(true)->find();

3、测试结果        $user = M('Member')->master(true)->find();
        dump($user);


结论:这样修改即解决了问题,但在核心框架升级时需要注意不要被覆盖。也希望官方在后续的版本中能解决该问题。


最后附上修改完的Model.class.php文件

附件 Model.class.zip ( 14.13 KB 下载:92 次 )

最佳答案
评论( 相关
后面还有条评论,点击查看>>