低延迟读写的持久性策略

时间:2009-11-19 16:06:38

标签: java database caching scalability low-latency

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

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

对于我们存储和读取的数据,数据的一致性和可用性并不像性能和可伸缩性那么重要。因此,如果在写入发生时系统出现故障,我可以处理一些数据丢失。但是,数据肯定需要在某个时刻保留到二级存储。

总而言之,以下是要求:

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

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

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

4 个答案:

答案 0 :(得分:2)

如果您有预算使用Coherence,我强烈建议您这样做。在Coherence中直接支持后写,最终一致性行为,并且它对于数据库中断和Coherence群集节点中断都是非常可生存的(如果在单独的JVM上使用> = 3 Coherence节点,最好是在单独的主机上)。我已经实现了这一目的,为财富100强企业的电子商务网站进行大批量CRM,它的运作非常好。

此体系结构的一个最佳方面是您编写Java应用程序代码,就好像没有发生后写行为一样,然后插入Coherence拓扑和配置来实现它。如果以后需要更改Coherence的行为或拓扑,则不需要更改应用程序。我知道可能有一些合理的方法可以做到这一点,但Coherence直接支持这种行为,而不是发明或手动滚动。

要做到非常好的一点 - 您对增加应用程序复杂性的担心是一个很好的问题。使用Coherence,您只需将更新写入缓存(或者如果您使用的是Hibernate,它可以是L2缓存提供程序)。根据您的Coherence配置和拓扑,您可以选择部署应用程序以使用后写,分布式缓存。因此,由于缓存的功能,您的应用程序不再复杂(并且坦率地不知道)。

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

答案 1 :(得分:1)

我曾经在一个使用异步写入althoguh的大型项目上工作,在这种情况下,它只是使用后台线程手写。您还可以通过将db write进程卸载到JMS队列来实现类似的功能。

一定能加速数据库写入的一件事就是分批进行。 JDBC批处理更新比单个写入快几个数量级,如果你是异步执行它们,你可以一次写500个。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

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

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