Suppose we have 100M users/10M DAU.
So around 1.5kwrite QPS and 15k read QPS.
Metadata Server
Chunk Server
User(user_id, email....)
File(file_id,file_name, file_version, user_id)
Chunk(chunk_id, file_id, )
Devices(device_id, user_id, )
We basically split into 3 big modules:
Metadata Server:
Chunk Server:
notification server
Uploading path:
Notification path:
Downloading path:
Chunk servers.
Polling/Long-polling/Websockets
How to save storage cost?
Data replication/durability
Normally, we can relies on the Cloud Storage's data replication for our durability. Usually they already did that by replication and we don't need to do that again.
Since metadata server does lots of read, we can have a in-memory cache to help with that
The database choice on metadata DB: we can choose relational DB as the write QPS ins't high and we need strong consistency
It is possible transimission failed between client and chunk server side or the chunk server to cloud storage side. As mentioned above, we use the database status tracking if the uploading is sucess or not and use checksum to decide if the data is corrupted or not. Otherwise we have to ask clients to retry with exponential back-off
Sharding: we need to shard our metadata DB in the future. Apparently we can shard by file_id. The another option is user_id. The advantage of using file_id is to prevent hotspot issue though sharding by user_id is better during fanout.
Scalab
We can add monitoring to monitor our service SLA. It should be very reliable.
CDN: on the edge proxy can improve latency a lot though it needs extra cost