【问题标题】:MongoDb unable to insert documents using Java Driver in sharded envMongoDb 无法在分片环境中使用 Java 驱动程序插入文档
【发布时间】:2014-11-27 06:04:00
【问题描述】:

当我尝试通过 jdbc 连接到键“状态”分片的 mongo db 并插入文档时,它说缺少 shardKey

我的所有分片(2 否,所有部分单独副本集)和配置服务器(1 否,部分副本集)已启动并运行,我可以使用 mongos 终端插入文档,但无法使用 Java 插入文档司机。 mongodb版本是2.6.5。

package dao;

import util.InstanceFactory;

import com.mongodb.DB;
import com.mongodb.MongoClient;
import org.apache.log4j.Logger;

public class MongoConnector {

private static MongoConnector mongoConnectorInstance;

private DB DbConnection;

public static DB getConnection(String dbName) {

  MongoConnector.mongoConnectorInstance = InstanceFactory.instantiateAsSingleton(MongoConnector.class);

  if (MongoConnector.mongoConnectorInstance.DbConnection == null) {

    synchronized (MongoConnector.mongoConnectorInstance) {

      if (MongoConnector.mongoConnectorInstance.DbConnection == null) {
        MongoConnector.mongoConnectorInstance.DbConnection = MongoConnector.mongoConnectorInstance
.getDbConnection(dbName);
      }
    }
  }

  return MongoConnector.mongoConnectorInstance.DbConnection;

}

private DB getDbConnection(String dbName) {

  DB db = null;

  try {

    MongoClient mongoClient = new MongoClient("some ip address of mongos", 27017);

   // Now connect to your databases
   db = mongoClient.getDB(dbName);

   System.out.println("Connect to database successfully");

  } catch (Exception e) {
    System.err.println(e.getClass().getName() + ": " + e.getMessage());
  }

  return db;
  }
}

现在,当我尝试使用具有以下功能的其他类插入文档时,我得到shard key not present code 61

 public static boolean insert(DBObject object, String table) {
    boolean status = false;
    if (object != null) {
        try {
            DB db = MongoConnector.getConnection("somedb");
            DBCollection collection = db.getCollection(table);
            //System.out.println(collection);
            if (collection == null) {
                db.createCollection(table, null);
            }
            collection.insert(object);
            status = true;
        } catch (Exception e) {
            MongoDao.logger.error("Could not insert in database" + e);
        }
    }
    return status;
}

我即将插入的对象看起来像

DBobject o=new BasicDBObject("SomeColumn":"somevalue")
           .append("shardKey":"UP");
MongoDAO.insert(o,"sometable");

我是否缺少一些连接到我的分片的配置?

【问题讨论】:

  • 我还没有详细分析你的Java问题,但是我看到你的分片键是“状态”:这个值的基数是多少?并且您能否确认您没有更新此属性的值。当您选择一个分片键时,您需要确保它具有高基数(以便能够在许多分片上分配值,除非您真的想针对特定分片),并且共享键是不可变的。见docs.mongodb.org/manual/tutorial/choose-a-shard-key
  • 对于一个文档,State 将只有一个。但是可能的状态总数为 36。就像一个人属于一个状态一样。同样,我们永远不需要更新这个值。
  • @Markus:感谢您更新帖子的格式。

标签: mongodb


【解决方案1】:

如果shard key是state,那么问题出在文档的构造上:

DBobject o = new BasicDBObject("SomeColumn" : "somevalue")
    .append("shardKey" : "UP");

应该是这样的

DBobject o = new BasicDBObject("SomeColumn" : "somevalue")
    .append("State" : "UP");

您似乎没有正确设置分片键。

另外,关于分片设置的其他几点说明:

  1. 您说您有 1 个配置服务器。使用 3。永远不要使用 1 个配置服务器,除非您根本不关心小型测试部署。使用 3 个配置服务器。

  2. 你说你的分片键有 36 个可能的值。这可能太少了。使用 36 个可能的值,您最多可以在分片之间分配 36 个可能的块。少量潜在的块将使 MongoDB 很难或不可能平衡分片之间的数据量。您需要重新考虑您的分片键。选择分片键是扩展 MongoDB 部署的关键部分,做出正确的选择需要大量关于系统用例的知识;您可以从手册中的some advice on choosing shard keys 开始。

【讨论】:

  • 我的意思是 1 个配置服务器,它是副本集的一部分,即实际上是 3 个配置服务器。无论如何谢谢。在分片问题上,是否可以像 One State 文件一样进入一个分片。至于一个国家,文件的数量可能从 100 万到 500 万不等。在这种情况下,Mongo 是否能够将文档数量平衡到两个不同的分片?
  • 不。如果所有文档的分片键值相同,则它们将位于同一个分片上的同一个块中。
猜你喜欢
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-01
  • 2017-08-02
  • 2016-05-29
  • 1970-01-01
相关资源
最近更新 更多