首页 > 数据库 > 关于facebook的osc(online schema change)

关于facebook的osc(online schema change)

2011年9月16日 10,292 views 发表评论 阅读评论

最近阅读了下facebook的online schema change方案(翻墙),简单测试了下. 做一个小结,供大家参考,有兴趣的同学可以下载看看:
1. 为什么facebook有osc的需求
使用mysql有一个苦恼,因为mysql在线ddl的能力很弱(myisam和innodb引擎都是如此).
Mysql的绝大部分DDL的操作的基本步骤是: 锁表,按照新的定义创建一个临时的空表,然后把数据插入这个临时表,完成之后,再rename这个临时表为生产表.
生产的实践,百万级别的表还好,一般1分钟内可以完成,千万级别的表,可能需要10多分钟才能更改完,这对于许多业务都是不可接受的,因为更改表结构的时候,会锁住表不能写入.
由于知道mysql的ddl限制,所以我们才有要求,mysql进行分表,尽量控制表在千万数据以下. 一般来说数据规模和性能,吞吐率并没有什么大的联系,主要还是为了ddl的方便.
存储为key-value也是一种很广泛使用的形式.

目前我们在生产环境中对于一些大表的ddl(更改表结构),一般采取如下几种方式:
1. 暂停服务的使用,或者降级服务的使用(比如切换服务为只读模式),这些都是从应用层来实现,应用方案会复杂些,但从应用层处理节点失效,是更成熟更可靠的办法;
2. 使用master< ->master的架构,先在从库上更改好表结构,然后切换服务到从库, 然后再另一个库执行同样的步骤,然后再切回来,可能存在切换导致的复制失败,丢失数据问题,来回切换也比较耗时,web服务器可能还需要重启,不是那么可控,但如果不是非常频繁,仍然是比较稳健的一种方式;
3. 凌晨闲时修改表结构:简单的可以写守护,复杂的现场施工,可能会影响少部分用户,所以需要预先评估受影响时间,受影响用户,一般需几分钟内执行完.
4. 或者在设计初期,就定义一些冗余字段,留待日后使用,虽然有点不好看,却也是很有效的方式.
以上种种,如果不频繁ddl,不涉及到大量的节点,一般成本不高.也是优先选用的.

由于facebook每个星期都会有几次修改表结构,涉及到的一些数据库节点可能表比较大,停服务(降级服务)或者切换服务到从库,都会是比较耗时繁重的任务.OSC可以在线做一些ddl的操作.大大降低了维护的成本.

2. OSC介绍
facebook参考了这个项目The openarkkit toolkit oak-online-alter-table ,python 实现.
简单介绍:这个工具的原理是创建一个ghost table,慢慢同步原始表, 当同步完成后,替换掉原始表. 可以用触发器来捕捉原始表的变化(创建相应的after insert,after delete,after udpate触发器) .
同步的时候,从原始表复制到ghost table,是分批复制的(chunk-size选项定义批次大小),当一批数据被复制时,对于myisam,archive,memory等引擎的表,施加表锁,对于innodb,仅对于这批数据行施加行锁.每批的行数越少,锁越快释放,允许更多并发,但最终完成的任务会更长;对于写负荷重的应用,作者建议设置sleep时间,以平均分布负荷,减少对生产的影响.(sleep选项);

facebook实现的online schema change为php实现.
基本步骤如下:
1. 先可以更改从库,做好改变.
2. 然后更改主库:set sql_log_bin = 0 ,执行如下的步骤.
copy – where they make a copy of the table
导出数据到外部文件,然后导入数据库copytable,分批导出的方式;
build – where they work on the copy until the copy is ready with the new schema
replay – where they propagate the changes that happened on the original table to the copy table. This assumes that there is a mechanism for capturing changes.
捕捉变化replay到临时表copytable ,存在的问题是:某些dml语句会查询,更新多个表,需要过滤掉,不能replay,会丢失数据或者数据不一致.
cut-over – where they switch the tables ie rename the copy table as original. There is typically small amount of downtime while switching the tables. A small amount of replay is also typically needed during the cut-over.
此切换过程瞬间,会有连接中断,报错,无法避免.

一些限制条件:
1. 原始表必须有主键;
2. 不能有外键;
3 .不能存在触发器;
4. 尽量不要更改主键,如更改,旧主键应该确认有高效索引;
5. facebook验证通过的版本是 5.1.47 and 5.0.84 ,如果要使用其他的版本,需要配置选项.

经过简单测试, 目前来说,facebook这个php包的适用性还是有局限性:
1. 限制比较多,存在不可控制的风险;
2.目前facebook仅测试了 5.1.47 and 5.0.84版本,其他版本使用还需要经过验证;
3.不支持rename字段,drop字段(其他的一些不是修改字段,添加索引之类的ddl估计也不支持:如truncate);
4. 在cut-over阶段,,部分连接会中断 出现错误”Table ‘test.t1’ doesn’t exist ” ,除非应用会重试连接

一个好消息是percona工具也提供类似的实现,具体就没有去测试了.

 » 如果喜欢可以: 点此订阅本站
分类: 数据库 标签: , ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.