Spring Data Mongodb上的性能问题 [英] performance issue on Spring Data Mongodb

查看:280
本文介绍了Spring Data Mongodb上的性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在spring数据mongodb上遇到了一个问题,在一种方法中,我请求一个简单的查找"方法以检索〜1000个文档.

I've got an issue on spring data mongodb, in a method, I request a simple "find" wich retrieve ~1000 Documents.

我的spring数据代码在这里:

my spring data code is here :

Query myquery = query(where("ipp").is(ipp).and(CODE_MESURE).in(codes).and(DATE_MESURE).gte(iDateDebut).lt(iDateFin));
return template.find(myquery, MessageMongo.class);

使用JProfiler,我在MongoTemplate类的查找"方法中获得了〜1,4sec . 注意:向MongoDB的请求不是问题,执行时间不到20毫秒.

And with JProfiler, i've got ~1,4sec in the "find" method of MongoTemplate class. Note : The request to MongoDB is not the problem, execution take less than 20ms.

但是如果尝试通过传统方式使用mongo java驱动程序请求相同的查询:

But if try to request the same query with mongo java driver by traditional way :

final DBCollection collection = template.getCollection(Constantes.MONGO_COLLECTION_MESSAGES_PARAMETRES_VITAUX);
 final DBCursor cursor = collection.find(myquery.getQueryObject());
final List<MessageMongo> tab = new ArrayList<>();
 while (cursor.hasNext()) {
  final DBObject d = cursor.next();
  tab.add(new MessageMongo((String) d.get("origine"), (String) d.get("appareil"),
      (String) d.get("chambre"), (String) d.get("lit"), (String) d.get("uf"), (String) d.get("ipp"),
      (String) d.get("domaineIpp"), (String) d.get("iep"), (String) d.get("domaineIep"), (String) d.get("ej"),
      ((Date) d.get("dateReception")).toInstant(), (String) d.get("codeMesure"),
      (String) d.get("uniteMesure"), (Double) d.get("valeurMesure"), ((Date) d.get("dateMesure")).toInstant()));
 }
return tab;

我的方法执行时间约为140毫秒(比mongoTemplate样式快 10倍!) Spring Data Mongo中是否存在错误,还是我错过了一些配置? 我更喜欢用它来编写,它更易于阅读,但是性能却很差:'(

My method execute in ~140ms (10x faster than mongoTemplate style !) is there a bug in Spring Data Mongo, or I missed something to configure ? I prefer to write with, it is easier to read, but performance is so poor :'(

Document类:

the Document class :

@Document(collection = Constantes.MONGO_COLLECTION_MESSAGES_PARAMETRES_VITAUX)
public class MessageMongo implements MessageModel {
  @Id
  private String id;
  private final String origine;
  private final String appareil;
  private final String chambre;
  private final String lit;
  private final String uf;
  @Indexed
  private final String ipp;
  private final String domaineIpp;
  private final String iep;
  private final String domaineIep;
  private final String ej;
  private final Instant dateReception;
  @Indexed
  private final String codeMesure;
  private final String uniteMesure;
  private final Double valeurMesure;
  @Indexed
  private final Instant dateMesure;
. . .

1,67sec ,如果我将MongoRepository与命名方法结合使用:

EDIT : 1,67sec if I use MongoRepository with the named method :

public List<MessageMongo> findByIppAndCodeMesureInAndDateMesureBetween(final String ipp, final List<String> codesMesure, final Instant from, final Instant to);

弹簧数据记录:

2017/12/04 15:44:59,455 INFO  [nio-8180-exec-4] fr.sib.sillage.biometrie.service.impl.MongoMessageService    : findByIppAndCodesBetweenDate ipp=102828799, codes=[147842], dateDebut=2017-12-02T13:46:59,dateFin=2017-12-03T01:46:59  
2017/12/04 15:44:59,482 DEBUG [nio-8180-exec-4] o.s.data.mongodb.repository.query.MongoQueryCreator          : Created query Query: { "ipp" : "102828799", "codeMesure" : { "$in" : [ "147842"]}, "dateMesure" : { "$gt" : { $java : 2017-12-02T12:46:59Z }, "$lt" : { $java : 2017-12-03T00:46:59Z } } }, Fields: null, Sort: null
2017/12/04 15:44:59,517 DEBUG [nio-8180-exec-4] org.springframework.data.mongodb.core.MongoTemplate          : find using query: { "ipp" : "102828799" , "codeMesure" : { "$in" : [ "147842"]} , "dateMesure" : { "$gt" : { "$date" : "2017-12-02T12:46:59.000Z"} , "$lt" : { "$date" : "2017-12-03T00:46:59.000Z"}}} fields: null for class: class fr.sib.sillage.biometrie.model.MessageMongo in collection: parametresVitaux
2017/12/04 15:44:59,517 DEBUG [nio-8180-exec-4] org.springframework.data.mongodb.core.MongoDbUtils           : Getting Mongo Database name=[LilleNoSQLDatabase]
2017/12/04 15:44:59,567 INFO  [nio-8180-exec-4] org.mongodb.driver.connection                                : Opened connection [connectionId{localValue:6, serverValue:3003}] to hades:27017
2017/12/04 15:44:59,567 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Sending command {find : BsonString{value='parametresVitaux'}} to database LilleNoSQLDatabase on connection [connectionId{localValue:6, serverValue:3003}] to server hades:27017
2017/12/04 15:44:59,592 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Command execution completed
2017/12/04 15:44:59,796 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Sending command {getMore : BsonInt64{value=63695089133}} to database LilleNoSQLDatabase on connection [connectionId{localValue:5, serverValue:3004}] to server hades:27017
2017/12/04 15:44:59,862 DEBUG [nio-8180-exec-4] org.mongodb.driver.protocol.command                          : Command execution completed
2017/12/04 15:45:01,213 INFO  [nio-8180-exec-4] fr.sib.sillage.biometrie.service.impl.MongoMessageService    : findByIppAndCodesBetweenDate size=1281

我已经在JProfiler中用org.springframework扩展了调用树的全视图,因此我可以查看Spring Data MongoDB的问题, 这是花费的大部分时间: 总共 2,5秒

EDIT 3 : I've expand the call Tree with org.springframework in full view in JProfiler, so I can view what's wrong with Spring Data MongoDB, and here is the majority of time spended : 2,5 sec total with


  • 的1,290次呼叫 org.springframework.data.convert.DefaultTypeMapper.readType(1,462
    毫秒)

  • 1,290 calls of
    org.springframework.data.convert.DefaultTypeMapper.readType (1,462
    ms)

1,290次呼叫 org.springframework.data.mongodb.core.convert.MappingMongoConverter.read (1,026毫秒)

1,290 calls of org.springframework.data.mongodb.core.convert.MappingMongoConverter.read (1,026 ms)

两种方法的组成是什么: 第一个readType中的大多数Class.forName(erk!)

And what's the composition of two methods : A majority of Class.forName (erk !) in the first readType

在第二次调用MappingMongoConverter.read时不清楚

And it's less clear on the second call to MappingMongoConverter.read

我希望发现问题会更容易.

I hope it will be easier to find the issue.

推荐答案

我不确定这是否适用于您的确切情况,但是我遇到了非常相似的情况,浪费了很多时间在ClassUtils.forName().

I'm not sure if this applies to your exact case but I had a very similar situation with a lot of time being wasted in ClassUtils.forName() and ClassLoader.load().

我已经检查了调试器下的情况,而在我的案例中,根本原因是我试图反序列化文档的类已移至其他程序包.在这种情况下,Spring Data无法正确地缓存类型信息,并在服务器上发出缓慢而昂贵的ClassLoader.load(). 每个文档的_class字段保留

I've inspected the situation under the debugger and the root cause in my case was that the class I was trying to deserialize the document to had been moved to a different package. In this case, Spring Data can't properly cache type information and issues a slow and expensive ClassLoader.load() on the persisted _class field for each document!

当然,该类加载注定会失败,因为它引用了在文档的_class字段中存储的位置不再存在的类.

Of course, this class load is doomed to fail because it references a class that no longer exists at the location stored int the _class field of the document.

这篇关于Spring Data Mongodb上的性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆