My setting is the following (Please assume that this points are entirely rock solid unchangeable, some for good reasons some: "just because"):
- In a super scalable microservice environment i receive messages
- These message have a logical order (a timestamp that they bring with them)
- The messages are fed into a messaging system
- The messages are idempotent
- As soon as a message has arrived in the data storage it is okay to discard any older message for the same objectId
- Neither the technical order of the messages (the order of the publishing to the system) can be guaranteed nor its uniqueness (messages can be delivered multiple times)
- Consumers are consuming messages in a highly parallel fashion
- At the end of the processing of the messages most of them will be stored in a SQL Database
- No hard consistency constraints apply (eventual consistency can be applied)
- Using Kafka order other event streaming platforms is too expensive because of its total cost of ownership
So the central problem i am facing is: What to do if a older messages gets processed after a newer one.
Here is a simple example, lets say the following messages are processed in this order:
{
objectId: '4711'
logicalOrder: 2
content: "World"
}
{
objectId: '4711'
logicalOrder: 1
content: "Hello"
}
In the end the field content
will be written to the database. So if i do nothing special about it, the result will be wrong:
+----------+---------+
| objectId | content |
+----------+---------+
| 4711 | Hello |
+----------+---------+
Now the first thing that comes to mind is adding the logicalOrder as a column and then there are two approaches.
- Adding everything that is processed to the table (keeping up the ability to easily batch insert records)
- Checking if something newer (according to logicalOrder) is in the table and only write to the table if there is no newer dataset in the table
In the first case we will end up with this:
+----------+---------+--------------+
| objectId | content | logicalOrder |
+----------+---------+--------------+
| 4711 | World | 2 |
| 4711 | Hello | 1 |
+----------+---------+--------------+
Now here comes the questions:
- What do you think is more performant in a SQL environment? Taking the overhead of checking first before writing to the table or
- using a PARTITION BY fancy sql statement to always select the entries with the highest logicalOrder evertime data is read (maybe also a cleanup job will be needed to free storage and to bring back performance).
- Do you encounter similar problems?
- How did you solve them?