4

我正在构建一个应用程序,其中包含一个以或多或少的交互方式批量标记数百万条记录的功能。用户交互与 Gmail 非常相似,用户可以标记单个电子邮件,或批量标记大量电子邮件。我还需要对这些标签成员身份进行快速读取访问,并且读取模式或多或少是随机的。

现在我们正在使用 Mysql 并为每个标签文档对插入一行。将数百万行写入 Mysql 需要一段时间(高 I/O),即使是批量插入和大量优化。我们需要这是一个交互过程,而不是批处理过程。

对于我们存储和读取的数据,数据的一致性和可用性不如性能和可扩展性重要。因此,如果在写入时发生系统故障,我可以处理一些数据丢失。但是,数据肯定需要在某个时候持久化到辅助存储中。

所以,总结一下,要求如下:

  • 潜在数千万条记录的低延迟批量写入
  • 数据需要以某种方式持久化
  • 低延迟随机读取
  • 不需要持久写入
  • 最终的一致性是好的

以下是我看过的一些解决方案:

  • 写在缓存(Terracotta、Gigaspaces、Coherence)后面,记录被写入内存并异步排入数据库。这些让我有点害怕,因为它们似乎给我想要避免的应用程序增加了一定的复杂性。
  • 高度可扩展的键值存储,如 MongoDB、HBase、Tokyo Tyrant
4

4 回答 4

2

我从事过一个使用异步写入的大型项目,但在这种情况下,它只是使用后台线程手动编写的。您还可以通过将数据库写入过程卸载到 JMS 队列来实现类似的功能。

肯定会加快数据库写入的一件事是分批进行。JDBC 批量更新可以比单个写入快几个数量级,如果您是异步执行它们,则一次可以写入 500 个。

于 2009-11-19T17:52:17.987 回答
2

如果您有预算为此使用 Coherence,我强烈建议您这样做。Coherence 中直接支持后写、最终一致性行为,并且对于数据库中断和 Coherence 集群节点中断(如果您在单独的 JVM 上使用 >= 3 个 Coherence 节点,最好在单独的主机上)都具有很强的生存能力。我已经为一家财富 100 强公司的电子商务网站执行大容量 CRM,并且效果非常好。

该架构的最佳方面之一是您编写 Java 应用程序代码时就好像没有发生任何后写行为一样,然后插入 Coherence 拓扑结构和使其发生的配置。如果您以后需要更改 Coherence 的行为或拓扑,则无需更改您的应用程序。我知道可能有一些合理的方法可以做到这一点,但这种行为在 Coherence 中得到直接支持,而不是必须发明或手工制作一种方法。

提出一个非常好的观点 - 您对增加应用程序复杂性的担忧是一件好事。使用 Coherence,您只需将更新写入缓存(或者如果您使用 Hibernate,它可以是 L2 缓存提供程序)。根据您的 Coherence 配置和拓扑,您可以选择部署应用程序以使用后写、分布式缓存。因此,由于缓存的特性,您的应用程序不再复杂(坦率地说,您不知道)。

最后,我在 2005-2007 年实施了上述解决方案,当时 Tangosol 制作了 Coherence,他们得到了最好的支持。我不确定甲骨文现在的情况如何 - 希望仍然很好。

于 2009-11-19T18:56:54.890 回答
0

根据您的数据的组织方式,也许您可​​以使用sharding,如果读取延迟不够低,您还可以尝试添加缓存。Memcache 是一种流行的解决方案。

于 2009-11-19T16:35:43.197 回答
0

Berkeley DB 有一个非常高性能的基于磁盘的哈希表,它支持事务,并在需要时与 Java EE 环境集成。如果您能够将数据建模为键/值对,这可能是一个非常可扩展的解决方案。

http://www.oracle.com/technology/products/berkeley-db/je/index.html

(注:oracle 大约在 5-10 年前购买了 berkeley db;原始产品已经存在了 15-20 年)。

于 2009-11-19T22:21:44.290 回答