Redian新闻
>
请教:performance issue
avatar
请教:performance issue# Java - 爪哇娇娃
p*s
1
我单位有个系统是做server用,理想的情况想一个server可以带12~15个clients。
但现在带个4~5个就慢得要死,
不知道问题在哪里。
这个系统主要功能是每1妙刷新不到100个item的status。
这个刷新我们用了synchronization 对每一个item。
我自己认为这个可能是performance问题的根本。
因为我们根本没必要对每一个itemsynchronization。
我们只需要对同一个item的不同status的update, synchronization。
不知道谁能给我点指点,
这里synchronization应该怎么实现?
avatar
r*l
2
看了好几遍也没看明白。难道我的中文是越来越差了?

【在 p*******s 的大作中提到】
: 我单位有个系统是做server用,理想的情况想一个server可以带12~15个clients。
: 但现在带个4~5个就慢得要死,
: 不知道问题在哪里。
: 这个系统主要功能是每1妙刷新不到100个item的status。
: 这个刷新我们用了synchronization 对每一个item。
: 我自己认为这个可能是performance问题的根本。
: 因为我们根本没必要对每一个itemsynchronization。
: 我们只需要对同一个item的不同status的update, synchronization。
: 不知道谁能给我点指点,
: 这里synchronization应该怎么实现?

avatar
g*g
3
你应该先说明白,这100 item在哪里,什么引起变化?第三方网站上?
直觉上你的问题都不是对单个item做synchronize有问题,而是所有的
更新是sequential的。弄个线程池,把单个item的更新做成一个任务,
往里提交,效果就好得多。需要更好的效率,就应该上async IO了。

【在 p*******s 的大作中提到】
: 我单位有个系统是做server用,理想的情况想一个server可以带12~15个clients。
: 但现在带个4~5个就慢得要死,
: 不知道问题在哪里。
: 这个系统主要功能是每1妙刷新不到100个item的status。
: 这个刷新我们用了synchronization 对每一个item。
: 我自己认为这个可能是performance问题的根本。
: 因为我们根本没必要对每一个itemsynchronization。
: 我们只需要对同一个item的不同status的update, synchronization。
: 不知道谁能给我点指点,
: 这里synchronization应该怎么实现?

avatar
s*e
4
You can't do performance tuning by pure guessing. To pin point the bottle
neck, do a thread dump for the server process when the slow down happens.
Usually you can identify a lock that many threads are waiting to acquire.
Once you know what's slowing down the whole thing it should be trivial to
optimize.

【在 p*******s 的大作中提到】
: 我单位有个系统是做server用,理想的情况想一个server可以带12~15个clients。
: 但现在带个4~5个就慢得要死,
: 不知道问题在哪里。
: 这个系统主要功能是每1妙刷新不到100个item的status。
: 这个刷新我们用了synchronization 对每一个item。
: 我自己认为这个可能是performance问题的根本。
: 因为我们根本没必要对每一个itemsynchronization。
: 我们只需要对同一个item的不同status的update, synchronization。
: 不知道谁能给我点指点,
: 这里synchronization应该怎么实现?

avatar
p*s
5
对不住,
主要东西多,
可能总结的有问题。

【在 r*****l 的大作中提到】
: 看了好几遍也没看明白。难道我的中文是越来越差了?
avatar
p*s
6
你说的基本都对,
这100 items不在这个系统上,在第三方的系统上。
我们系统更新是sequential的。
主要就是这个第三方系统,
它会随时broadcast送这100 items的当前status给我们系统,只要有变化,
我们系统是负责,如果这个item在1秒内有变化,
我们系统要处理这个变化,比如这个item死掉了,得去掉,
或者这个item换了地方,管理的人应该不同了,我们系统负责把这个item从原来的管理
人那里去掉,再加到新的管理人的GUI界面里。
我们系统处理完这个,再把处理后的结果送到GUI端。
不知道我说清楚没。
你说的线程池听起来是可行的,
问题是我们做的不是web,
没有强大的web container 提供只需简单设置的线程池。
就用pure java实现,我不知道怎么实现,
如果你知道,能告诉大概怎么做,
或你能帮我找个链接,让我想想应该怎么下手。
做线程,我非常菜。

【在 g*****g 的大作中提到】
: 你应该先说明白,这100 item在哪里,什么引起变化?第三方网站上?
: 直觉上你的问题都不是对单个item做synchronize有问题,而是所有的
: 更新是sequential的。弄个线程池,把单个item的更新做成一个任务,
: 往里提交,效果就好得多。需要更好的效率,就应该上async IO了。

avatar
p*s
7
谢谢建议,
不知道我可不可以问下什么是thread dump?
该怎么做啊?
我可能问的很菜鸟,
不过我真不知道怎么入手,
请帮忙。

【在 s*******e 的大作中提到】
: You can't do performance tuning by pure guessing. To pin point the bottle
: neck, do a thread dump for the server process when the slow down happens.
: Usually you can identify a lock that many threads are waiting to acquire.
: Once you know what's slowing down the whole thing it should be trivial to
: optimize.

avatar
s*e
8
Thread dump is a just way to get the state of every thread in the VM -- what
it's doing, what monitors it's holding, and what monitor it's waiting for.
For performance issues in a multithreaded system, it often provides a
straightforward view of the bottleneck. Google 'jave thread dump' you will
find a ton information.
In Unix, use kill 3 to trigger thread dump; in windows, use ctrl-break
.Once you see the log for the actual thread dump, it's fairly self-
explanatory.

【在 p*******s 的大作中提到】
: 谢谢建议,
: 不知道我可不可以问下什么是thread dump?
: 该怎么做啊?
: 我可能问的很菜鸟,
: 不过我真不知道怎么入手,
: 请帮忙。

avatar
s*e
9
Gut feeling is that you have I/O ops in a synchronized block, which is
always a practice causing many uncertainties. However, in your original post
you said the performance only deteriorates when the number of clients
exceeds 5. Are all clients reading from the same data set? If the answer is
yes and the performance only depends on the number of clients, then you may
have too much synchronization for reading which is neither necessary nor
good.
Not sure how your system is designed, but you may want to check out
ConcurrentMap. It allows non-blocking read and concurrent update with up to
16 threads. Use that to hold the items and your clients' reading thread won'
t have to compete with your updating threads for locks and many threads can
update the status at the same time (unless they happen to access the same
partition).
Do you have to wait for the external system to send ALL items before doing
your work? If not, then you can create one job for each item and submit to
ExecutorCompletionService as soon as enough info is received to update the
item on your side. It works as a thread pool and automatically returns next
completed job without expensive polling, which can be monitored with another
thread since there's always wait for I/O.
If you feel some asynchronous ops can help, take a look at Executor,
Callable, and Future. They are the Java framework made ready for you to use
so you don't have to reinvent the wheel.

【在 p*******s 的大作中提到】
: 你说的基本都对,
: 这100 items不在这个系统上,在第三方的系统上。
: 我们系统更新是sequential的。
: 主要就是这个第三方系统,
: 它会随时broadcast送这100 items的当前status给我们系统,只要有变化,
: 我们系统是负责,如果这个item在1秒内有变化,
: 我们系统要处理这个变化,比如这个item死掉了,得去掉,
: 或者这个item换了地方,管理的人应该不同了,我们系统负责把这个item从原来的管理
: 人那里去掉,再加到新的管理人的GUI界面里。
: 我们系统处理完这个,再把处理后的结果送到GUI端。

avatar
g*g
10
Start with
java.util.concurrent.ThreadPoolExecutor
Just wrap you task as a runnable and submit.

【在 p*******s 的大作中提到】
: 你说的基本都对,
: 这100 items不在这个系统上,在第三方的系统上。
: 我们系统更新是sequential的。
: 主要就是这个第三方系统,
: 它会随时broadcast送这100 items的当前status给我们系统,只要有变化,
: 我们系统是负责,如果这个item在1秒内有变化,
: 我们系统要处理这个变化,比如这个item死掉了,得去掉,
: 或者这个item换了地方,管理的人应该不同了,我们系统负责把这个item从原来的管理
: 人那里去掉,再加到新的管理人的GUI界面里。
: 我们系统处理完这个,再把处理后的结果送到GUI端。

avatar
p*s
11
I am not sure we have I/O task in synchronized block or not, since sometime
we also made third party calls in synchronized block.
My clients get data from the same set. But I don't think this will make any
different, since what we concern is in 1 second, we might need to update A
item twice, and we need ensure that two updates are processed on the same
order as what we get. For us, we made any update are synchronized even
processing B item also needs wait that A item was processed, if we got A
update before B update.
I think ExecutorCompletionService might be useful for us, but first, I need
do thread dump test as what you said to find out the bottle neck.
Thanks for you post, I got lots of information that I never touched.

post
is
may
to
won'

【在 s*******e 的大作中提到】
: Gut feeling is that you have I/O ops in a synchronized block, which is
: always a practice causing many uncertainties. However, in your original post
: you said the performance only deteriorates when the number of clients
: exceeds 5. Are all clients reading from the same data set? If the answer is
: yes and the performance only depends on the number of clients, then you may
: have too much synchronization for reading which is neither necessary nor
: good.
: Not sure how your system is designed, but you may want to check out
: ConcurrentMap. It allows non-blocking read and concurrent update with up to
: 16 threads. Use that to hold the items and your clients' reading thread won'

avatar
p*s
12
Thanks for help.
I will do google search on this.

【在 g*****g 的大作中提到】
: Start with
: java.util.concurrent.ThreadPoolExecutor
: Just wrap you task as a runnable and submit.

avatar
c*n
13
我觉得楼主问这种问题还是用英文比较好,那中文看到实在是累,要把专有名字转换成
英文才顺一点,或者是我自己退化的太厉害了?
About the issue, Is your system java based? If so you can use jstack or
visualvm to monitor the system status.
You can also use various system monitoring tool to see if the bottleneck
happens in OS layer. In Windows, like PerfMon. In Linux, like ps, iostat.
Another suggestion is do you have a test client that simulate the client
activities? So you can role out the 3rd party influence.
avatar
x*6
14
I think you can use the ExecutorService, with a fixedThreadPool or
CachedThreadPool. Make refreshing every item a task and run it in the
ExecutorSerivce. I guess you also have a time budget for it so you can pack
the tasks in a collection and call ExecutorService.invokeAll().
Using intrinsic locks on the time comsuming computations like refreshing the
status of items in remote machines will definitely reduce concurrency.
avatar
s*e
15
lock striping might be a good idea in your case.
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。