« 返回

Liferay's Architecture: Caching (Part 1)

Company Blogs 2013年1月21日 按 Jorge Ferrer Staff

Here I am again with another in the series about Liferay's architecture. If you haven't read them yet, the four previous entries covered: Overview, Services Layer, Web Services and Service Builder.

This time I'm going to cover a very important concept: caching. In today's web, it's impossible for a web application to provide even good enough performance in the web unless it has a well designed caching system. So what I'm going to cover here is not only useful to understand Liferay's architecture better but might also be beneficial for anyone writting Java web applications, specially if they are large.

Liferay is known to provide very good performance (check the Performance Whitepaper in the whitepapers section of this website for details) and its caching system is a key factor in achieving that performance. This caching system spans through all three layers. The following diagram shows the main caching components in each layer:

Let's cover each of them one by one, starting with the lower layer.

At the persistance layer Liferay relies on Hibernate to do most of its database access. Hibernate has two cache layers called Level 1 (L1) and Level 2 (L2). Level 1 is used to cache objects retrieved from the database within the current datababase session. In the case of Liferay a session is tied to an invocation to a service layer. So when the frontend layer (or a web service) invokes a service a db session is opened and reused until the service method returns. All operations performed until that point will share the L1 cache so the same object won't be retrieved twice from the database.

Hibernate's cache Level 2 is able to span across database sessions and stores database objects (Entity Cache) and results of queries (Query Cache). For example if any logic retrieves from the database all users that belong to a certain organization, the result will be stored in the cache. Note that what is really stored is the list of "references" to the actual objects which are stored in the Entity Cache. This is done to ensure that there aren't several copies of the same object in the cache.

Besides using Hibernate, Liferay's code also performs some complex database queries directly (although reusing the database conneciton). For these queries Liferay has its own Entity and Query cache. In fact thanks to the work of Shuyang these two caches are extremely efficient and as a result, for Liferay 6.2, we have decided to disable Hibernate's level 2 cache by default leaving Liferay's Query cache as responsible for that task to improve performance.

One final important aspect is that all of these caches use an underlying cache provider to manage the objects in memory. By default Liferay uses ehcache to do that, but it is also possible to change the caching provider through portal.properties.  The configuration is done within hibernate-clustered.xml which defines  and configures several cache areas.

Finetunning these configuration files is a very important task for any high-profile site. But don't try to do it based on guesses. You should always do it while running a performance test suite that can help you find bottlenecks and verify changes in the configuration.

Since I want to try and keep these blog entries shorter and more frequent, I'm dividing it in two parts. In the next one I'll cover the caching mechanisms of the services and the frontend layer.

讨论主题回复 作者 日期
Great !! :-) !!! Please write more on Caching,... MANOVINAYAK AYYAPPAN 2013年1月21日 下午8:47
Hi Jorge! Great article. I hope the next entry... Florencia Gadea 2013年2月7日 上午10:56
Una sugerencia.Este blog podria ser multidioma,... rafa sojo 2013年2月28日 上午4:01
Muy buen articulo! Todo queda muy claro.... Gerardo Travesedo 2013年4月2日 上午10:24
I am currently facing some EhCache Replication... MANOVINAYAK AYYAPPAN 2013年4月7日 下午7:45
Hi Manovinaya, as explained by Jorge: "Level 1... Mario Lavarreda 2013年7月31日 下午2:01
Hi jorge, It is a great series on liferay... Ramkumar Chandran 2013年7月23日 上午6:39
Great !!. Is there a part 2 of this Blog. Shiva Gokaram 2013年12月3日 上午7:19
Not yet, sorry. I got too caught up with the... Jorge Ferrer 2013年12月3日 上午9:22
Hi Jorge, waiting your next part about... Christophe Cariou 2013年12月5日 上午12:52
Hi Jorge, Got a chance to write next series of... Vipin Bardia 2015年4月2日 上午2:41
Hey Vipin, Sorry I got side track and never... Jorge Ferrer 2015年4月7日 上午8:20
Sure :) Will wait for the article. Vipin Bardia 2015年4月7日 上午10:53
Hi Jorge, you say: "One final important aspect... Marcello Torriani 2015年7月15日 上午8:32
It is potentially possible, although you will... Jorge Ferrer 2015年7月16日 上午12:55

Great !! :-) !!!

Please write more on Caching, as it is quite difficult to understand the bigger picture to start off. I have been struggling with EhCache for past 2 weeks.

Thanks
在 13-1-21 下午8:47 发帖。
Hi Jorge!

Great article. I hope the next entry explains a lot more. What performance test suite do you use or recommend?
在 13-2-7 上午10:56 发帖。
Una sugerencia.Este blog podria ser multidioma, o por lo menos tener una versión en castellano
在 13-2-28 上午4:01 发帖。
Muy buen articulo! Todo queda muy claro. Gracias de parte de los que aun somos unos novatos!
在 13-4-2 上午10:24 发帖。
I am currently facing some EhCache Replication issue with My 6.0.6 implementation.

I would like to know which of the following Cache would be used, for a custom entity object.
L1 or L2.

Say I created a Custom Entity Object and retrieve it using the CustomEntityLocalService from my front end, which Cache will be used L1 or L2.
在 13-4-7 下午7:45 发帖。
Hi jorge,
It is a great series on liferay architecture
Could share some knowledge on Workflow Framework part of the liferay?
在 13-7-23 上午6:39 发帖。
Hi Manovinaya, as explained by Jorge: "Level 1 is used to cache objects retrieved from the database within the current datababase session. In the case of Liferay a session is tied to an invocation to a service layer. So when the frontend layer (or a web service) invokes a service a db session is opened and reused until the service method returns. All operations performed until that point will share the L1 cache so the same object won't be retrieved twice from the database."

Ehcache is used to manage the 2nd level cache. Second level cache allows to mantain a object reference across multiple calls from your front end.
在 13-7-31 下午2:01 发帖以回复 MANOVINAYAK AYYAPPAN
Great !!.

Is there a part 2 of this Blog.
在 13-12-3 上午7:19 发帖。
Not yet, sorry. I got too caught up with the 6.2 release.

But I plan to continue with this blog series pretty soon.
在 13-12-3 上午9:22 发帖以回复 Shiva Gokaram
Hi Jorge,

waiting your next part about caching.

In the meantime, can you give us some links where we can find explanations about the front end (mainly) an service layers caching mechanisms ?

For a proposal, I have to argue on the caching management in Liferay...

Thanks
在 13-12-5 上午12:52 发帖。
Hi Jorge,

Got a chance to write next series of this article?
在 15-4-2 上午2:41 发帖。
Hey Vipin,

Sorry I got side track and never found the time to continue.

I do plan to blog more about Liferay's architecture later this year but with a focus on the new modular architecture of Liferay 7. I hope you find that info useful as well.
在 15-4-7 上午8:20 发帖以回复 Vipin Bardia
在 15-4-7 上午10:53 发帖以回复 Jorge Ferrer
Hi Jorge,
you say: "One final important aspect is that all of these caches use an underlying cache provider to manage the objects in memory. By default Liferay uses ehcache to do that, but it is also possible to change the caching provider through portal.properties. The configuration is done within hibernate-clustered.xml which defines and configures several cache areas."
But also that. "Besides using Hibernate, Liferay's code also performs some complex database queries directly (although reusing the database conneciton). For these queries Liferay has its own Entity and Query cache."
My question is:
is it possible to switch from ehcache implementation to another one both for hibernate and for liferay level cache?
在 15-7-15 上午8:32 发帖。
It is potentially possible, although you will probably have to do a bit of research since it's not a common operation and thus it's not documented.

Out of curiosity, what implementation are you looking to use instead of ehcache?
在 15-7-16 上午12:55 发帖以回复 Marcello Torriani