views:

214

answers:

9

Hi,

I am developing a client-server based application for financial alerts, where the client can set a value as the alert for a chosen financial instrument , and when this value will be reached the monitoring server will somehow alert the client (email, sms ... not important) .The server will monitor updates that come from a data generator program. Now, the server has to be very efficient as it has to handle many clients (possible over 50-100.000 alerts ,with updates coming at 1,2 seconds) .I've written servers before , but never with such imposed performances and I'm simply afraid that a basic approach(like before) will just not do it . So how should I design the server ?, what kind of data structures are best suited ?..what about multithreading ?....in general what should I do (and what I should not do) to squeeze every drop of performance out of it ?

Thanks.

A: 

I would think that squeezing every drop of performance out of it is not what you want to do, as you really never want that server to be under load significant enough to take it out of a real-time response scenario.

Instead, I would use a separate machine to handle messaging clients, and let that main, critical server focus directly on processing input data in "real time" to watch for alert criteria.

JoshJordan
+3  A: 

I've worked on servers like this before. They were all written in C (or fairly simple C++). But they were even higher performance -- handling 20K updates per second (all updates from most major stock exchanges).

We would focus on not copying memory around. We were very careful in what STL classes we used. As far as updates, each financial instrument would be an object, and any clients that wanted to hear about that instrument would subscribe to it (ie get added to a list).

The server was multi-threaded, but not heavily so -- maybe a thread handing incoming updates, one handling outgoing client updates, one handling client subscribe/release notifications (don't remember that part -- just remember it had fewer threads than I would have expected, but not just one).

EDIT: Oh, and before I forget, the number of financial transactions happening is growing at an exponential rate. That 20K/sec server was just barely keeping up and the architects were getting stressed about what to do next year. I hear all major financial firms are facing similar problems.

DougN
I am receiving updates from a data generator program, not from real stock exchanges, and these updates conserning the the financial instruments come at 1 or 2 seconds at the monitoring server. My choice is to write it in java as I am much more skilled in this language than C/C++.
+3  A: 

You might want to look into using a proven message queue system, as it sounds like this is basically what you are doing in your application.

Projects like Apache's ActiveMQ or RabbitMQ are already widely used and highly tuned, and should be able to support the type of load you are talking about outside of the box.

matt b
JMS could be used as a notification delivery method but I don't see how it applies to the lookup and criteria checking part of the system.
Javamann
A: 

Best advice is to design your server so that it scales horizontally.

This means distributing your input events to one or more servers (on the same or different machines), that individually decide whether they need to handle a particular message.

Will you be supporting 50,000 clients on day 1? Then that should be your focus: how easily can you define a single client's needs, and how many clients can you support on a single server?

Second-best advice is not to artificially constrain yourself. If you say "we can't afford to have more than one machine," then you've already set yourself up for failure.

kdgregory
A: 

Beware of any architecture that needs clustered application servers to get a reasonable degree of performance. London Stock Exchange had just such a problem recently when they pulled an existing Tandem-based system and replaced it with clustered .Net servers.

You will have a lot of trouble getting this type of performance from a single Java or .Net server - really you need to consider C or C++. A clustered architecture is much more error prone to build and deploy and harder to guarantee uptime from.

For really high volumes you need to think in terms of using asynchronous I/O for networking (i.e. poll(), select() and asynchronous writes or their Windows equivalents), possibly with a pool of worker threads. Read up about the C10K problem for some more insight into this.

There is a very mature C++ framework called ACE (Adaptive Communications Environment) which was designed for high volume server applications in telecommunications. It may be a good foundation for your product - it has support for quite a variety of concurrency models and deals with most of the nuts and bolts of synchronisation within the framework. You might find that the time spent learning how to drive this framework pays you back in less development and easier implementation and testing.

ConcernedOfTunbridgeWells
A: 

From the way you describe it, it sounds like your bottleneck concern is the number of alerts you will have to process for any given update; that they will slow your overall system to less than real-time. Sounds like the update process is not very heavy and won't cause a slowdown in and of itself.

So first, decouple the update monitoring process from the alerting process. DougN describes having separate threads for each, that's a start. Once a single process is responsible for monitoring updates, have it relay those updates via socket-type protocol of your choice to each of a scalable number of alerting drones, each of them responsible for some subset of the alerts that must be sent. Then you're ready to send out a million alerts on a single update without slowing anything down.

Of course, if you're doing all of this on a single box, then your actual alerting mechanism (e-mail server, etc) might become the bottleneck.

John Pirie
A: 

One Thread for the receiving of instrument updates which will process the update and put it in a BlockingQueue.

One Thread to take the update from the BlockingQueue and hand it off to the process that handles that instrument, or set of instruments. This process will need to serialize the events to an instrument so the customer will not receive notices out-of-order.

This process (Thread) will need to iterated through the list of customers registered to receive notification and create a list of customers who should be notified based on their criteria. The process should then hand off the list to another process that will notify the customer of the change.

The notification process should iterate through the list and send each notification event to another process that handles how the customer wants to be notified (email, etc.).

One of the problems will be that with 100,000 customers synchronizing access to the list of customers and their criteria to be monitored.

Javamann
What do you mean by a BlockingQueue ?
It's a Queue in Java that will block on the put method if the Queue is full and block on the take method when the Queue is empty. It's a good way to pass data between threads.
Javamann
A: 

You should try to find a way to organize the alerts as a tree and be able to quickly decide what alerts can be triggered by an update.

For example let's assume that the alert is the level of a certain indicator. Said indicator can have a range of 0, n. I would groups the clients who want to be notified of the level of the said indicator in a sort of a binary tree. That way you can scale it properly (you can actually implement a subtree as a process on a different machine) and the number of matches required to find the proper subset of clients will always be logarithmic.

Toader Mihai Claudiu
A: 

Probably the Apache Mina network application framework as well as Apache Camel for messages routing are the good start point. Also Kilim message-passing framework looks very promising.

Karimchik