我们正在建设一个大型的电子商务网站,为超过 100,000 名用户提供服务,但我们预计用户数量在第一年会迅速增长。通常,该站点的功能与 ebay 非常相似,用户可以在其中创建、更新和删除列表。用户还可以搜索列表并购买感兴趣的项目。基本上,系统具有事务性和非事务性要求:
**Transactional**
Create a listing (multi-record update)
Remove a listing
Update a listing
Purchase a listing (multi-record update)
**Non-Transactional**
Search listings
View a listing
我们希望利用可扩展的、基于文档的 NoSQL 数据存储(例如 Couch 或 MongoDB)的强大功能,但同时我们需要一个关系存储来支持我们的 ACID 事务需求。因此,我们提出了一个使用这两种技术的混合解决方案。
由于该站点是“主要阅读”的,并且为了满足可扩展性的需求,我们建立了一个 MongoDB 数据存储。对于事务的需要,我们建立了一个 MySQL 集群。作为中间件组件,我们使用 JBoss App 服务器集群。
当“搜索”请求进来时,JBoss 将请求定向到 Mongo 来处理搜索,这应该会产生非常快速的结果,同时不会给 MySQL 带来负担。当一个列表被创建、更新、删除或购买时,JBoss 为 MySQL 的事务提供服务。为了使 MongoDB 和 MySQL 保持同步,JBoss 处理的所有针对 MySQL 的事务请求都将包括业务逻辑中的最后一步,即通过列表 id 更新 MongoDB 中的相应文档;我们计划使用 MongoDB Java API 来促进这种更新文档的集成。
因此,从本质上讲,由于站点主要是读取,因此该架构允许我们横向扩展 MongoDB 以容纳更多用户。使用 MySQL 允许我们利用关系数据库的 ACID 属性,同时通过 JBoss 中间件保持我们的 MongoDB 存储更新。
这种架构有什么问题吗?没有任何平台可以同时提供一致性、可用性和分区容错性——NoSQL 系统通常会放弃一致性——但至少通过这种混合方法,我们可以以增加系统复杂性为代价实现这三者,而且我们没关系,因为我们的所有要求都得到了满足。