数据仓库的消亡和重起
在Facebook,我们不断地向MySQL数据仓库加载更多的数据,执行更多的查询。我们只执行过为动态网站提供服务的数据库查询,对于在数据仓库上执行一条查询所需运行的时间之长,令我们都很惊讶。在和一些经验丰富的数据仓库专家讨论后,我明白了由于查询复杂性、数据量大或者两者兼备,查询执行几个小时甚至几天都是很正常的。
有一天,我们的数据库数据接近100万兆(1TB),mysqld守护进程突然中断了。在诊断了一段时间后,我们试着重启数据库,熬了一宿,直到重启操作开始执行,我们才回家。
当我次日早上回去工作时,数据库还处在恢复阶段。由于数据被很多客户端修改,为了获得一致性视图,数据库服务器维护了一张持久性列表,该列表包含了所有的修改操作,称为“重做日志”(rdo log)或者“预写日志”(wite-ahead log)。如果数据库服务器被粗暴地终止和重启,它将会从重做日志中读取最近的写操作日志,加快恢复速度。由于我们的数据仓库系统规模很大,MySQL数据库恢复需要一定的时间。在那次崩溃之后,我们花了三天时间才重新拥有可以正常工作的数据仓库。
我们那时决定把数据仓库迁移到Oracle上,Oracle数据库软件对于管理大数据集有更好的支持。我们还购买了一些昂贵的高密度存储服务器和一个强大的Sun服务器来运行新的数据仓库。
在我们把程序从MySQL迁移到Oracle的过程中,我充分体验到所谓的标准关系数据库在实现上还是存在许多差别。每个数据库的大批量导入和导出工具使用完全不同的机制。此外,每个数据库支持的SQL语句很不一样,这迫使我们不得不重写很多查询。更糟的是,Oracle上的Python客户端库还不正式且有些bug,因此遇到问题时,我们需要直接和开发人员联系。
经过几周的辛苦努力,我们重写的脚本在新的Oracle平台上可以运行了。夜间执行的程序运行正常,我们很兴奋地去尝试Oracle“生态系统”的其他工具。尤其是,Oracle有个名为Oracle仓库构建器(Oacle Warehouse Builder,OWB)的ETL工具,我们期望用它替代自己手工写的Python脚本。但是,该软件不支持我们需要的数据源规模:在那时,通过每天晚上收集数据,Facebook已经有几万个MySQL数据库。虽然连Oracle都无法帮助我们解决在ETL方面遇到的可扩展性挑战,但是我们很高兴拥有一个能够正常运行的包含几百万兆(T)数据的数据仓库。
然后,我们打开点击流日志:仅仅第一天,在Oracle数据库上就发送了400GB的无结构化数据。我们再次对使用数据仓库表示怀疑。