LMAX may be appropriate ..
LMAX people first implemented traditional ones, then they realized participants (with bursts) and found that the actors spent most of their time in bursts. Then they switched to single-threaded architecture. Now the destroyer is not the key to architecture, the key is a single-threaded BL. With 1 author (one stream) and small objects, you get a high cache hit and no complaints. To do this, they need to move all the long code from the Business level (including IO). Now they use a destroyer for this, basically it's just a ring buffer with one script, which was used for some time in the device driver code, but on a huge message scale.
At first I have one disagreement with this, LMAX is an acting system. Where you have 1 actor for all BLs (and destroyers connect other actors) .. They could significantly improve the actors' system instead of jumping to 1 actor for BL, namely
- You do not have a large number of services / actors, try using commonly used components in one service. (this appears again and again in SOA / distributed systems).
- When communicating between subjects, not many to 1. use dots from point to point. (Like all service buses!)
- When you have queues of points in a point, make sure the tail is a pointer to a separate area of ββmemory. With 2 and 3, now you can use blocked queues, and in queues / threads there is only 1 writer (and you can even use not temporary 256, but the YMM bit writes to the queue). However, the system now has more threads (and if you correctly made 1 relatively small number of messages between the participants). Queues are similar to disruptors and can process many entries and can use the ring buffer style.
With these actors, you have a more modular (and therefore main table) system (and the system can run more actors to process queues - 1 writer entry!)
In your case, I think that 20% of the changes per hour are huge ... Are queries always included in memory objects? Do you have hash tables / memory indices? Can you use read-only collections? Does it matter if your data is old, for example, Ebay uses an update for 1 hour in its collection of elements, so the collection of elements itself is static. With a static collection and static element instructions, they have a static index, and you can quickly find and find elements in memory. It is restored every hour, and when it is completed (it may take several minutes to recover), the system switches to new data. Please note that the elements themselves are not static.
In your case with a huge domain, a single thread can get a low cache level. It is different from LMAX, which has a small domain for each message that needs to be transmitted.
An agent-based system can be better, namely because a group of entities can be grouped and therefore has a high cache hit. But I need to know more. for example, validation validation, auditing, logging, etc. are probably a good plan. Less code = smaller objects = higher cache hit and LMAX objects were small.
Hope this quick reset helps, but it's hard to just look.