From: Robert Klemme Date: 2004-04-27T23:14:09+09:00 Subject: Re: How do I scale large Ruby web applications? ------=_NextPart_000_002E_01C42C72.787DC9E0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit (selective reply) "Sascha Ebach" schrieb im Newsbeitrag news:408E2D1D.6090004@hexatex.de... > Thanks for all the comments so far. They are really helping. > > Let me elaborate a little more. In the comments I read interesting ideas > I want to go into a little more. > > Robert Klemme wrote: > > > The problem with performance is that you normally have to try and > > measure to see whether it's ok or not. And of course it heavily > > depends on the algorithms and kind of application at hand. I'd say > > without more information about these it's impossible to say offhand > > whether Ruby will deliver or not. > > I know that. You only going to really know the moment your service gets > used. Still you have to find a good scalable approach to begin with to > minimize the chances of rewriting everything. And I also know that > premature optimization is a bad thing. But blindly doing anything that > works can be equally problematic in the future. > > We are currently in the planning stages writing the use cases. And if I > would have to compare what the system will have to do I would probably > have to say it will be a lot like ebay. Except that it will have nothing > to do with auctions. We are not that crazy ;) Ppl will be able to put > there profiles in, upload pictures and descriptions of their objects, > search the database for these objects, communicate over the system about > these objects. Those are the basics. So from the viewpoint of what you > will be able to do I see that it is pretty similiar to the basic things > you can do on ebay. I hope that clears things up a little more. > > Robert also states that typically (in web applications?) a queue based > approach is used. I wasn't clear enough: I meant to say in webservers. Tomcat for example has a thread pool (whose min and max size is configurable). The start with min size and increase the number of threads if needed and until max is reached. > That sounds very interesting. Not only that you can > circumvent threads You don't circumvent threads but you remove the overhead of thread creation - which is significant if processing times are low. > which is always good if possible but I can imagine > that such a system would be fairly easy to implement. Yeah, not really a big deal. (see attached example) > The thing I am > wondering about is the response times. While you can have > progress bars in a desktop app you really can't afford to let the > user wait in a web app. It would probably take a while before that > happens on newer hardware, but this was exactly my point. In the event > you are so lucky that ppl get crazy about your service and you really > get more visitors than anticipated even a queue based solution has to > scale. I cannot imagine how to do that so I have to give it more > thought. Well, you have the response time problem either way - i.e. with threads per request as well as with tasks distributed via a queue. The advantage of the pool based approach is, that you can configure the max number of threads to the max reasonable for the system at hand and thus ensure that those requests that don't time out are processed with reasonable performance. > Maybe such a system can be implemted in such a way that it can > be easily scaled with new (upgrading) hardware? I could imagine a queue > based system that forwards its items to a distributed network of > computers via DRb... You mean a load balancing frontend that distributes requests among other hosts? Yeah, that's possible. And you can buy such solutions out of the box without additional ruby programming. Regards robert ------=_NextPart_000_002E_01C42C72.787DC9E0 Content-Type: application/octet-stream; name="pooling.rb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pooling.rb" #!/usr/bin/ruby require 'thread' # setup COUNT = 10 TERM = Object.new queue = Queue.new threads = [] COUNT.times do |i| threads << Thread.new(i, queue) do |index, q| until ( TERM == ( task = q.deq ) ) # process task # simulate long processing sleep rand puts "thread #{index}: #{task}" end end end # fill queue & process while ( line = gets ) queue.enq "line #{$.}: #{line.chomp}" end # init termination threads.each do queue.enq TERM end # wait for all threads to complete threads.each do |th| th.join end ------=_NextPart_000_002E_01C42C72.787DC9E0--