如何为大容量站点优化数据库架构?


28

问题不是关于特定的Mysql配置项目,而是关于处理多个数据库,将读取和写入拆分为多个数据库服务器(master + master)?主+多个奴隶?

人们在哪些方面拥有最佳的经验,是否有实现该目标的示例?

Answers:


18

我们在MySQL集群方面拥有相当丰富的经验-Percona在突破复杂配置的界限时曾与我们合作过很多次。

Magento可以原生处理只读从站吗

Magento的本身能够分裂关闭读取/写入到不同的数据库服务器(少数破碎释放外,例如EE 1.11。) -让你偏移select负载到附加(或多个)服务器(一个或多个); 并将所有update/write查询转发到单个主服务器。

我什么时候应该做

这是一个更合适的问题。借助像MageStack这样的专用Magento操作系统,内置的服务器端高级缓存技术变得可用并易于使用(例如Varnish前端缓存和Redis后端缓存)变得越来越普遍。

从历史上看,Magento从未受到MySQL的束缚-而是受PHP束缚。但是随着Varnish和Full Page Caching(FPC)的使用更加频繁,重复任务(类别/产品负载,频繁搜索)的负担突然被吸收了,PHP的负担也减轻了。实际上,只有在最初生成内容或完成不可缓存的场景(添加到购物车,订单完成等)时才真正起作用。出于解释的目的,我们故意忽略行政负担

这里这里都可以看出,MySQL一直不是大多数零售商关注的领域。但是,如果您每小时要处理数百个订单,而不是一位或两位数,那么它将很快成为优化的领域。

最终适用于较小的商店(每日唯一身份访问者少于2万5千)

您的工作将集中在仅找到合适的主机上,该主机可以从偏移量上建议正确的硬件,并且以最适合您商店的方式配置了机器,您的工作会更好。不要浪费时间追求主/从或主/主配置-这不会产生任何性能优势,最终将需要持续关注和高级MySQL知识。

最终,与MySQL优化相比,硬件的大小确定和选择将发挥更大的作用。

但是对于较大的商店

随着您的商店开始发展,随着重复完成复杂inserts和复杂的任务,转换或事务负载将成为更大的负担updates。每个新订单的增加将触发目录库存的减少,来自支付网关的回调以及来自EPOS / ERP系统的更新。将其与相应产品/类别的关联缓存清除结合使用,您很快就会发现MySQL的负载成比例地增加。

多主服务器永远不是我们推荐或认为可行的解决方案,但是主/从服务器可以通过将读取负载转移到辅助/三级节点上来产生收益(我们强调,在企业级存储中)。

但是我还是想做

首先配置您的奴隶。我们是Percona实用程序和MySQL分支的大力拥护者-它们是用于对现有数据库进行备份的理想工具-innobackupex。有一个很好的写在这里

在主人

替换$ TIMESTAMP或制表符完成。

mysql
> GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'$slaveip' IDENTIFIED BY '$slavepass';
> quit;
innobackupex --user=username --password=password /path/to/backupdir
innobackupex --user=username --password=password /
       --apply-log /path/to/backupdir/$TIMESTAMP/

rsync -avprP -e ssh /path/to/backupdir/$TIMESTAMP TheSlave:/path/to/mysql/
scp /etc/mysql/my.cnf TheSlave:/etc/mysql/my.cnf

在奴隶上

/etc/init.d/mysql stop
mv /path/to/mysql/datadir /path/to/mysql/datadir_bak
mv /path/to/mysql/$TIMESTAMP /path/to/mysql/datadir
chown -R mysql:mysql /path/to/mysql/datadir
sed -i 's#server-id=1#server-id=2#g' /etc/mysql/my.cnf
/etc/init.d/mysql start
cat /var/lib/mysql/xtrabackup_binlog_info
> TheMaster-bin.000001     481

mysql
> CHANGE MASTER TO MASTER_HOST='$masterip', MASTER_USER='repl', MASTER_PASSWORD='$slavepass', MASTER_LOG_FILE='TheMaster-bin.000001', MASTER_LOG_POS=481;
> START SLAVE;

然后,在实践中,一旦您的从属服务器开始运行,只需完成几行代码即可。

./app/etc/local.xml

<default_read>
  <connection>
    <use/>
    <host><![CDATA[host]]></host>
    <username><![CDATA[username]]></username>
    <password><![CDATA[password]]></password>
    <dbname><![CDATA[dbname]]></dbname>
    <type>pdo_mysql</type>
    <model>mysql4</model>
    <initStatements>SET NAMES utf8</initStatements>
    <active>1</active>
  </connection>
</default_read>

资料来源


“从历史上看,Magento从未被MySQL所束缚-而是被PHP所束缚。” 我不确定您在说什么Magento,但是EAV一直是性能问题。:)
B00MER

1
好吧,我指的是我们管理的400多个Magento服务器...作为大多数规则,在考虑MySQL之前还有很多其他瓶颈。实际上,一个典型的例子是我们在12月期间的一位客户。每小时有15,000个唯一身份访问者,可在单个服务器设置(32核,64GB RAM)上每小时处理200个订单。对于这个问题的典型读者来说,即使是这一卷,他们也极不可能这样做。因此,在他们将要遇到的流量和事务级别上,MySQL并不是瓶颈。
Ben Lessani-Sonassi

1
@布兰登。我只是想补充。我不否认调整MySQL不是必需的-显然是必要的。但是,在您实际达到某个临界点之前,不需要配置主/主或主/从设置来提高性能-这相当高。同样,尝试执行此操作很可能导致性能瓶颈或冒险数据完整性。
Ben Lessani-Sonassi

5

通常,Magento是受CPU约束的,而不是受数据库约束的,并且大多数CPU活动都可以被缓存,这就是为什么您会找到很多有关varnish / nginx设置的教程的原因。您还可以将管理员移至单独的webnode,如此处所述

对于一般的健壮性来说,绝对物有所值的是托管的MySQL服务。

我只有Amazon RDS的经验,但是它们可以自动执行故障转移,备份,升级,向上/向下缩放以及创建只读副本。因此,您可以拥有一个具有自动故障转移功能的高可用性主节点-Amazon使用自定义二进制日志复制来使从属服务器保持同步,故障转移通常花费不到2分钟的时间,然后您可以创建尽可能多的只读副本需要扩展以满足您的报告/集成需求。

我研究了拆分读取/写入,这在Magento的体系结构中非常可行,但是数据库在我的用例中并不是瓶颈。我强烈建议您使用xhprof / xhgui之类的性能分析,而不要猜测需要优化的内容。剖析的第一个规则是测量。


请,我们不是在这里建立一个书签网站,通过链接回答问题。在此处包括答案的基本部分,并提供链接以供参考。
13年

@ j0k提供链接供参考,答案独立存在-如果您不同意,请更具体。
拉尔夫·蒂斯

是的,至少您的答案比另一个答案要好。我的意思是,OP可能需要更多有关配置方面的技术知识,为什么还不需要架构架构等……即使您的经验很棒!
13年

5

我没有任何生产经验,但是经过一番挖掘,我找到了这篇文章。在本文中,有人说明了如何为Magento设置主从复制,因此这可能对您有用。

最重要的一点:

/app/etc/local.xml

<default_setup>
    <connection>
        <host><![CDATA[Master-host]]></host>
        <username><![CDATA[user]]></username>
        <password><![CDATA[pass]]></password>
        <dbname><![CDATA[magentodb]]></dbname>
        <active>1</active>
    </connection>
</default_setup>
<default_read>
    <connection>
        <use/>
        <host><![CDATA[Slave-host]]></host>
        <username><![CDATA[user]]></username>
        <password><![CDATA[pass]]></password>
        <dbname><![CDATA[magento]]></dbname>
        <type>pdo_mysql</type>
        <model>mysql4</model>
        <initStatements>SET NAMES utf8</initStatements>
        <active>1</active>
    </connection>
</default_read> 

主MySQL服务器(/etc/mysql/my.cnf)的配置在文件中添加以下内容:

[mysqld]
server-id       = 1
log_bin         = /var/log/mysql/mysql-bin.log
expire_logs_days    = 10
max_binlog_size     = 100M
binlog_do_db        = magento_demo
binlog_ignore_db    = mysql 

从MySQL服务器(/etc/mysql/my.cnf)的配置在文件中添加以下内容:

[mysqld]
server-id=2
log-bin=mysql-bin
master-host=192.168.1.2
master-user=username
master-password=111111
master-port=3306
replicate-do-db=magento_demo
replicate-ignore-db=mysql
master-connect-retry=60 

之后重新启动两个MySQL服务器


1
孤独的链接被认为是一个糟糕的答案,因为它本身是毫无意义的,并且不能保证目标资源在将来仍然存在最好在这里包括答案的基本部分,并提供链接以供参考。
13年

@ j0k,按要求完成;)
肯尼

3

一种想法是,您可以使用dns round-robin将目录读取拆分为从属服务器。

因此,在MySQL中设置普通的master-> slave复制。

然后在您的Magento设置中,您可以配置目录以从循环配置的dns主机读取数据。写入将保留在您的主数据库中。

您可以在 app/etc/local.xml

<catalog_read_setup>
   <connection>
      <host><![CDATA[round.robbin.dns.host]]></host>
      <username><![CDATA[USERNAME]]></username>
      <password><![CDATA[password]]></password>
      <dbname><![CDATA[DATABASE]]></dbname>
      <initStatements><![CDATA[SET NAMES utf8]]></initStatements>
      <model><![CDATA[mysql4]]></model>
      <type><![CDATA[pdo_mysql]]></type>
      <pdoType><![CDATA[]]></pdoType>
      <active>1</active>
   </connection>
</catalog_read_setup>
<catalog_read>
   <connection>
     <use>catalog_read_setup</use>
   </connection>
 </catalog_read>

您可以以相同的方式重定向任何核心(和第三方)模块以使用不同的MySQL实例。


1
DNS轮询不是任何解决方案。MySQL代理或HAProxy是平衡MySQL读取负载的更为复杂的解决方案。
Ben Lessani-Sonassi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.