{ by david linsin }

April 16, 2009

More Playing with GAE

In my previous blog about the Google App Engine (GAE), I wrote about the problems I had encountered using JPA and Maven. In this post I want to share how using Groovy on the GAE worked out and what my impressions are on the scalability of the platform.

Inspired by SpringSource's blog on Groovy with the GAE and after almost a year, I decided to do some Groovy coding. I wrote a small Groovlet, which uses the JPA to fetch entities from persistent storage. Again, I'm quite astonished of how smooth coding can be:

import javax.persistence.*
import java.util.List
import de.linsin.sample.gae.domain.User
import de.linsin.sample.gae.EMF

EntityManager em = EMF.getInstance().createEntityManager()
Query query = em.createQuery("SELECT u FROM " + User.class.getName() + " u")
List<User> users = query.getResultList()

for (User user : users) {
out.println(user.getName() + " " + user.getLastname() + "<br/>")
}

em.close();


To be fair, I have no Exception handling in this code and there is no finally making sure the EntitManager is closed at the end. Yet, it feels like Java without the clutter.

To get this working on the GAE, all you need to do is drop the groovy-all.jar into the WEB-INF/lib folder of your WAR file and add the GroovyServlet to your web.xml. You add your Groovlet to a groovy folder under WEB-INF and access it like a good old Servlet in your browser e.g. http://dlinsin-area51.appspot.com/HelloWorld.groovy.

Unfortunately there is one major drawback, which makes developing Groovy for GAE a real pain - local deployment of Groovlets is not working right now. It seems like Google has been notified about the issue, but even after a few days the bug is still in status "new", so I don't think there'll be a fix anytime soon. Since daily deployment is limited by a quota, I think this bug is almost a show-stopper and I wouldn't want to develop in Groovy for the GAE right now.

Let's turn our attention to performance and scalability. First off I have a disclaimer: I didn't run any thorough or scientific tests! Although I have some numbers to back up my opinion, you might want to run further tests before you draw a final conclusion.

To get us all on the same page, let's start with a little "theory". When I talk about performance it means something like this:

... performance is characterized by the amount of useful work accomplished by a computer system compared to the time and resources used.

...performance may involve one or more of the following:
  • Short response time
  • High throughput

  • The same goes for scalability, although in general it's more subtle to properly define it:

    ...scalability is a desirable property of a system, a network, or a process, which indicates its ability to either handle growing amounts of work in a graceful manner, or to be readily enlarged.

    With that out of the way let's head over to the test setup. It consists of a simple Apache JMeter test script, which puts my poor sample application under load. The script loads the start page http://dlinsin-area51.appspot.com, then inserts the name "JMeter" into the input field and submits the form. The submission results in a redirect to the start page again. I mainly wanted to test "writes" to the persistent storage, because in my experience that's the most hardest part to scale.





    I ran the test script with 10 threads (blue shaded) and with 100 threads hitting my sample app. Each thread runs the test procedure 10 times. The results were quite interesting. If you take a closer look at the average response time of both samplers you can see only a small difference between 10 users and 100 users (or threads) hitting the application at the same time. The response time for inserting a row into the persistent storage went up insignificantly, which I think is quite astonishing, considering the increase of load.

    However, you should take these results with a grain of salt. They merely exist to give me a hint of what the GAE is capable of. I would be interested in real benchmarks, because I think it's crucial to see how scalable the GAE is under field conditions.

    Update: The test results are simply wrong! Thx for pointing it out Bernd, I'm working on it!

    Update 2: Here comes the bugfix!

    gae_summary_revised_10.png




    You might ask what happened? Frankly, I mixed up the pictures and didn't double check, before pushing out the post. Sorry about that! I ran the tests with the same specs as mentioned above again and as you can see from the results, this time it looks reasonable.

    Based on the new numbers, I have to put my conclusion a little bit into perspective. It still think the GAE scales reasonably well, but the numbers are not that astonishing anymore.

    5 comments:

    eckes said...

    I think the test you did is rather scaleable. What is interesting is session (stickyness) and maybe write/read dependencies inbetween the requests. So that the multiple appending instances are forced to cooperate.

    eckes said...

    Hmm.. noch mal zu den Zahlen, wenn du die Anzahl der Threads verzehnfachst, wieso verdoppelt sich der Throughput nur?

    Gruss
    Bernd

    david said...

    Mhh you are right I screwed up the JMeter test and didn't clear the results when running the test multiple times! I'll fix that asap.

    eckes said...

    I also managed to play around a bit, and it looks like the app is restricted to a single JVM. Because I used a static counter, and it was reliable seeing all my hits.

    (However I did not put much load on the ap yet). I dont think the service scales horizontally in the current version. But I am sure this attributed to the fact that its early. Or maybe they dynamically observe the load and reassign more worker nodes (however the documentation does not contain much warnings about "not asuming requests beeing handled in same jvm".

    david said...

    eckes > ...it looks like the app is restricted to a single JVM.That would be a huge bummer!

    eckes > I dont think the service scales horizontally in the current version.That would contradict with the Google mantra to use standard PCs to scale horizontally.

    I wonder how to properly test horizontal scaling?


    com_channels

    • mail(dlinsin@gmail.com)
    • jabber(dlinsin@gmail.com)
    • skype(dlinsin)

    recent_postings

    loading...