Performance - computeMd5

146 views
Skip to first unread message

ragnor

unread,
Aug 12, 2011, 5:00:55 AM8/12/11
to xmemcached
Hi, I've noticed that in high performance application (more than 50
parallel threads, deployed on app server) on high load many of threads
block on java.security.Provider.getService(Provider.java:663). I've
checked it deeper and found that this block occurs because of invoking
MessageDigest.getInstance("MD5") each time the hash need to be
calculated.
Part of the stack trace:
java.lang.Thread.State: BLOCKED
at java.security.Provider.getService(Provider.java:663)
- waiting to lock <7a6e4b14> (a sun.security.provider.Sun) owned by
"http--xxx.xxx.xxx.xxx-8080-15" t@65
at sun.security.jca.ProviderList.getService(ProviderList.java:314)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:140)
at java.security.Security.getImpl(Security.java:659)
at java.security.MessageDigest.getInstance(MessageDigest.java:129)
at net.rubyeye.xmemcached.HashAlgorithm.computeMd5(HashAlgorithm.java:
204)
at net.rubyeye.xmemcached.HashAlgorithm.hash(HashAlgorithm.java:138)
at
net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator.getSessionByKey(KetamaMemcachedSessionLocator.java:
120)
at
net.rubyeye.xmemcached.XMemcachedClient.catalogKeys(XMemcachedClient.java:
1218)
at
net.rubyeye.xmemcached.XMemcachedClient.getMulti0(XMemcachedClient.java:
1148)
at net.rubyeye.xmemcached.XMemcachedClient.get(XMemcachedClient.java:
1046)

MessageDigest object isn't thread safe and can't be used concurrently
by many threads so each request needs dedicated MessageDigest object.
I see two possible solution:
1. create pool of MessageDigest objects
2. invoke once MessageDigest.getInstance("MD5") and store it in
HashAlgorithm static field and the each time create clone of this
object

What do you think about this? Did you encounter a similar performance
issues?

Best regards,
Ragnor

dennis zhuang

unread,
Aug 12, 2011, 10:15:09 AM8/12/11
to xmemc...@googlegroups.com
Yeath,it may be an problem here.
Another soluation is use static ThreadLocal field to cache MessageDigest instance,i think it is better than other solutions.
I will modify it in next release,maybe you should implement it now by yourself,just modify HashAlgorightm.java.

2011/8/12 ragnor <ragn...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "xmemcached" group.
To post to this group, send email to xmemc...@googlegroups.com.
To unsubscribe from this group, send email to xmemcached+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/xmemcached?hl=en.




--
庄晓丹
Email:        killm...@gmail.com
伯岩(花名)  bo...@taobao.com
Site:           http://fnil.net

淘宝(中国)软件有限公司 / 产品技术部 / Java中间件

Jakub Białek

unread,
Aug 13, 2011, 5:46:45 AM8/13/11
to xmemc...@googlegroups.com
Yes, ThreadLocal is better solution when thread live long (as on app servers) and many times uses MessageDigest but if live of thread is short then we'll back to square one. 
We can combine ThreadLocal with MessageDigest static field and clone approach. This static MD field can be used each time to create dedicated object in ThreadLocal by invoking clone (I assume that cloning object doesn't involved security checking).
Reply all
Reply to author
Forward
0 new messages