ticket system

System DesignE-commerce & Payments

Topic: ticket system

Interviewer: haha王国

Interviewee: 左茜

Level: L4 (Experienced Individual Contributor)


Topic

Mock System Design Interview Summary

Interview Overview

Date: 5/15/2022

Target level: L4

Duration: 45 minutes

Topic covered: Online ticket system

Drawing tool used: whimsical.com

Requirements

Functional requirements

Movie ticket system

Support different location

Movie, User, Cinema - Room, City

In each city there may be many cinemas

Payment

MovieTimeline

Non functional requirements

User amount: 1M visit per day

100K tickets per day

100 cinemas in total

More functional requirements

User login the website

User search movies in different ways

User can choose a movie and put it into cart

User chooses seats

Payment

Need to resolve conflict if 2 different users choose the same seat

Non functional requirements

Scale of the system. Scale fast within limited time

Optional

Get notification once there is a seat

1M / 24 / 3600 = 15 times/second

Peak traffic (popular movies, sold with 2 minutes)

100 * 200 / 120 = 200 times/second

4 + 1 = 5 machines

System Design

21:00

System architecture

Choosing sql vs no-sql.

Choosing mySQL: Low QPS, convenient to use

Add data balancer

Add cache to reduce read loads

Q: Searching for ticket vs ordering tickets. Should we have one service or two separate services?

A: need multiple services

Q: How to handle holding of ticket for 1 hour?

A: add column called hold_time, hold_Expire_time

User can choose a movie, put it into cart, hold the movie for 1 hour from database level, - unsold database subtract 1 from the table cron job

Data subtract 1 from the table

We need some API to finish the cronjob, e.g. checkAvailable(movieID, cityID, )

Alternative:

We don’t need cronjob

User A chooses a movie, and purchases the last ticket

User B chooses the same movie to purchase

Check the hold time of A. if it’s more than 1 hour, then user B can purchase the ticket

Q: Do you want to put all data in mysql?

A: yes. Unclear how to make it work across sql and noSQL

Q: if we increase the number of cinemas to 10,000, what do you need to do to scale

A: we can scale horizontally. Or we may use noSQL database.

Q: how to handle payment failures?

we received money but the ticket status may not have changed

A: use ACID protection. we received money, we need to refund money

Q: how to notify users when tickets previously unavailable becomes available again?

A: Email, SMS message

Q: what mechanism do we use to detect such situation?

A: we can use a scheduler

Q: Any additional improvements?

A: monitoring system for database, payment, and search.

For 2C system, we should track user behaviors; useful business information

Interviewer and Audience Feedback

Interviewer:

Overall is good. Can satisfy L4 requirements

Requirement gathering is clear

System design: I reduced the difficulty

System design: the drawing is not very clear in some area. Overall design is fine

Database choice is good

There can be improvement of detail area.

I wanted to discuss the DB schema design and tradeoff.

Interviewee:

The question is well chosen. It’s not a highly scalable system.

The data size is not very big.

OOD

Lots of details. I wasn’t able able describe things completely

We ran out of time for deep dive

I should add more details for scaling

===

Soft skill

Audience

Need to clarify requirement more

Too quickly jumped into OOD

Requirement -> resource -> data flow -> architecture -> scale up

Audience

Are the requirement too detailed?

A: about right

Similar to paper requirement. The time is insufficient for detail design

A: L4, we didn’t go into details

Hard skill

Interviewer

In the design of online resource, it’s split into multiple databases

Ticket database vs transaction database

Requires coordinator service

This may be too hard for L4

Movie database is good candidate for sharding, due to geography

Conflict resolution: add to cart and then put into hold

The best is to add lock during transaction.

What does coordinator service do?

All database needs to be reliable. Sometimes the money successfully was reduced but ticket is not reserved.

Go through a flow:

Choose a seat. Add lock to the seat

Send request to coordinator service. 2PC

Coordinator service send prepare for all databases. Databases send back ack.

Coordinator service send comment to all databases. Databases send back ack

Is retry required?

The most simple way is not to retry.

Why do we need to split into different databases?

If we use the same database for transaction and ticket

Since transaction needs to communicate with other external companies

Transaction DB relies on other companies

You can put in the same database, but it is harder to extend

I want to know available tickets

Ticket search service -> rename to movie search service

Why split into different DBs?

Reservation, ticket, etc.

Due to microservice architecture, each microservice need its own database backend

Why do we need to use microservice architecture?

It will be simple to use single service

Pessimistic or optimistic locking.

Big systems usually use microservice architecture

Regardless of whether to use microservice or single service, coordinator service is needed

2PC is not good

Should use saga

Coordinator service:

It’s better to use saga than 2PC

A ticket comes in, generates an ID

Payment is an external system; it can be very slow

Using 2PC you need to hold the transaction for a very long time

Payment succeeds: then we can proceed to the next step

Payment fails: then we can rollback

It’s better to use a local transaction.

To avoid clicking too fast, you can generate an ID for each user request

During payment and ticket reservation, we can use the same ID

Normally should use Saga not 2PC due to invoking external systems

If payment fails, the coordinator can rollback the original transaction.

Reason using saga: due to sequence in different actions.

Distributed transaction, 2PC, saga: saga orchestration, saga choreography

Reasons to use saga:

Payment service is invoked by API

The transaction is more suitable to saga, because it’s step-by-step

Internal transactions between 2 bank accounts, then use 2PC

If transaction between 2 banks, then use saga

Use seat to purchase. Should we have a queue for each seat?