2

所以,这就是我的场景。

我有数百万个事件进入,我不想将这些数据直接扔到我的数据库中。我想要一个“批处理”操作,其中 java 代码保存传入的事件,直到达到阈值(比如每 10 秒),然后它们对主数据库进行批量插入。

我还需要容错,因为如果机器崩溃,我不想丢失数据。我正在考虑使用 hsqldb 将这些事件(大约 10k)保持 10 秒。

有什么建议么?

4

4 回答 4

2

如果您想要每秒数百万个整数和持久性,您可以尝试。Java Chronicle 你可以有一个不同的进程来消费数据,所以如果你的程序死掉了,数据仍然会被写入数据库。(您的主进程也不会因为必须执行数据库更新而减慢)它还支持通过 TCP 复制到多台机器。

基于此测试的简单示例HERE

 // create a Chronicle for reading or writing.
 String basePath = TMP + File.separator + "deleteme.ict";
 IndexedChronicle tsc = new IndexedChronicle(basePath);

 // create a handle to excerpts in the chronicle.
 Excerpt excerpt = tsc.createExcerpt();

 // add 1024 entries.
 int counter = 1;
 for (int i = 0; i < 1024; i++) {
        excerpt.startExcerpt(129);
        for (int j = 0; j < 128; j += 8)
            excerpt.writeLong(counter++);
        excerpt.write(-1);
        excerpt.finish();
 }

 // somewhere else read the file
    int counter2 = 1;
    Excerpt excerpt2 = tsc.createExcerpt();
    while (excerpt2.nextIndex()) {
        for (int j = 0; j < 128; j += 8) {
            long actual = excerpt2.readLong();
            long expected = counter2++;
            if (expected != actual)
                assertEquals(expected, actual);
        }
        assertEquals(-1, excerpt2.readByte());
        excerpt2.finish();
    }
    assertEquals(counter, counter2);

这使您可以在它们可用时进行批处理,以最大程度地降低未将其添加到数据库中的风险。当 nextIndex() 返回 false 时,您提交批处理的事务,稍等片刻并重复。

于 2013-01-08T20:31:24.980 回答
0

Martin Fowler 发表了一篇关于他的 LMAX 架构的文章,该架构允许在主内存中进行数百万次事务,并在发生故障时可以恢复。

至少你应该看看:http ://martinfowler.com/articles/lmax.html

于 2013-01-08T19:50:21.143 回答
0

我推断您的问题是数据库负载,而不是进程负载。这向我提出了一个问题,为什么您希望批处理操作更便宜,从您目前的问题来看,听起来您宁愿每小时支付 600 美元而不是每分钟 10 美元,但负载也会一样糟糕。

如果您可以廉价地处理批处理操作,那么您只需要缓存到一个节省成本的媒介中,然后从那里加载。想到的两件事是用 JSON 写入平面文件,以及使用 Memcached(也可能是 JSON),其中加载发生在单独的进程(或线程池)中。您需要确保两者之间的原子性。可能有更多开箱即用的解决方案,我会留下更多知识渊博的答案来提出。

根据您期望崩溃的严重程度,您还可以设置关闭挂钩以在机器崩溃之前转储,尽管这充其量是值得怀疑的做法。

于 2013-01-08T20:37:20.127 回答
0

批处理操作实际上是在数据库级别处理的。数据库将单个(或几个)写入中的多个事务合并到事务日志中,写入从事务日志移动到表,但它们被分组以最小化磁盘写入。至少与甲骨文。这就是为什么它如此高效且如此昂贵的原因。但它可以是这样,PostgreSQL将满足您的期望。先测试。

在数据库读取方面,也有来自数据库站点的密集缓存。但是解析 SQL 的成本很高,所以使用客户端缓存是一个很好的选择。考虑EhCache。它支持 2 级缓存:预定义数量的项目保存在内存中,其他集合溢出到磁盘(如果需要,您可以只使用内存缓存)。从内存缓存中读取的时间大约是HashMap的访问时间。当然,您拥有的 RAM 越多,内存缓存的效率就越高。

当谈到容错时,数据库保证,缓存不会。这仅是写入问题,而不是读取问题。例如,不要尝试使用 hsqldb 自己实现某些东西。磁盘写入总是很昂贵。你不会写出比 Oracle 更好的东西,因为你没有这么多的人和时间 :) 他们的事务日志机制非常有效。并且当系统崩溃时,只要执行了提交,操作就会从该日志中恢复。

于 2013-01-26T07:33:32.067 回答