2009年9月24日星期四

sqlalchemy、storm和web2py dal的比较报告

工作项目报告,所以抹掉项目名先,以"X"代之。

分割线内内容仅代表个人意见,与所供职企业及参与社区无关。

===================================

X 从很早的时候就出现各种数据库访问错误。包括链接数占用过多,死锁,
僵尸事务等。本周我集中梳理了一遍代码。我认为,虽然数据库设计方面有诸多
不合理之处,但是这些不合理主要影响业务错误,造成 X 性能和使用上的
问题是因为使用的ORM框架 storm 有严重的缺陷。

首先,storm 对数据库架构的同步有非常奇怪的设定。它不自动同步表结构,却插
手外键关联关系。强制要求外键必须都是级联更新、级联删除、set null。且不说
其设定中有自相矛盾之处,本身在MIS系统中做级联删除就是一件很危险的事——除
了系统维护、分表,MIS系统不应该删除任何数据。 storm 从一开始设计恐怕就没
有考虑企业级应用,但是对于web 开放式应用,storm 对外键的依赖又太笨重了。

其次,storm 在联接数据库后应该会有 DDL 操作(即修改数据库结构)或独占锁
定事务,此推断的证据在于用 storm 联接到 S 库后, S 无法进行
vacuumdb -a -f 处理。而根据 Postgres 手册,PG只有在遇到有链接正在进行
DDL 操作时,才会产生库级锁,造成 vacuum 操作无法进行(或手工建立一个隔离
级别相当的事务锁定)。作为世界上并发能力最强的数据库产品,正常的数据访问
操作与 vacuum 根本不会冲突,热处理资源回收正是 PG 独到的特性。这样造成了
X 应用频繁用光所有的链接数,还在数据库服务器遗留僵尸进程。我观察到
有僵死十几二十天没有完成过的 X 链接,这应该是因为同时多个 storm 链
接提交错误的锁定关系,造成死锁。

第三,storm 如果可以象 DAL 那样,明确设定不同步数据库,以上问题至少可以
解决一半,但是它没有链接配置参数。这造成了我们对其出现的问题无法进行友好
的调整。现在同事在 X 的 controll 层添加了强制的 commit 操作,一定
程度上减少了死链,但是我仍然观察到有点击 X 页面(在测试环境下)无
法响应,甚至造成数据库服务器闪断重启的现象,对于同时运营三十几个数据库的
数据库服务器,这是非常大的安全隐患。

昨天我尝试将 X 的数据库访问层迁移至 web2py DAL,经过一天尝试,总结
出以下的问题:

第一,DAL 缺少精确实数计算类型,它不支持 Numeric 或 Decimal,只能用
double,这是一个相当大的安全隐患,对于涉及财会计算的应用,使用浮点数是一
种很不严肃的作法。

第二,DAL 不支持数组和大数据类型,此类字段在 X 中有几处应用。

第三,DAL 对原生SQL的支持比较初级,虽然也可以使用,但是有时需要兼顾开发
速度,希望可以组合使用的时候,就会受限。

以上问题不是不能解决,但是需要修改 DAL 本身。虽然我一直有计划改造 DAL,
fork 一个对 PG 有良好支持的分支出来。但是这显然需要更多的开发时间。

昨天我详细查阅了一下 sqlalchemy 的文档,进行了一些简单的尝试,感觉这个
ORM 框架比较符合我们的需求:

第一,sqlachemy 对数据库链接的隔离级别和事务有良好的控制,默认也不会去尝
试DDL操作。

第二,sqlachemy 有非常丰富的数据类型支持,包括BLOB,Decimal/Numeric,以
及为 PG 特别定制的数组类型。

第三,sqlachemy 的查询类似 DAL (很可能DAL学习自sqlachemy),对各种查询操
作有良好的支持,还可以嵌入 SQL 片段,也可以方便的直接传入 SQL。

第四,sqlachemy 其实并不难学,它的功能虽然丰富,但是只掌握自己要用到的部
分即可,不需要完全学会,上手还是很简单的。

第五,文档比 storm 完整的多,而且现在仍在活跃开发。

第六,数据存储模型与业务模型分离,虽然看起来有重复劳动,但是对于一个需要
长期维护的企业应用项目,这是正确和严肃的作法。

第七,对特定数据库的特性有良好的支持,还可以扩展。

在使用 sqlachemy 时,我们还可以结合 web2py 原有的一些优秀工具,例如广泛
用于 DAL 的storage类型,这是一个类似 JS Object 的智能对象类型,很适合动
态结构的数据对象。

对于 X 项目的数据访问层重构,我评估工作量至少在一周左右。如果全部
换用 sqlachemy ,可以一劳永逸的解决数据库访问的问题,甚至 S 的后续版
本,我也建议尝试使用这个框架,毕竟这比 hack dal 要方便一些。

sqlachemy 当前的稳定版本是 0.5.6 ,我昨晚试验了开发中的 0.6 ,发现功能还
没有完整实现,现在还不能实用。


===================================

--
光见贼吃肉,没见贼挨打。
……

劉鑫
March.Liu

没有评论: