SEDA: An Architecture for Well-Conditioned, Scalable Internet Services

Matt Walsh, David Culler, and Eric Brewer
Home - Questions - Discussion

SEDA Questions

Here we have the list of submitted questions filtered to eliminate most duplicates and sorted to categories that somewhat apply to the nature of the question


Architecture & Engineering

Is it possible that individual stages of the network could be hosted on individual machines to transparently distribute the application?

Would the design model being presented transfer well to other (eg distributed) systems?

Would you evaluate SEDA in the aspects of reliability and scalability?

The architecture of SEDA seems to lead well to pipelining. How would you tune the system so that a messsage passing through has minimal latency? What trade off would you be making if you tune it in this way?

The idea of queues isolating a third-party module assumes that all such modules support the same queuing API. Is this really any better than other means of specifying a common API (e.g. Java interfaces), which allow for direct calls between modules?

SEDA looks a lot like pipelining with multiple threads per pipeline stage. Is there really anything new here other than having dynamic controllers for each stage?

The authors mention that event queues can be finite. In their model we can assume that there is a "root" stage, i.e. the first stage that receives an event and then processes the request by handling it itself of pushing it onto event queue of other stages ("substages). What do you think would happen to an event trying to enqueue itself onto root stage's queue which happens to be full, and also finite? How is what would happen different or simmilar to what Apache would do?

What are the new factors in the design of SEDA?

With the stages in the SEDA architecture, a lot of threads are required for a single task (at least one per stage). This seems like a bad idea for a complicated system with many stages. On a related note, how should stage broundaries be determined?

What are the difference between SEDA event-driven mechanism and traditional scheduling mechanism?

Since SEDA uses application as a network of stages, does it affect the concurrence of processing these applications?

Isn't SEDA actually something like a pipelined thread?

Would this concept spread naturally to a more distributed computing environment, compared to the uniprocessor or SMP environment it was developed on?

Performance

What are the relative merits of the throughput, RTT, and "Fairness" as indicators of performance? Are there still better measures?

In the benchmarking data shown, flash performs very well. Does the Berkeley team actually make a strong case for the (very complex) SEDA arcitecture in light of this?

The feature set supported by the SEDA prototype is certainly much smaller in scope than the production servers. Would it not be expected that any lean and competent implementation of a web server would outperform a production server out of sheer simplicity?

In the performance benchmarking section, the authors mentioned that they traded off "low average response time" for "low variance in response time" in their Haboob server. Was this really a "choice" or something that just turned out because of the way the SEDA architecture worked?

Would you justify if "graceful degradation" is good for a web server? (In my opinion, the idea of giving an equal response-time penalty to clients is not good. If a user tries to access a web server and finds that the access speed is slow, then the user could disconnect, reconnect, and luckily get a speedy access line. However, if a web server applies the policy of "graceful degradation," all connections would become slow and all users would begin to complain. Is it a really good policy?)

According to the paper load shedding is executed on the bottleneck stage's queue. If this stage is near the end of stage chain (consider the running application as a chain of stages) I think that this approach decreases efficiency because it wastes the work of previous stages. I think that no matter which stage is the bottleneck, load shedding should start from the first stage. At the same time we can start deallocating threads from previous stages and allocating them to the bottleneck stage. What's wrong with this idea that they didn't use it?

Regarding the design of having queues at each stage, could that actually lead to a lot of wasted work when the server is under heavy load? For example, let's say that you have queues between stage a and b(Queue AB) and b and c(Queue BC). If BC is full, then anyone on AB that wants to go through stage b will have to wait. But, if the request on AB is time sensitive, then BC could become a bottleneck in which a lot of things on AB might get timed out even after having gone through stage a, and whatever other stages before a, and thus the server's work would've been wasted.

For additional throttle safeguarding, what would implementing "expiry" times to events help eliminate "stuck" events from the system?

Can you explain the performance metric explained in Haboob?

They don't mention the scheduling algorithm they use to schedule events but they say that the scheduling algorithm is often tailored to the specific application. If different scheduling algorithms are used by different applications, could that have effect on speed and completition of an event?

In an overloaded condition is it better to serve a few clients quickly or is it better to show "fairness" to all the clients and serve them equally albeit at a lower rate.

How does a discrete threshold value for the resource controllers ? Imagine a scenario were the load is always just below the threshold. This would prevent the controller from adding a new resource, although the system is overloaded.

This paper typically benchmarks against servers which use one thread per task. Do systems which limit the number of threads used (e.g. Apache) exhibit the degredation in throughput when load increases?

Can't the graphs in figures 2 and 4 be almost the same if we consider multiple core processors?

Implementation

If a customer cheat to send a lot of request, which then will become the events, how does SEDA control this kind of situation? Does it need to add another controller to control this kind of things?

For Asynchronous file I/O in SEDA, if some event is blocked, what will happen for SEDA?

Suppose that you have an event-driven program: how would you efficiently implement a "scheduler" to ensure that the events for one particular client are not flooding out the events for other clients?

Given the discussion in the previous class about the improvements in threading implementations, especially in Linux, do you think that in 2001 (when the paper was published), programmers were still suffering from not having efficient threading implementations?

Apparently, in order to implement a software with SEDA, the software has to be parsed into multiple independent, decoupled stages. What if this cannot be done trivially?

How did they solve the problem of non-blocking file IO? And what is the result of their fix?

Sandstorm provides API's for destroying stages. How do you think they solve the case of event returns of substages to a stage that has been destroyed?

With dynamic resource controller and load shedding, it adds a lot of overhead at monitoring the application states. Also, if the dynamic control is not tune properly (ie sampling interval to spawn new threads, and idle time to kill unused threads), it will have negative result on performance. Is all these overhead worth the result? Should plain old threads be used instead?

In the staged Event-Driven architecture, what principles should be used for stage separation when designing a high currency system? How can we decide the number of stages? If more than three stages are used, how do we structure them?

Some questions about resource controller as below:

  1. Is the thread pool bounded or unbounded?
  2. What algorithms/rules are used to decide the thread pool's size?
  3. In 3.4, it says "Threads are removed from a stage when they are idle for a specified period of time". I wonder if we can add some "guess algorithm" to the controller to let it estimate the future workload based on past ones?

Do current commodity operating systems support SEDA execution model directly? In general it seems like the SEDA archirecutre increases the modularity and decouples the execution hence making it easier to manage loads. On the other hand the performance is not as high (as stated in paper 6) due to context switches between event-handlers in different stages.

Asynchronous IO: Will their system of running IO in a separate thread cause similar degredation in performance as I/O load goes up? (At least ~two synchronizations per I/O request served)

Application

Figure 5 of the paper shows an structural representation of Haboob in its composing stages, and section 5.1 details this composition. Unfortunately, neither the figure nor the description mention anything concerning handling internal or external errors (malformed client requests, requests for invalid pages,...). Where does error handling fit in SEDA ? Are errors passed just like the rest of the events ?

In figure 12 a) we can observe that the 3 curves follow each other closely until each one reaches its own maximal throughput. In other words, for each of the 3 web servers, as the number of clients augments, the throughput first increases, then stabilizes, but never decreases. The author suggests that Apache maintains its performance because it accepts a maximum of only 150 connections at any time. Would increasing that number, say to 200, have any benefit for Apache's throughput ?

Do modern http servers apply this idea of comining threads with events?

How do these factors deal with the problems of high-concurrency and loading in Internet servers?

Is it really fair to compare overload performance on systems that are designed for light loads? (i.e Flash capped at 506, Apache at 150, etc). Isn't that sort like saying that my T-Rex can do more damage than your poodle even though they're both mammals?

Do you think implementing Haboot server with C++ would have increased the perfomance (even though authors claim that the performance gap between java and statically compiled languages is closing) and would have prevented memory leak problems where garbage collection is not adequate?

Do you think the servers tested against Haboot are a good choice for testing perfomance? (Both of them uses a process based concurrency which is well known to be slower than threads and events)

Are there any large (i.e. significant) production server software packages use a similar architecture? As far as I know, Apache does not.

Future

The approach taken in this paper is to allow each application to finely control its resource allocation. Could we not instead establish some sort of protocol via which the application could communicate information about its load characteristics to the operating system so that the resource management could still be encapsulated in the OS?