search 2013 adfgs
作者:Sky.Jian | 可以任意转载, 但转载时务必以超链接形式标明文章原始出处 和 作者信息 及 版权声明
链接:http://isky000.com/database/core-databas-system-migration-from-oracle-to-mysql | del.icio.us | Twitter it

为了对核心技术拥有更多的自主控制能力,为了解决数据库的线性扩展问题,为了尽量减少对商业软件的依赖,为了摆脱对高端硬件的依赖,为了… 基于以上多种原因,2年前,我们计划将公司某核心应用平台进行大手术:数据库平台从软件到硬件全部重构。当然,这其中应用架构的改造也不可避免的进行了大换血。

这个项目无论是从技术角度还是是业务角度来说,都对我们有着非常大的价值,也必定会带来非常深远的影响。项目历时2年多,分4个阶段才完成:

  • 应用接口统一
  • 这一阶段主要是为了后面真正迁移的时候做准备工作,将该核心应用系统的所有数据访问入口统一到一起,全部以服务化的接口方式呈现给其他有需要的系统,一来方便后续变更的控制,二来也推进了服务化的进程。

  • Oracle数据库中拆分(1拆16)
  • 这个阶段本不是必要的,但是由于项目启动稍微晚了点,数据出现了爆发性增长,导致该系统的数据表太大(单表不带索引过500GB),原 Oracle 数据库已经快撑不住了。为了安全起见,先在 Oracle 中从一个主表以会员ID进行 hash 运算后再进行水平拆分,从1个表分拆成了16个。附表由于访问量稍小,而且全部是根据主键访问,暂时保留原样。

    当然,这样的水平拆分,必然会带来数据访问路由以及数据合并的问题。我们专门为此开发了具有分布式数据库路由/数据合并,数据库读写分离,数据库链接管理等功能的数据访问中间层,专门解决拆分后给应用服务器带来的影响,使得应用服务器完全感受不到后端数据库的变化。

    这个数据访问中间层,对前端应用服务器来说,就是一个完整的数据库,所有数据请求都从这里实现,以协议的方式和前端应用服务器的jdbc驱动进行交互,以便让数据库对应用服务器彻底透明。

  • Oracle迁移至 MySQL(16拆128)
  • 这个阶段是整个阶段中历时最长,复杂度最高,风险系数最高的,未知因素也最多的一个阶段。虽然 MySQL 数据库已经在互联网行业占据了大片江山,但是对于阿里巴巴来说,却仍然是一个新鲜玩意儿,因为之前我们一直都用 Oracle 来提供所有的业务系统的数据库服务。

    在此之前,我们从来没有在如此核心业务系统的数据库上使用过 PC Server 和本地硬盘来承载数据库,一直是使用 IBM 小型机和中高端存储设备来解决高性能和高可靠的问题。在更换成 PC Server 和本地硬盘来承载数据库之后,我们就必须面对 PC Server 本身硬件可能存在的不可靠性所带来的 Crash,所以我们必须有一套完善的 HA 切换机制,要比小型机厂商所提供的商业 HA 管理软件更加高效更加自动化更加可控,才能我们降低了设备本身可靠性之后达到原有的可用性要求。

    对于一个需要满足 365 * 24 * 7 的核心业务系统来说,肯定是不可能给我们太多时间来进行数据迁移的,所以我们不得不设计出一个对现有系统影响尽可能小的迁移方案,这势必会造成方案的高度复杂化,带来更多的风险。最后的迁移方案要经历如下4个阶段:

    1. Oracle 读/写;;MySQL 初始化并增量写
    2. Oracle 读/写; MySQL 写
    3. Oracle 写; MySQL 读/写
    4. Oracle 停访问; MySQL 读/写

    当然,也正式由于有如此复杂的方案,才确保了在整个迁移过程中的的停机时间被控制在了10分钟之类。

  • 附属Detail信息迁移至 MySQL
  • 从项目开始,至完成主表拆分结束,已经接近2年了。这2年时间内,数据量一直都在飞涨,这让即使仅仅只是按照主键访问的附表也快无法承受持续增长的业务压力,附表的拆分也就成了必行之势。由于在原来主表拆分的过程中,整个项目组已经积累了大量的经验,附表拆分过程非常顺利,基本没有出现任何问题。虽然附表的拆分过程与主表相比除了 1拆16这个阶段外没有减少其他任何环节,但是整个拆分过程也才2个月就全部搞定了。

这个迁移项目算是彻底完成了,但是我们的迁移之路并不会就此止步,还有很多的系统仍然存在扩展性问题,还有很多的数据库应用等着我们去拆分。

注:同事们还为此送了我们一个虽不太雅但也意思相近的名称 “拆迁队”。

, , ,

已经有29个回复

  1. 八神 Says @ 10-08-19 4:30 pm

    这个项目的结束,意味着阿里巴巴MYSQL的时代已经到来,恭喜楼主

  2. 匿名 Says @ 10-08-19 5:38 pm

    “菜”确保了在整个迁移过程中的的停机时间被控制在了10分钟之类

  3. jacky Says @ 10-08-19 7:47 pm

    拆迁队成员情绪稳定的飘过。

  4. 匿名 Says @ 10-08-19 9:43 pm

    数据库切分的思路 貌似 Amoeba

  5. dhhb Says @ 10-08-20 2:20 am

    不懂Mysql的飘过,
    从字面理解主要是那个数据访问层做了load balance的作用最重要,后台用O or M都可以.
    如果M以后收费咋办? 总觉得O 不可能让M一直免费的.

  6. 朝阳 Says @ 10-08-20 9:36 am

    @dhhb
    这个我倒是一点都不担心,收不收费本身并不是一个非常关键的因素,而且就我个人看来,Oracle 还没有能力完全控制MySQL,现在的分支已经足够多了,而且也不乏非常优秀的分支版本。
    后台用O还是M并不是一样的,O没法很好的解决高可用问题,因为Physical standby无法直接连接使用,而Logical Standby的Bug和稳定性问题实在太多。

  7. 朝阳 Says @ 10-08-20 9:37 am

    “菜” -> 才,非常抱歉,错别字,已经修正,呵呵。

  8. Rebill Says @ 10-08-20 2:40 pm

    感谢分享。如果能透露更多的细节则更加完美。

  9. 呵呵 Says @ 10-08-20 5:50 pm

    应用接口统一是内网的api吗?会不会存在网络消耗的问题,

  10. 朝阳 Says @ 10-08-24 1:12 pm

    @Rebill
    考虑到公司机密问题,不便再次透露过都细节,实在抱歉;

    应用接口统一后的API并不是在一处以远程服务提供,而是部署到其他应用中,injvm;

  11. doordie Says @ 10-08-26 8:53 pm

    对自己写一个中间层提供jdbc访问很感兴趣,不知道这个中间层是否同时实现了缓存等功能?应该不是简单的代理吧。
    作为一个几乎可以肯定是国内访问压力最高的互联网应用,对mysql的探索有着标志意义,也让别的架构师在选择mysql作为后端时有了足够的信息,不过共享的信息过少…..

  12. 灵猫 Says @ 10-08-27 9:51 am

    请教一下朝阳大师,像你们在迁移过程中,数据量那是非常巨大的,TB级的肯定。看了BLOG说到也就只停机10分钟,怎么保证迁移的过程是完全平滑过渡的呢。因为你生产库的数据是一直快速增长,在你迁移的过程中肯定也是高速增长的。你在迁移完成前,怎么来保证迁移的数据是完整的呢。有没有什么好点的思路

  13. 灵猫 Says @ 10-08-27 9:54 am

    对于热点数据的迁移,比如现在分库1中的一个用户的数据很平稳,过了段时间,成为热点,那怎么迁移出去呢。有什么可以借鉴的思路不。最近也在做产品线的水平切分,对热点的迁移头都大了

  14. 灵猫 Says @ 10-08-31 8:31 am

    作者去参加SACC2010去了?

  15. 朝阳 Says @ 10-08-31 10:04 am

    @doordie
    这个中间层暂时并不负责缓存的控制,他隔断了前端业务相关的代码和后端数据库之间的依赖,让数据库对前端的应用程序完全透明,统一管理后端的 Oracle/MySQL 分布式数据库集群。当然也包括数据节点的路由策略控制,读写管理控制,HA 控制等。
    你这里所说的缓存,可能会在后续的发展中考虑。

  16. 朝阳 Says @ 10-08-31 10:07 am

    @灵猫
    不知道你这里有没有注意到,我在文中列出了数据迁移的4个步骤,正是由于使用了文中所说的那4个复杂的步骤,才保证了停机时间非常短。
    4个步骤中,是有同时写 Oracle 和 MySQL 这一环节的。

    对你与这里提到的热点数据的问题,其实一般都会遇到,我个人觉得主要也就以下这么几种解决方案:
    1、考虑合理的拆分规则,让数据在Sharding后尽可能平均,通过拆分规则来避免热点数据带来的影响;
    2、如果实在找不到合理的拆分规则来避免热点带来的问题,可以考虑合适的 Cache 规则,起始热点数据更适合 Cache;
    3、上面两招还是搞不定,基本上就只能再对热点进行拆分了,呵呵。

  17. 灵猫 Says @ 10-09-3 1:44 pm

    请教朝阳大师,你们用的MySQL版本多少呢,或者说你觉得几版本的是比较成熟稳定的。上次参加淘宝的数据库技术论坛,当时MySQL中国研发区的一个人说目前5.5是最稳定的。

    还有就是关于MyISAM和InnoDB的选择,什么情况下选择哪个,有什么好的经验吗关于这个的选择,虽然说一般是数据量大的情况选择InnoDB,但是太笼统了。不知道大师有什么思路建议,比如说读多写少的用哪个,写多读少,写多读多,数据量到多少选择哪个比较好

  18. fc_lamp Says @ 10-10-9 4:23 pm

    学习呀~~~

    自己还是“菜菜”一碟

  19. leoxqing Says @ 10-11-14 10:46 pm

    马上我也要面临对核心业务从O拆迁到M,现在还无头绪。谢谢大师的分享!

  20. 黄兵 Says @ 11-07-21 10:54 am

    朝阳老师。分享很不错,感谢无私的奉献。请问下朝阳老师您几个问题:
    1、在第四阶段 数据都在本地磁盘存储是吗?
    2、是不是换成集群的MySQL读写之后,写是一份数据,读也是一份数据了。读的数据要从写的数据去同步? 还是读写都在一起,采用集中控制的呢?
    3、朝阳老师,各个节点怎么保证HA的呢?

  21. 朝阳 Says @ 11-07-21 11:23 am

    @灵猫
    我们采用MySQL5.1,5.5过于超前,是否最稳定,我想还是应该由用户来评价,而不是他们自吹,呵呵。我很少使用MyISAM引擎,在线应用基本上都是 InnoDB,毕竟无论从并发还是内存利用率方面都要好,只有在一些存档表才使用MyISAM。

  22. 朝阳 Says @ 11-07-21 12:16 pm

    @黄兵
    首先,老师这个称呼实在受不起,还是叫我朝阳或者sky比较合适,呵呵。
    你这里提到的3个问题,分别如下:
    1. MySQL中的数据始终存储在本地磁盘
    2. 读写使用的相同的节点,确保数据始终一致,但每个节点都有一个在线热备的节点与之对应,配置成Dual Master
    3. 在线的Dual Master节点直接的HA判断由中间应用层确保,当一个节点有异常后,应用连接主动切换到另外的一个备用节点。

  23. jack Says @ 11-09-23 11:28 am

    您好! 朝阳。 首先感谢您分享这么好的观点! 有个问题请教下您。

    1、在第一阶段:•应用接口统一中,提到以服务化的方式统一接口。 服务化应该如何理解呢?

    2、服务化是否在JDBC上面一层。在以前的JDBC和应用层之间增加了一层(服务层)。这一层统一了上层应用系统的请求,向JDBC提供了更加有序的API请求?可否这么理解。

    3、再想请教下您,服务层怎么去做的呢? 是否是SQL语句和服务化接口的一个映射? 不是很理解服务层是怎样的。

  24. 朝阳 Says @ 11-09-23 12:36 pm

    所谓服务层统一,其实就是将原本散布在各个业务模块中对同一数据进行各类操作的逻辑,给统一整合到一起,以服务接口API的方式对外提供,以方便统一控制。所有对这类数据的各种操作,都由这个统一的服务来处理,以接口的方式提供服务。

  25. jack Says @ 11-09-27 1:12 pm

    谢谢您了! 您是我见过在IT圈子中,最负责任的一个了。问题都很细心,细致的解答。有一些博主,写了一篇文章,下面一推的问题。。。其实这样不好! 谢谢你了。给我们带来这么好的分享!

  26. 杨乐 Says @ 11-09-27 1:19 pm

    朝阳:您好! 好评很多呀,最后服务化做好之后,也完成了MySQO+PCserver+本地存储的迁移。我想请问下您:

    1、一个PCServer上面装几个MySQL呢? 以前我参加过一个讨论会,分布式数据库中pcserver有说装3个MySQL,您这个改造是装几个呢?

    2、是不是每一个节点(pcserver)上,就是建一个数据库,这个数据库中有存储有多张表。比如说商品中心,是否就在此节点就创建一个Product DataBase 呢?

  27. 朝阳 Says @ 11-09-28 1:56 pm

    1. 使用传统硬盘的2路 PC Server 基本上一个 MySQL Instance 肯定是可以将硬件资源利用的比较充分的,我们当时也是单实例。如果使用 SSD硬盘或者是 Fusion-IO 的 IODrive 这类高性能 IO 设备的话,CPU 肯定需要配置得比较高端(或者是4路)才能完全发挥出 IO 设备的能力,在这种情况下,如果不是使用 最新的 MySQL版本,建议使用双实例(2个Instance);
    2. 这里其实就只有2种选择:“同库不同表名 ” 或者 “同表名不同库”,从开发角度来说,尽量保证SQL语句一致可能会更方便一些,所以我们采用了同表名不同库的方式。

  28. boddi Says @ 17-04-22 11:31 pm

    请问大神四个阶段各自使用什么方案完成的:
    1. Oracle 读/写;;MySQL 初始化并增量写。-是否使用etl工具定时拉取?
    2. Oracle 读/写; MySQL 写 –是在业务系统实现的双写? 还是在中间件完成的?
    3. Oracle 写; MySQL 读/写 –是在业务系统实现的 还是在中间件完成的?

Trackbacks & Pingbacks

看完了要说点啥么?