// For retrieving top-k results
GET /topsites?k={k}&interval={1m|1hour|1day|n-min|...}×tamp={time} ->
{
k,
interval,
timestamp,
topK: [
{url: "", count: }
]
}
Capacity estimation:
We might need to ingest:
When a request enters APIGateway, it sends the url to IngestService, which puts it on IngestQueue. Each message contains the url and the timestamp.
Persistence service takes the message off IngestQueue, and persist into blob storage, partitioned by hour. This is our raw data.
A real-time processing service (Spark streaming or Flink) takes message of IngestQueue, and aggregate it by the minute. It stores minute level aggregation in AggTable. This can be a no-sql database, such as DynamoDB, Cassandra.
A BatchProcess service runs in the background, and aggregate data into larger granularities (hour, day), and stores it into AggTable in descending order.
When querying for top-k for a given interval and given timestamp, the query service looks for the more appropriate table with the right granularity (e.g. if top-10 on Nov 10), then it looks for the daily aggregate table for Nov 10, and retrieve top 10 results.
How to handle late data
How to show a leaderboard
Handling failures
How to scale the service
Data retention