Room data: assuming 1k of metadata for each room, total data is 100k * 1k = 100Mb
Request volume:
// Manage room inventory
POST /rooms -> Room
{
id, //output
name,
buildingId,
floor,
address,
lat, // output
long, // output
capacity,
videoLink,
status, // output
...
}
GET /rooms/
DELETE / PATCH
// Find rooms
GET /rooms?lat={}&long={}&buildiingId={}&floor={}&capacity={}&time_start={}&time_end={}&
// Reserve room
POST /reservations -> Reservation
{
id, // output
owner, // output. Owner is the authenticated user
participants,
timeStart,
timeEnd,
}
// Manage reservations
GET /reservations/
PATCH / DELETE
// User table is omitted
// Building table is omitted
Room table (100Mb)
Reservations
We will use a relational database for its strong consistency.
Reservations: per day 2M *100b = 200Mb. Yearly growth is 200Mb * 365 = 70Gb.
Both tables are very small and can be hosted on a single instance of PostgreSql.
In addition, since the room table is very small, we enable full text index on name and address, and geo index on lat & long. Floor, capacity and status are also indexed.
For reservation table, we index timeStart and timeEnd.
Gateway sits in between client and other services to act as load balancer, SSL termination, authentication, rate limiter, etc.
Room service handles room management and search requests.
Reservation service handles reservations.
Both services talk to the tables int the same database.
Room management (using room creation as an example):
For an update or delete request, reservations may need to be changed.
For a room search request
Reservation flow:
Reservation:
Caching
Cleanup:
Database:
Room service, reservation service and job service are stateless and can be horizontally scaled for high availability.
For job queue, we can choose a managed queue (like SQS) or Kafka. The message volume is not high so we probably don't need extra partitioning.
For the database, we should enable high availability mode (having standbys with replication, read replicas)
Traffic spike: