我们可以在MySQL 5.0 Replication中做什么来解决带宽问题?


18

我正在开发一个在客户端PC(Win)上运行的应用程序,该PC配置有MySQL服务器5.1实例,该实例将充当远程主服务器的只读从属服务器。远程主服务器有几十个模式,但是每个客户端只需要一个模式,因此我在my.ini中提供了copy-do-db设置,以仅复制客户端所需的模式。复制是可行的,但是当我们的客户进入仅通过3G无线访问互联网(按数据用量收费)的地区时,他们很快就会超出数据计划的限制,并遇到了昂贵的问题。

据我了解,MySQL将所有模式的所有事务都写入单个binlog文件中,这意味着每个客户端必须下载在主服务器上的每个模式上执行的所有事务,然后一旦下载,则对每个复制应用数据库过滤器- 客户端的my.ini文件中的do-db设置。

为了最大程度地减少这种低效率,我采用了slave_compressed_protocol = 1设置,该设置似乎将传输的数据减少了50%,但仍然导致我们的客户的数据流量迅速超过了3G账单。

我无法想象我是唯一面对这个问题的人,所以我敢肯定,通过设置x = y,我将获得大量有关如何实现这一目标的答案。但是,我找不到有关这种设置的任何文档,也找不到推荐的方法。

到目前为止,这是我对可能的解决方案的想法,请提供反馈或替代路线:


  1. 为每个模式设置“代理”从属(在不同的框上,或在具有不同的MySQL实例/端口的同一框上)
  2. 配置代理从属服务器,使其仅复制客户端希望复制的一个数据库。
  3. 将客户端的MySQL实例配置为相应代理从属的从属。

应该导致客户端仅提取其架构的binlog数据。不利的一面(据我所知)是,它极大地增加了我们设置的复杂性,可能使其更加脆弱。

有什么想法吗?这种方法还能行吗?

注意,我们正在RedHat上运行MySQL 5.0服务器,但是如果它可以解决的话,我们可以升级到5.5。


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特

Answers:


10

建议1:使用分发主数据

分发主控是mysql从属服务器,已启用log-bin,启用log-slave-updates,并且仅包含具有BLACKHOLE Storage Engine的表。您可以将plicate-do-db应用于分发主服务器,并在分发主服务器上创建二进制日志,该分发日志仅包含您要进行二进制记录的数据库模式。这样,您可以减少来自分发主服务器的传出二进制日志的大小。

您可以按以下方式设置分发主服务器:

  1. mysql使用--no-data选项转储您的数据库以生成仅模式转储。
  2. 将仅模式的转储加载到分发主机。
  3. 将分发母版中的每个表转换为BLACKHOLE存储引擎。
  4. 使用真实数据从主数据库设置复制到分发主数据库。
  5. 将Replication-Do-db选项添加到分发主服务器的/etc/my.cnf中。

对于第2步和第3步,您还可以编辑仅模式转储,并将ENGINE = MyISAM和ENGINE = InnoDB替换为ENGINE = BLACKHOLE,然后将已编辑的仅模式转储加载到Distribution Master中。

仅在第3步中,如果要在Distribution Master中编写所有MyISAM和InnoDB表到BLACKHOLE的转换的脚本,请运行以下查询并将其输出到文本文件:

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name', ENGINE=BLACKHOLE;') BlackholeConversion FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql') AND engine <> 'BLACKHOLE'" > BlackholeMaker.sql

编写脚本将表转换为BLACKHOLE存储引擎的脚本的另一个好处是,MEMORY存储引擎表也​​将转换。虽然MEMORY存储引擎表不占用数据存储的磁盘空间,但会占用内存。将MEMORY表转换为BLACKHOLE将使分发主数据库中的内存保持整洁。

只要您不将任何DDL发送到分发主机,就可以传输所需的任何DML(INSERT,UPDATE,DELETE),然后再让客户端仅复制所需的DB信息。

我已经在另一个StackExchange网站上写了一篇文章,讨论如何使用发行版母版

建议2:使用较小的二进制日志和中继日志

如果将max_binlog_size设置为小得离谱,那么二进制日志可以收集并以较小的块发送出去。还有一个单独的选项可以设置中继日志的大小max_relay_log_size。如果max_relay_log_size = 0,它将默认设置为max_binlog_size。

建议#3:使用半同步复制(仅适用于MySQL 5.5)

将您的主数据库和多个分发主服务器设置为MySQL 5.5。启用半同步复制,以便主数据库可以快速将二进制日志发送到分发主数据库。如果所有从属服务器都是分发主服务器,则可能不需要半同步复制或MySQL 5.5。如果除分发主服务器以外的任何从服务器具有用于报告,高可用性,被动备用或备份目的的真实数据,则将MySQL 5.5与半同步复制一起使用。

建议4:使用基于语句的二进制日志记录而不是基于行的日志记录

如果SQL语句更新表中的多行,则基于语句的二进制日志记录(SBBL)仅存储该SQL语句。使用基于行的二进制日志记录(RBBL)的同一SQL语句将实际记录每行的行更改。显而易见,传输SQL语句将节省执行SBBL而不是RBBL的二进制日志的空间。

另一个问题是将RBBL与copy-do-db结合使用,其中表名前面带有数据库。这对于从属者(尤其是分发主服务器)来说不是很好。因此,请确保所有DML在任何表名之前都没有数据库和句点。


有趣的想法@RolandoMySQLDBA,建议1听起来就像我试图用“代理”从属设置描述的那样。但是,DDL是我需要与奴隶相关的东西。我想我可以在应用程序层中处理此问题,但是如果可以避免,则宁愿不行。我可以看到建议2如何解决流量/速度问题,但是不确定如何帮助网络带宽使用。对于建议3,您能为我详细说明一下吗?我认为当您需要知道至少一个从属获得更新时,半同步将更适合“安全”复制。很棒的建议顺便说一句!
亚伯兰

@Abram请确保分发主服务器永远不会收到InnoDB或MyISAM表,以将磁盘I / O限制为binlog管理!
RolandoMySQLDBA 2011年

我目前正在设置一个测试环境,其中将有多个MySQL 5.5实例作为分发主服务器在同一盒(差异端口)上运行。每个DM将具有来自主数据库的相应DB的黑洞版本。然后,我将设置一些挂在DM上的远程从站。我将返回结果,这听起来是最好的选择,尽管出于某些原因,我急于运行多个MySQL实例。也许是亚马逊的微型云服务器的工作。
亚伯兰

2
@Abram,您应该将skip-innodb添加到/etc/my.cnf。您不能禁用MyISAM,因为它是库存存储引擎。如果分发主服务器上的任何表最终都是MyISAM,则必须手动执行ALTER TABLE tblname ENGINE = BLACKHOLE。也许可以通过以下查询创建脚本:SELECT CONCAT('ALTER TABLE',table_schema,'。',table_name,'ENGINE = BLACKHOLE;')AlterCommand FROM information_schema.tables WHERE engine ='MyISAM'和table_schema NOT IN('information_schema' ,'mysql'); 如果找到任何内容,只需将其从此查询的输出中转换即可。
RolandoMySQLDBA 2011年

1
至于建议3,半同步复制使主服务器从从服务器收到确认,日志条目将其记录到从服务器。在mysql 5.0下,主服务器会等到从服务器完成对SQL的处理,然后再将相同的语句发送给下一个从服务器。因此,半同步速度更快。
RolandoMySQLDBA 2011年

2

max_binlog_size应该无关紧要-binlog数据不断地流出。

关于“分发主服务器”的警告-这是“单点故障”。也就是说,如果它死了,则超出其范围的所有从站将不会接收数据,并且重建中继将开始工作。

SBR与RBR-取决于查询。任何一个都可以比另一个更好或更坏。

将分发母版与真正的母版放在同一台机器上,或放在“母版”附近的机器上。使用单独的端口将实例分开。

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.