Monolith uses a collisionless hash table and online training to solve the two key challenges
Collisionless hash table
This uses cuckoo hashing
The hash table doesn’t insert all IDs (IDs are identifiers of some sort of feature) but only the more popular ones (because this gives better recommendation accuracy) and evicts old keys
IPS is split up into 3 layers, with data hashed across nodes using consistent hashing
Application layer
Flink jobs add real-time data into IPS
Spark jobs add batch data into IPS
Compute cache layer
This does the actual querying + merging, etc.
Storage layer
Layers communicate using Apache Thrift (a protobuf alternative)
To prevent time slices of a profile from growing indefinitely large, these are either compacted or truncated
In compaction, the value is updated with the given reduce function (e.g. sum or max)
This is similar to computing incremental motor temperatures, etc.
The caching layer is a super simple map of user id -> an entire serialized and compressed profile
Periodically this is flushed to disk and on a cache miss it is loaded into memory
There is a separate write table to separate read and write traffic so read workloads (more important) don’t have as much lock contention in the main table
Periodically the separate write table is merged with the main table by applying aggregate functions (e.g. clicks are summed over the past few seconds, etc.)