SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
805 stars 171 forks source link

RESTHEART throwing exceptions during load test #236

Closed abhinav1singhal closed 7 years ago

abhinav1singhal commented 7 years ago

we implemented RESTHEART to get aggregated data from MongoDB. For single requests , the data is coming up fine and meets the requirement. When we started checking this under JMeter requests by adding load on MongoDB we got exceptions at backend. We shared these exceptions with MongoDB engineers and they are indicating it could be because of restheart api issue. Has anyone faced these issues before?

@Andrea Di Cesare , any help on this will be greatly appreciated.

Below is detail Below are the examples URI which error out with “Out of memory”. REST API CALLS http://ftc-lbeapoc202:8080/statdata/InsStatData/_aggrs/getStatDataByIssuerIdSectionName?avars={'issuerId':66915,'sectionName':'SCDPT1'}

Error in server log:

[[1;31mERROR^[[0;39m org.restheart.handlers.ErrorHandler - Error handling the request java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3554) at java.util.Arrays.copyOf(Arrays.java:3525) at java.util.ArrayList.grow(ArrayList.java:272) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:246) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:238) at java.util.ArrayList.add(ArrayList.java:469) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:84) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:41) at com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52) at com.mongodb.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:53) at org.bson.codecs

Error in response: { · _exceptions: [ o { § exception: "java.lang.OutOfMemoryError", § exception message: "Java heap space" } ], · http status code: 500, · http status description: "Internal Server Error", · message: "Error handling the request, see log for more information" }

Thanks!

ujibang commented 7 years ago

Which version of java are you using?

mkjsix commented 7 years ago

@abhinav1singhal That's simply a java.lang.OutOfMemoryError, your tests are just using all the available JVM's heap space, you just need to start RESTHeart with a bigger heap adding the -Xmnsize parameter.

Java 8 takes Larger of 1/6th of your physical memory for your Xmssize (Minimum HeapSize) and Smaller of 1/4th of your physical memory for your -Xmxsize (Maximum HeapSize).

In Linux or Mac OS systems you can Check your default HeapSize with:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

-Xmnsize

Sets the initial and maximum size (in bytes) of the heap for the young generation (nursery). Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes.

The young generation region of the heap is used for new objects. GC is performed in this region more often than in other regions. If the size for the young generation is too small, then a lot of minor garbage collections will be performed. If the size is too large, then only full garbage collections will be performed, which can take a long time to complete. Oracle recommends that you keep the size for the young generation between a half and a quarter of the overall heap size.

The following examples show how to set the initial and maximum size of young generation to 256 MB using various units:

-Xmn256m -Xmn262144k -Xmn268435456

Instead of the -Xmn option to set both the initial and maximum size of the heap for the young generation, you can use -XX:NewSize to set the initial size and -XX:MaxNewSize to set the maximum size.

See https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html

abhinav1singhal commented 7 years ago

@ujibang We are using JDK 1.8

abhinav1singhal commented 7 years ago

We changed the memory settings as suggested above. But we are still unable to get data, It looks like we are pulling document close to 14 MB size. If I run the same query on something like robomongo without Aggregation I am able to get results.

abhinav1singhal commented 7 years ago

The same can be queried on RoboMongo as

db.InsStatData.aggregate([{$match:{sectionName:"SCDPT1",issuerId:66915}},{$unwind:"$rows"},{$unwind:"$rows.columns"}])

The query definition on RESHEARTis as below

{"$push": { "aggrs": { "type": "pipeline", "uri": "getStatDataByIssuerIdSectionName", "stages": [ { "$match": { "$and": [ { "sectionName": {"$var":"sectionName"} }, { "issuerId": {"$var":"issuerId"} } ] } }, { "$unwind": "$rows" }, { "$unwind": "$rows.columns" }, { "$match": { "$and": [ { "sectionName": {"$var":"sectionName"} }, { "issuerId": {"$var":"issuerId"} } ] } } ] } } }

abhinav1singhal commented 7 years ago

Thanks for suggestion, this one worked on windows machine. We will check this on Linux machine as well.

ujibang commented 7 years ago

@abhinav1singhal I'm closing this issue. Feel free to reopen if you need more help...