【发布时间】:2012-10-25 09:41:44
【问题描述】:
我们在 Symfony 1.4/Propel 1.4 中有一个现有项目(SNS 网站+android/Iphone 游戏)
我们在 DB 服务器(比如 DB1)上遇到了额外的负载。我们正在做 DB 优化,但作为直接的解决方案,我们决定再创建一个 DB 服务器,因为 DB2 始终是 DB1 的精确副本。目前我们只有 DB1,用于读写操作。
现在我们需要将所有读取操作移至 DB2,并保持 DB1 上的写入操作(通常在事务中)与现在一样。
进行这些更改的可能方法是什么(在没有太多停机时间的生产服务器上),如果可能的话,只需最少的代码更改。
在第一条评论后编辑
根据 J0k 提供的链接和其他一些链接,我已经在本地开发环境中完成了以下操作。
- 创建了一个测试 symfony 1.4 项目
-
更新database.yml如下
all: propel: class: sfPropelDatabase param: classname: PropelPDO dsn: 'mysql:host=localhost;dbname=wzo;' username: root password: mysql encoding: utf8 persistent: true pooling: true slaves: slave1: dsn: 'mysql:host=localhost;dbname=wzoslv;' username: root password: mysql encoding: utf8其中数据库
wzoslv是数据库wzo的精确副本,但一个测试条目的更改除外。在表odd_play第 26 行(PK)列result条目分别为WON1和WON。 -
运行 symfony 任务
php symfony propel:build-schema php symfony propel:build-model php symfony cc -
创建了一个模块并添加了以下代码:
class wzoActions extends sfActions { public function executeIndex(sfWebRequest $request) { $con_write = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_WRITE); $con_read = Propel::getConnection(OddPlayPeer::DATABASE_NAME, Propel::CONNECTION_READ); $oddPlay = OddPlayPeer::retrieveByPK(26,0,$con_write); echo "on write connection, result=".$oddPlay->getResult(); $oddPlayRead = OddPlayPeer::retrieveByPK(26,0,$con_read); echo "<br/>on Read connection, result=".$oddPlayRead->getResult(); exit; $this->setLayout('layout'); } }在浏览器中运行
http://local.sftest.com/index.php/wzo/index,输出为,在写入连接时,result=WON //正确的预期输出
on Read connection, result=WON //不正确。那应该是 WON1
我猜想在创建读/写连接时传递OddPlayPeer::DATABASE_NAME 是问题所在,但在线示例中是如何建议的。有人可以建议我在哪里犯了错误吗?
编辑:更多输入
我更新了lib\vendor\symfony\lib\plugins\sfPropelPlugin\lib\vendor\propel\Propel.php 中的调试回显,以检查它是如何返回连接的。发现它正在进入下面的if(第544-549行)
$slaveconfigs = isset(self::$configuration['datasources'][$name]['slaves']) ? self::$configuration['datasources'][$name]['slaves'] : null;
if (empty($slaveconfigs)) {
echo "inelseifif<br/>";// no slaves configured for this datasource
self::$connectionMap[$name]['slave'] = false;
return self::getConnection($name, Propel::CONNECTION_WRITE); // Recurse to get the WRITE connection
}
其中$slaveconfigs 为空,因此返回写连接。现在的问题是,为什么 slaveconfigs 是空的?
我也尝试按照old forums 中的定义编辑 sfDatabaseConfigHandler.class.php,但这样做会在某处破坏 symfony,并且不会在 Web 甚至日志中显示任何内容。
【问题讨论】:
-
你检查过the doc吗?
-
嗨@j0k,我浏览了那个 URL,但不知道如何在 symfony 中使用该信息。我根据不同链接提供的示例,使用我正在尝试的代码/配置编辑了问题。你能告诉我我在哪里做错了吗?
-
嗨@j0k,似乎没有什么对我有用。这迫使我使用核心框架文件来解决生产服务器上的紧急问题。我发布了我的解决方案。我知道这不是一个好习惯,但请你看看它并想提出一些建议。
-
这太疯狂了,文档中的官方信息不起作用?您是否也尝试过推进 1.6(在本地)?顺便说一句,您在回答中描述的是我也在网上找到的一个黑客解决方案,但它是针对旧的推进版本(我认为是 1.2)。
-
是的@j0k 它的(官方信息..)是极不可能的,我同意我一定犯了一些错误,但最终结果是:它对我不起作用。后来我恢复到推进 1.4,但该解决方案首先在 1.6 上进行了测试,并且也在 1.6 上工作。我从有问题的链接中得到了想法,但它是针对 Propel 1.2 的。关于黑客攻击,是的,它真正的黑客攻击&我提到我不推荐我的一般情况下的解决方案,但我的情况不同。生产服务器停机,堆栈持有者站在我身后寻求解决方案,在这种情况下黑客攻击是可以接受的,不是吗?现在正在寻找完美的解决方案。
标签: php symfony1 symfony-1.4 propel