【问题标题】:Transactions over very very large entity group非常非常大的实体组的交易
【发布时间】:2011-03-20 21:01:55
【问题描述】:

我正在尝试设计一个可以容纳大量数据的数据模型,有大数据量经验的人对此有何反馈,即:

// example only, not meant to compile
public class TransactionAccount {
    private long balance;
    private List<Transaction> transactions = new ArrayList<Transaction>();
    ....
    public long getBalance() { return balance; }
}
private class Transaction {
    public Date date;
    public long amount;
}

根据我的阅读,在插入 Transaction 和更新 balance 时获得事务完整性的唯一方法是使其成为一个实体组。

但是,随着时间的推移,特定TransactionAccount 将有数百万笔交易。对该实体组的写入次数会很少,但读取次数会高得多。

我知道它可能会被分片,但是读取balance 是一个非常频繁的操作,而对它进行分片会使getBalance() 最常见的操作之一成为最慢的操作。

【问题讨论】:

标签: java google-app-engine jdo


【解决方案1】:

您描述的安排应该可以正常工作。如果您的实体组变得过大(在这成为问题之前我们正在谈论数百兆字节的事务),您可以编写一个“汇总”旧事务的过程:用单个事务替换一组旧事务记录这些交易的总和,以保持余额等于所有交易的总和的不变性。如果您仍需要存储这些旧的“汇总”交易的记录,您可以在执行汇总之前将它们复制到单独的实体组中。

【讨论】:

  • 这是一个绝妙的主意,例如,您可以有一个“cron”任务来检查具有超过 X 条记录的实体,然后简单地将最旧的 X 事务移动到另一个实体组。跨度>
  • 只是好奇,你从哪里得到“数百兆字节”这个数字作为指导?将“Transaction”对象加载到包含 100Mb 数据的内存中会不会有点过分?
  • 数百兆字节是指整个实体组的大小——账户及其所有交易——而不是单个实体的大小。我从自己作为 Bigtable 管理员的经验中获得了数百兆字节的指南。 :)
  • 谢谢!整个周末,我一直在脑海中折腾尝试拆分数据的方法,当您不熟悉 JDO 和 bigtables 时,这很困难。这让我想到了另一个更实际的问题,即您将如何实际处理 Set&lt;Transaction&gt;List&lt;Transaction&gt;,如果实际上有 100Mb 的对象,即 100 万个对象,我不确定如何管理这个问题
  • 在这种情况下,最好让子实体引用父实体,但不要将其放在列表中。不过,我不确定这在 JDO 中是​​如何完成的。
【解决方案2】:

您是正确的,TransactionTransactionAccount 必须在同一个实体组中才能执行事务性插入和更新操作。

分片的原因是为了减少写竞争,但你说这将是一个低写实体,所以这里不需要分片。

为了减小实体组的大小,您可以使用某种类型的归档过程。例如,如果这是针对银行账户的,那么在生成月结单时,您可以归档该月的交易价值。

【讨论】:

  • 这很接近,但是一个月的界限可能不是最好的方法。因为在高峰期,一个月内可能会发生很多事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
相关资源
最近更新 更多