我有以下mongoDB命令来了解分片中的数据分布:
db.images.getShardDistribution()
如何使用java执行此mongoDB shard命令?
答案 0 :(得分:0)
以下是我在Java
中的实现:
Requierements:
- org.mongodb:mongo-java-driver:2.12.5 >=
- log4j:log4j:1.2.17 >=
/**
* Prints the data distribution statistics for a sharded collection.
* You must call the getShardDistribution() method on a sharded collection,
* as in the following example:
* db.myShardedCollection.getShardDistribution()
* @param collection sharded collection
*/
public static void getShardDistribution(DBCollection collection){
CommandResult stats = collection.getStats();
// Check if collection is sharded
if(stats.get("sharded") != null && (Boolean) stats.get("sharded")){
DB config = collection.getDB().getSisterDB("config");
Integer numChunks = 0;
BasicDBObject shards = (BasicDBObject) stats.get("shards");
for(String key: shards.keySet()){
DBObject shardDoc = config.getCollection("shards").findOne(new BasicDBObject("_id", key));
LOG.info("Shard " + key + " at " + ((shardDoc != null) ? shardDoc.get("host") : " shardDoc not found"));
DBObject shardStats = (DBObject) shards.get(key);
Pattern chunkPattern = Pattern.compile("^" + collection.getDB().getName() + "." + collection.getName() + "-.*", Pattern.CASE_INSENSITIVE);
List<DBObject> chunks = config.getCollection("chunks")
.find(new BasicDBObject()
.append("_id", chunkPattern)
.append("shard", key)
).toArray();
numChunks += chunks.size();
int estChunkData = (int)shardStats.get("size") / chunks.size();
Double estChunkCount = Math.floor((int)shardStats.get("count") / chunks.size());
LOG.info(" data : " + humanReadableByteCount((int)shardStats.get("size")) + " docs : " + shardStats.get("count") + " chunks : " + chunks.size());
LOG.info(" estimated data per chunk : " + humanReadableByteCount(estChunkData));
LOG.info(" estimated docs per chunk : " + estChunkCount.intValue());
}
LOG.info("");
LOG.info("Totals");
LOG.info(" data : " + humanReadableByteCount((int)stats.get("size")) + " docs : " + stats.get("count") + " chunks : " + numChunks);
for(String key: shards.keySet()){
DBObject shardStats = (DBObject) shards.get(key);
// Check if avgObjSize is empty
if(!shardStats.containsField("avgObjSize")){
shardStats.put("avgObjSize", 0);
}
double estDataPercent = ((int)shardStats.get("size") / ((int)stats.get("size") * 1.)) * 100;
double estDocPercent = ((int)shardStats.get("count") / ((int)stats.get("count") * 1.)) * 100;
LOG.info(String.format(Locale.ENGLISH, " Shard %s contains %.1f%% data, %.1f%% docs in cluster, avg obj size on shard : %s",
key,
estDataPercent,
estDocPercent,
humanReadableByteCount((int)shardStats.get("avgObjSize")))
);
}
}else{
LOG.warn("Collection " + collection.getName() + " is not sharded.");
LOG.warn("More info: " + stats);
}
}
/**
* Returns human readable byte count with handles both SI units and binary units
* @param bytes total bytes
* @return Formatted string of byte measure
*/
public static String humanReadableByteCount(long bytes) {
int unit = 1024;
if (bytes < unit) return bytes + " b";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = ("kMGTPE").charAt(exp-1) + "";
return String.format(Locale.ENGLISH, "%.2f %sb", bytes / Math.pow(unit, exp), pre);
}