Job Title: Sarcastic Architect
Hobbies: Thinking Aloud, Arguing with Managers, Annoying HRs,
Calling a Spade a Spade, Keeping Tongue in Cheek
Of course, as with ANY technology, (Re)Actors (and (Re)Actor-fest architectures) have their own limitations.
Let’s expand our performance table (the one which was shown on a slide from Part II) with two new columns:
- A chance to handle a respective approach correctly in a typical business-level app, and
- types of Apps where the respective approach is usable to write app-level code
Now, let’s take a closer look at it. As discussed above, BLOCKING Shared-Memory (the one which uses mutexes at app-level to synchronize between threads), tends to fail badly BOTH in terms of performance AND in terms of being correct. As a result, I DO NOT see ANY room for mutexes in modern app-level programming – except when they’re VERY accidental to the task at hand.
Non-blocking shared memory (including rather exotic stuff such as non-blocking algorithms, memory fences, and RCU) are known to perform really well (at least within one NUMA node) – but complexity of these things for any non-trivial task (especially IF we’re not going to accept non-fixable bugs in production) is usually THAT high, that it is not really feasible for a vast majority of business programs out there (nor it is really necessary). Still, it remains a very reasonable choice for absolutely-latency-critical apps such as High-Frequency Trading (HFT).
"Classical" flavor of Message Passing (including (Re)Actors), tends to have very good performance- and excellent chances to handle it well in a typical business app. No wonder it is my personal preference to be used (except noted otherwise in this table).
The second flavor of Message-Passing, is Message-Driven (a.k.a. Data-Driven) programming, tends to improve calculation performance even further, but this performance gain is mostly HPC-oriented, and won’t make much difference for a typical business app (though IF you REALLY need heavy calculations, HPX would be my first recommendation).
As for no-contention stuff, it is widely used for web apps (in fact, assuming no-contention, though it is actually pushed down to the database level, with transaction isolation coming into play). Moreover, for LOW-WRITE-LOAD web apps I don’t object to this kind of architectures; it DOES work – as long as we have not-more-than a few writing transactions per second (or, more formally, as long as we can keep "serializable" isolation level for our DB connections). However, as we discussed above, in spite of all the theory saying that going for stateless no-sync apps is the only way to scale, such systems-taken-as-a-whole, are NOT really scalable. As a result, I am AGAINST trying to scale this kind of architecture beyond its limits (which happen to be around 100M writing transactions/year, but still covers LOTS of websites, including such monsters as BBC, CNN, etc., which have LOTS of reads but only VERY FEW writes).
One important thing to note is that this table is based only on anecdotal evidence (a.k.a. Real-World Experience), so Your Mileage May Vary.
To provide a bit different perspective to the table from the previous slide, it can be rewritten as follows:
- the ONLY field which I know where (Re)Actors won’t fly, is High-Frequency-Trading a.k.a. HFT. HFT guys-and-gals are dealing with latencies of the order of hundreds-of-nanoseconds, and traditional (Re)Actors are not AS good latency-wise. On the other hand, I have to mention "CAS-size (Re)Actors" [NoBugs17a] in this context, which MIGHT simplify development of non-blocking algorithms (CAS (Re)Actors is a very interesting subject per se, but unfortunately, we don’t have time to discuss them).
- For HPC, Message-Passing MPI is successfully used for ages, but I do agree that HPX-like approach of being Message-Driven is more promising (still, mutexes are outlawed there).
- For low-write-load web apps, a classical approach which essentially ignores all the synchronisation problems – DOES work, but ONLY as long as write load is relatively low. As soon as the write load goes higher – this approach doesn’t really scale (causing ALL kinds of trouble, from impossible-to-find data races to poor scalability).
- And for everything-else-out-there, IMNSHO (Re)Actors are THE way to go. In particular, real-world experience has shown that (Re)Actor-based systems have been seen to perform 30x better, and 5x more reliably than the competition, while processing billions of messages per day, and tens of billions DB transactions per year.
WHAT ARE YOU WAITING FOR? ARCHITECT YOUR NEXT SYSTEM AS A (RE)ACTOR-FEST!
To wrap it up, I also have to note that the subject of the (Re)Actors and related architectures (especially when speaking about fine details of implementing it) is a huuuge subject. As a result – it isn’t possible to fit all of this discussion into one 90-minute presentation, so pretty much inevitably there will be remaining questions. For further information, you can either to...
contact ‘No Bugs’ over e-mail (or via his website), or to wait for Vol. II/Vol.III of his upcoming book on "Development & Deployment of Multiplayer Online Games". In Vol. II, he discusses (Re)Actors as such and Client-Side (Re)Actor-fest Architectures, and in Vol. III – he speaks about the Server-Side.
Questions?
Acknowledgement
Cartoons by Sergey GordeevIRL from Gordeev Animation Graphics, Prague.