【问题标题】:Doctrine 2 Master / Slave connectionsDoctrine 2 主/从连接
【发布时间】:2011-06-22 19:18:15
【问题描述】:

我正在研究设置 Doctrine 2 以使用 MySQL 的主/从连接的不同方法。设置将是一个主数据库和多个从属数据库。所有 SELECT 语句都应该来自一个随机的活动从属,并且任何 UPDATE、INSERT、DELETE 语句都将始终委托给主连接。

有没有人以这种方式设置 Doctine 2 或对如何处理它有任何想法?

【问题讨论】:

    标签: doctrine-orm


    【解决方案1】:

    据我所知,Doctrine 2 中没有对此的内置支持。

    似乎(至少使用 mysql),这个问题最终将在别处得到解决。在mysql_proxy 中,或者通过最近与mysqlnd(php 的mysql 本机驱动程序扩展)的一些工作

    由于它们都没有准备好进入黄金时段(尽管 mysql_proxy 可能是),不幸的是,你唯一的直接选择是开始研究 Doctrine DBAL,并扩展内置类以巧妙地处理事情——这意味着它可能最好检测当前请求是否已完成任何写入操作,然后强制任何后续读取使用主服务器,避免任何与复制延迟相关的问题。

    希望我们能在接下来的 6 到 12 个月内看到 Doctrine 团队提供更正式的解决方案。但如果你现在需要它,那就是 DIY,AFAIK。

    【讨论】:

    • 最后我选择实现我们自己的 Connection 包装器,它似乎已经成功了。我希望 D2 在以后的版本中正式开发该功能。
    【解决方案2】:

    Doctrine2 现在在 \Doctrine\DBAL\Connections 命名空间中有一个 MasterSlaveConnection。

    编辑: 除非这篇文章不起作用,否则不要阅读以下内容

    不再需要重载器,dbal 配置将自行获取从站。例如

    connections:
                default:
                    driver:   %database_driver%
                    host:     %database_host%
                    dbname:   %database_name%
                    user:     %database_user%
                    password: %database_password%
                    slaves:
                        slave1:
                            host:     %database_slave1%
                            dbname:   %database_name%
                            user:     %database_user%
                            password: %database_password%
    

    如果上面的方法不行,试试这个

    一些简单的事情,只需在每个主机之间放置管道(|)

    default:
                    driver:   %database_driver%
                    host:     %database_host%|%database_slave%|%database_slave2%
                    port:     3306
                    dbname:   %database_name%
                    user:     %database_user%
                    password: %database_password%
                    wrapper_class: \Foo\Bar\Symfony\Doctrine\Connections\MasterSlave
    
    
    <?php
    namespace Foo\Bar\Symfony\Doctrine\Connections;
    use \Doctrine\DBAL\Connections\MasterSlaveConnection;
    use Doctrine\DBAL\Connection,
            Doctrine\DBAL\Driver,
            Doctrine\DBAL\Configuration,
            Doctrine\Common\EventManager,
            Doctrine\DBAL\Event\ConnectionEventArgs,
            Doctrine\DBAL\Events,
            Doctrine\DBAL\Cache\QueryCacheProfile;
    
    class MasterSlave extends MasterSlaveConnection
    {
            public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null)
            {
                    $tempParams = array(
                                    'master' => array()
                                    , 'slaves' => array()
                                    , 'driver' => $params['driver']
                                    );
                    $hosts = explode('|', $params['host']);
                    unset($params['host']);
                    foreach($hosts as $num => $host)
                    {
                            $params['host'] = $host;
                            if($num == 0)
                            {
                                    $tempParams['master'] = $params;
                            }
                            else
                            {
                                    $tempParams['slaves'][] = $params;
                            }
                    }
    
                    if(!isset($tempParams['master']['driver']))
                            $tempParams['master']['driver'] = "pdo_mysql";
    
                    foreach($tempParams['slaves'] as $k => $slave)
                    {
                            if(!isset($slave['driver']))
                                    $tempParams['slaves'][$k]['driver'] = "pdo_mysql";
                    }
                    parent::__construct($tempParams, $driver, $config, $eventManager);
            }
    
            public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
            {
                    try
                    {
                            return parent::executeQuery($query, $params, $types, $qcp);
                    }
                    catch(\Exception $e)
                    {
                            $logger = new \Uelib\Core\Logger();
                            $message = $e->getMessage() . "\nSql: " . $query . "\nParams: \n" . print_r($params, true);
                            $logger->log($message);
                            throw $e;
                    }
            }
    }
    

    【讨论】:

    • 唯一的问题是,我不知道如何让 symfony 与需要的配置配合得很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2014-01-05
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多