Contributed by uttam on 8 Feb 2013
It’s always great to have application running on high CPU & more memory and that way you can always hide your code and environment mistakes. I did the same when I had a large instance of EC2 and IOPS enabled on the RDS, I designed and developed code which was less effective in terms of performance.
But one day I moved my code to a medium EC2 with RDS having no IOPS, it all ran slow and more slow.
My environment was Grails 2.1.1 & I had many plugins and huge DB with transactions which was like trying to insert 100k records frequently.
Steps I followed
Read all the blogs & I landed on Mr. Burt’s presentation
http://www.infoq.com/presentations/GORM-Performance (Great presentaiton)
I picked one immediate helper from Burt (which someone stopped during the presentation and asked about)
grails>grails console
The console helped me a lot for faster development, I could skip all the hoops of navigating through screens to get my code executed, no authentication, no steps just run :-).
I pasted all my code in the console, Ctrl + R and it ran!!
I changed my domain module to include only a reference of the parents key instead of the whole object
Example:
Older Version
public domain CustomerWeeklyServiceMenu {
String id
Date dateCreated
Date lastUpdated
BigDecimal pricePerServing
BigDecimal servingsQuantity
CustomerWeeklyServiceMenu customerWeeklyServiceMenu
Menu menu
static transients = ['excluded']
…..
}
New Version
public domain CustomerWeeklyServiceMenu {
String id
Date dateCreated
Date lastUpdated
BigDecimal pricePerServing
BigDecimal servingsQuantity
CustomerWeeklyServiceMenuId
MenuId
static transients = ['excluded']
…..
}
As you can see now I don’t have the Parent Objects in the domain rather, I now have the ids of those domain classes (or tables)
This is a good step to start with as Burt clearly mentions how Hibernate works with Collections and what can be the draw back if you don’t do it this way.
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = ‘org.hibernate.cache.EhCacheProvider’
}
This will enable Hibernate’s second level of caching for us. You need to add this in your DataSource.groovy
You would need to perform changes in your domain class which you want to make use of the second level caching.
static mapping = {
cache usage: ‘read-only’
}
From Mr. Burts’s presentation:
● Can significantly reduce database load by keeping instances in memory
● Can be distributed between multiple servers to let one instance load from the database and share updated instances, avoiding extra database trips
● “cache true” creates a read-write cache, best for read-mostly objects since frequently-updated objects will result in excessive cache invalidation (and network traffic when distributed)
● “cache usage: ‘read-only’” creates a read-only cache, best for lookup data (e.g. Countries, States, Zip Codes, Roles, etc.) that never change
● DomainClass.get() always uses the 2nd-level cache
● By default nothing else always uses the cache but can be overridden
Then you need to configure your Ehchace.xml
We created indexes on parent classes after using explain on Mysql tables. It did help us to certain extent.
I did CleanGorm after performing batch inserts.
if (index % Constants.SQL_BATCH_SIZE == 0) cleanUpGorm(index)
def cleanUpGorm(def index) {
def session = sessionFactory.currentSession
session.flush()
session.clear()
}
But I still did not see that big performance Run, then after reading more blogs and more books on hibernate, a thought came across if the session cache was very large. But that was the reason.
Next, I read that Grails has FlushMode as “AUTO”, so I referred to this page on Hibenate
session.setflushMode(FlushMode.COMMIT)
ICE breaker…..that’s it !! Now I had 450K records in an hour instead of 20K in 2 hours.
Visit us at Neevtech.com to know more about our offerings.
© 2016 Neevtech Blog | Neev Technologies
Leave a Comment