4

我一直在副本集配置中尝试 MongoDB,以了解它如何扩展/执行/应对。

我一直在使用Morphia ( Mongo 的 Java 驱动程序之上的 POJO 映射层)将 10,000 个简单的随机文档保存到单个集合中。我已经用注释注释了我的 POJO(MyData在下面的代码段中),@Entity(concern="REPLICAS_SAFE")希望发送到数据库的数据能够安全地持久化。

我的 POJO 由ObjectId字段(Mongo 的主键类型)、一个String随机长度的随机字符(最多 20 个字符)和一个long使用Random.nextLong().

我的代码如下:

for (int i=0;i<10000;i++) {
    final MyData data = new MyData();

    boolean written = false;
    do {
        try {
        ds.save(data); //ds is of type DataStore
        written=true;
        } catch (Exception e) {
            continue;
        }
    }
    while (!written);
}

我建立了一个四节点副本集集群,运行上述程序,然后开始隐喻地拔出电缆,看看发生了什么。

期望的结果是程序一直运行,直到它成功地将所有文档持久化到数据库中。

经过几次之后,实际结果是以下之一:

  • Java 报告它已经提交了 10k 个条目,但数据库只有 <10k
  • Java 报告它已提交 <10k 并且数据库报告相同或更少的值
  • 一切正常

在一种情况下,重新启动的节点实际上无法赶上 PRIMARY 节点,因此必须使用已删除的数据库从头开始。尽管将 opfile 参数增加到 2 gigs,但我认为这足以重播 10,000 行非常简单的数据。

你应该知道的其他事情:

  1. 所有这些都运行在单个硬件(2 gig Pentium D!)上,集群运行在两个 32 位 Ubuntu Server VirtualBox 实例上,每个实例有 128 兆内存,Java 客户端在 Windows XP 主机内运行。每个虚拟机上运行两个mongod进程,另外还有一个仲裁器也在一个虚拟机上运行。
  2. 两台虚拟机上的时钟关闭了几秒钟(我需要安装 VirtualBox Guest Additions 来解决这个问题),但不是很大 - 10gen 说时间不应该是集群的问题,但我想我' d 提及它。

我知道 Mongo 在 32 位机器上的 2 gig 限制,其他人的记录消失的事实,而且我知道我正在做这些测试的机器并不完全在前 500 名(这就是为什么我选择保留的数据很小的原因)但是当我的测试工作时,它们工作得很好。

我的问题是否证明 Mongo 还没有为黄金时段做好准备,还是我做错了什么?

我正在使用 1.6.5。

非常感谢任何见解、提示、提示、指针、解释或批评!

ps:我不是在拖钓——我真的很喜欢 NoSQL 的想法,因为它适用于各种数据,所以我真的希望它能够工作,但到目前为止我运气不佳!

4

1 回答 1

2

MongoDB 现在肯定在很多地方都在“黄金时段”使用。所以值得看看这里可能发生的其他事情。

所以这里有几个入门问题:

  1. “new MyData()”是如何工作的?您是否有可能正在敲打现有的 ID?
  2. 您的副本集是否在整个过程中“启动”?您只是在“继续”错误,所以我不确定如何处理错误。Morphia 是否正确冒泡错误?

我真的很感激你经历并编写了一种“测试用例”,但我认为你需要更深入地挖掘这个案例。您可以尝试以下两件事吗?

  1. 设置为。_id_ 通过这种方式,您可以看到您正在死亡的过程中的哪个位置。MyDatai
  2. console.write每次遇到错误时执行或等效操作。看看你是否无法弄清楚数据的实际去向。
  3. 以同样的console.write方式对每次成功的保存进行一次。

如果您执行这些步骤,您将获得正在发生的事情的日志,并且您将能够查看已保存或未保存的内容并将其与数据库中的数据进行比较。

我知道这有点乏味,但我认为你有两个问题之一,执行这些步骤将有助于解决这个问题。

要么 1. Morphia 未正确报告错误(未正确处理) 2. 您发现副本集存在实际问题 3. 您被“最终一致性”所困扰。

无论哪种方式,有了更多细节,我们应该能够深入研究问题。

于 2010-12-17T17:49:27.530 回答