System requirements
Functional:
- Search for Theaters:
- Users should be able to search for theaters by city or ZIP code.
- Select and View Movies:
- After selecting a theater, users should be able to view the list of movies being shown in that theater.
- Select Showtimes:
- Users should be able to select the available showtimes for movies.
- View Available Seats:
- After selecting a showtime, users should be able to view available seats.
- Select and Book Seats:
- Users should be able to select seats and proceed to the booking process.
- Make a Purchase:
- Users should be able to finalize the booking by purchasing tickets.
Non-Functional:
- Consistency:
- Once a booking is made, it should be consistently maintained to avoid double bookings.
- Concurrency:
- The system should handle multiple users interacting simultaneously, ensuring consistent bookings.
- Scalability:
- The platform should efficiently manage a growing number of users and data.
- Fault Tolerance:
- The system should be designed to withstand and recover from failures.
Capacity estimation
- 100 million sales transactions per month (38 transactions per second)
- Let's assume we have 30 times more reads than writes so 1000/rps )
API design
Let's assume we want to create a RESTful for demo purpose:
- Search api: GET /theaters?city={cityName}&zip={zipCode}
- List Movies in Theater: /theaters/{theaterId}/movies
- List Showtimes for Movie: GET /movies/{movieId}/showtimes
- View Available Seats:GET /showtimes/{showtimeId}/seats
- POST /bookings Body: { "userId": "", "showtimeId": "", "seatIds": [] }
- Finalize Booking: PUT /bookings/{bookingId}/finalize
Database design
Entities and Their Attributes:
- User
- id (Primary Key)
- name
- phone_number
- password
- Theater
- id (Primary Key)
- name
- location
- number_of_screens
- Movie
- id (Primary Key)
- title
- duration
- genre
- rating
- ShowTime
- id (Primary Key)
- theater_id (Foreign Key referencing Theater)
- movie_id (Foreign Key referencing Movie)
- start_time
- end_time
- Seat
- id (Primary Key)
- screen_number
- seat_number
- showtime_id (Foreign Key referencing ShowTime)
- Booking
- id (Primary Key)
- user_id (Foreign Key referencing User)
- showtime_id (Foreign Key referencing ShowTime)
- seat_id (Foreign Key referencing Seat)
- booking_time
- status (e.g., reserved, paid, canceled)
Now, let's visualize these relationships in an ERD:
USERstringidPrimary Keystringnamestringemailstringphone_numberstringpasswordBOOKINGstringidPrimary Keystringuser_idForeign Key referencing USERstringshowtime_idForeign Key referencing SHOWTIMEstringseat_idForeign Key referencing SEATdatebooking_timestringstatusenum: reserved, paid, canceledTHEATERstringidPrimary Keystringnamestringlocationintnumber_of_screensSHOWTIMEstringidPrimary Keystringtheater_idForeign Key referencing THEATERstringmovie_idForeign Key referencing MOVIEdatestart_timedateend_timeMOVIEstringidPrimary KeystringtitleintdurationstringgenrefloatratingSEATstringidPrimary Keyintscreen_numberintseat_numberstringshowtime_idForeign Key referencing SHOWTIMEmakeshasdisplayed inincludesreserved in
Explanation:
- Users can make multiple Bookings.
- Each Theater features multiple ShowTimes.
- Each Movie has associated ShowTimes when it is screened.
- ShowTimes offer multiple Seats, which can be booked.
- Bookings link a User, ShowTime, and Seat together.
Feel free to further elaborate on any specific areas or raise questions you have regarding the database design!
High-level design
- Client UI:
- Web or Mobile Client: A user-facing interface that interacts with backend services. Depending on user interactions, it sends requests to search, book tickets, and manage user accounts.
- API Gateway:
- Role: Handles routing, request validation, and authentication.
- Scalability: Typically horizontally scaled using an application load balancer for HA.
- Auth & Routing: Ensures requests are authorized and routes them to respective microservices (e.g., booking, search).
- Identity Service:
- Purpose: Manages user identities and sessions.
- Implementation: Can use a third-party service (e.g., OAuth providers) or an in-house service.
- Integration: Communicates closely with the API Gateway to authenticate requests.
- Microservices:
- Booking Service:
- Handles the lifecycle of user bookings.
- Interacts with the Booking Database for transaction management.
- Search Service:
- Manages queries related to theaters, movies, showtimes, and available seats.
- Works with the Search Database for optimized searching capabilities.
- Booking Service:
- Databases:
- Booking Database:
- Stores transactionally critical data (bookings, users).
- Relies on relational database for ACID properties.
- Search Database:
- Optimized for read-heavy operations (e.g., theaters, movies, showtimes).
- Can utilize a combination of relational databases and caching for efficient queries.
- Booking Database:
- Load Balancing and HA:
- Application Load Balancer:
- Ensures web service instances are highly available.
- Supports automatic scaling based on incoming traffic.
- Application Load Balancer:
Here's a simplified diagram illustrating these components and their interactions:
flowchart TD C[Client UI - Web/Mobile] -->|HTTP Requests| AG[API Gateway] AG -->| Auth/AuthZ | ID[Identity Service] AG -->|Route to| B[Booking Service] AG -->|Route to| S[Search Service] B -->|CRUD Bookings| BD[Booking Database] S -->|Query Data| SD[Search Database] subgraph DBs [Databases] direction TB BD -- Search DB Cluster SD end C <--> LB[Application Load Balancer] <--> AG
There was an issue generating the diagram for the code above.
Explanation:
- Client UI communicates with the API Gateway, which is centrally responsible for authentication and request routing.
- API Gateway ensures valid sessions through the Identity Service.
- The Booking Service and Search Service each have their own dedicated databases, emphasizing separation of concerns and scalability.
- Load balancing is crucial across different services and database clusters to maintain availability and responsiveness under varying loads.
This architecture supports modularity, ease of scaling, and separation of concerns, ensuring that each microservice can be independently developed, deployed, and scaled.
If you have specific questions regarding any component or need further elaborations, feel free to ask!
Request flows
- User Lands on Homepage:
- The client application requests theaters based on the user's current location.
- This triggers an API call to the Search Service, which returns a list of theaters sorted by proximity.
- Selecting a Theater:
- User actions trigger API calls to the Booking Service to fetch available movies for the selected theater.
- Movie Selection:
- Requesting specific movie details, including metadata and show times, from the Booking Service.
- ShowTime and Seat Selection:
- User selects show time, triggering an API call to fetch available seats.
- Add to Cart:
- Seats selected are added to a cart, with price calculation resulting in an API call using
addToCart.
- Seats selected are added to a cart, with price calculation resulting in an API call using
- Checkout:
- User proceeds to payment, interacting with a payment gateway.
- After successful payment, a booking is created using the
/bookingAPI.
- Finalization:
- User is presented with booking details and receives an email confirmation via the Email Service.
This sequence diagram covers the entire user journey from browsing to booking, including interactions with backend services to ensure seamless processing and feedback to the user. If you have further questions or need clarity, feel free to ask!
Detailed component design
1. Client (Web/Mobile UI):
- Functionality: Provides the user interface for searching, selecting, and booking tickets.
- Technology: HTML/CSS/JavaScript for web or native frameworks for mobile (like Swift for iOS, Kotlin for Android).
2. API Gateway:
- Role: Central entry point for all client requests, handling routing, authentication, and authorization.
- Features: Rate limiting, API key validation, logging, and monitoring.
- Technology: Solutions like AWS API Gateway, Kong, or custom-built using technologies like NGINX.
3. Identity Service:
- Purpose: Manages authentication and session handling.
- Features: OAuth2, JWT tokens for stateless sessions.
- Technology: Third-party providers (Auth0, Firebase Auth) or custom in-house service.
4. Booking Service:
- Functionality:
- Manages booking lifecycle, including CRUD operations.
- Handles checkout process, pricing updates, and payments.
- Features: ACID transactions for booking creation, rollback mechanisms for incomplete bookings.
- Technology: Developed as a microservice using frameworks like Spring Boot, Node.js.
5. Search Service:
- Functionality: Handles all search functionalities for theaters, movies, and showtimes.
- Features: Caching for frequently accessed data, full-text search capabilities.
- Technology: Elasticsearch, Redis for caching, implemented using efficient REST APIs.
6. Databases:
- Booking Database:
- Role: Stores transactional data (bookings, users).
- Technology: Relational database (e.g., PostgreSQL, MySQL) ensuring ACID properties.
- Search Database:
- Role: Optimized for read-heavy operations (showtimes, theaters, movies).
- Technology: NoSQL databases (e.g., MongoDB, Cassandra) for flexible schema support.
7. Payment Gateway:
- Role: Handles transaction processing securely.
- Technology: Third-party services like Stripe, PayPal, integrated via SDKs.
8. Email Service:
- Functionality: Manages email notifications for booking confirmations.
- Technology: Third-party services like SendGrid, AWS SES, or SMTP servers.
Diagram Representation:
Here's how these components interact in a high-level flowchart:
Microservices
HTTP Requests
Auth Requests
Booking Actions
Search Queries
Payment Processing
DB Ops
DB Ops
Email Notifications
Payment Gateway
Booking Service
RDBMS: PostgreSQL/MySQL
NoSQL: MongoDB/Elasticsearch
Search Service
Client UI
API Gateway
Identity Service
Email Service
Databases
Explanation:
- Microservices architecture isolates functionalities, allowing independent scaling and deployment.
- API Gateway handles all inbound requests, ensuring security and load management.
- Components use asynchronous calls where appropriate, particularly in distributed systems, to improve performance (e.g., using message queues for non-blocking operations).
- Transactions within the Booking Service must be atomic, ensuring consistent state even in case of failures.
This detailed design aims for a robust, scalable, and maintainable system that handles high traffic efficiently while ensuring data integrity and security. If you have deeper inquiries or components to explore further, feel free to ask!
Trade offs/Tech choices
Trade-Offs & Technology Choices:
1. Database Choice: Relational vs. NoSQL
- Relational Database (RDBMS):
- Pros: Strong ACID compliance, ideal for transactions like bookings where consistency is crucial.
- Cons: Scalability can be complex due to vertical scaling limits.
- Choice: Use for booking information to ensure transactional consistency.
- NoSQL Database:
- Pros: High read/write throughput, flexible schema, easier horizontal scaling.
- Cons: Weaker consistency guarantees, complexity in handling joins.
- Choice: Use for search operations where flexibility and high availability are prioritized.
2. Microservices vs. Monolith
- Microservices:
- Pros: Scalability, independent deployments, fault isolation.
- Cons: Complexity in service orchestration, potential for inter-service latency.
- Choice: Suitable for a system requiring different scaling dimensions, e.g., booking vs. searching.
- Monolith:
- Pros: Easier development and testing, simpler deployments.
- Cons: Scalability challenges, potential for larger deployment impact.
- N/A: Less favorable for the diverse functionality and scalability required.
3. API Gateway
- Choice: Use a managed solution like AWS API Gateway to simplify authentication, routing, and logging.
- Trade-off: Can introduce latency; however, this is balanced by the simplicity and security it offers.
4. Caching Strategy
- Pros: Reduces load on backend services and databases, improves response times.
- Cons: Data consistency challenges, cache invalidation complexities.
- Choice: Use caching for read-heavy data like movie listings, with strategies for cache invalidation on updates.
5. Payment Processing
- Choice: Utilize third-party services such as Stripe or PayPal for secure transaction handling.
- Trade-off: Dependency on external service reliability, but mitigated by their industry reputation and security expertise.
6. Authentication and Authorization
- Choice: OAuth2 for robust identity management.
- Trade-off: Complexity in integration, but offers a comprehensive solution for session management and user authentication.
Diagram of Technology Layers:
Here's a tech stack representation highlighting where these choices fit within the system architecture:
Services
HTTP
Authentication
Booking Requests
Search Queries
RDBMS Ops
NoSQL Ops
Cache Ops
Process Payment
Send Email
Relational Database
Booking Service
NoSQL Database
Search Service
Cache Layer
Payment Gateway
Email Service
Client UI - Web/Mobile
API Gateway
Identity Service
Considerations:
- Caching Layer: Use technologies like Redis or Memcached for improving data retrieval speeds.
- Scalability: Every layer is designed to be scalable, facilitating independent resource scaling.
- Security & Fault Tolerance: Ensure to add SSL/TLS and robust error handling to enhance security and reliability.
These technology choices are crafted to align with the requirements of scalability, performance, and maintainability. If you want more insights into specific trade-offs, feel free to ask!
Failure scenarios/bottlenecks
Failure Scenarios and Bottlenecks
1. Database Write Scalability
- Issue: The main node of an RDBMS can become a bottleneck due to the high volume of write operations, especially during peak times.
- Mitigation:
- Vertical Scaling: Initially scale up the database node for more CPU, memory, and I/O capacity.
- Sharding: Distribute data across multiple nodes. A logical approach is sharding by geographic location (city-based) to handle localized spikes in demand.
- Distributed Transactions: Ensure consistency across shards, potentially using technologies like Google Spanner for transaction consistency.
2. Read Scalability and Query Performance
- Issue: With growing data, query performance can degrade, and read replicas alone may not keep up.
- Mitigation:
- Read Replicas: Use multiple read replicas for distributing read loads.
- Partitioning: Implement partitioning schemes within databases to control how data is distributed across a cluster.
- Indexing and Caching: Optimize queries through strategic indexing and utilize caching mechanisms like Redis for common queries.
3. Network Latency
- Issue: Latency increases with geographic distance, impacting user experience negatively.
- Mitigation:
- CDNs: Utilize Content Delivery Networks for static resources to reduce latency for distant users.
- Edge Computing: Deploy services in multiple geographical regions to bring services closer to users.
4. Service Failure and Resilience
- Issue: Individual service failures can cascade, affecting user experience.
- Mitigation:
- Circuit Breakers: Implement circuit breakers to prevent cascading failures.
- Retries and Backoff: Use exponential backoff strategies for retrying operations.
- Load Balancing and Redundancy: Use load balancers to distribute load evenly and ensure service redundancy.
5. Payment Gateway Dependency
- Issue: Relying on a third-party service introduces potential points of failure in the payment process.
- Mitigation:
- Multiple Providers: Supporting multiple payment gateway options can mitigate a single point of failure.
- Timeouts and Fallbacks: Use clear timeout settings and fallback processes for payment retries.
Diagramming Scalable and Fault-Tolerant Architecture
A representation reflects some of these strategies:
Microservices
Database
Data Request
Read/Write
Sharded Data
Sharded Data
Read
Vertical Scaling
Partitioning
Caching
Booking Requests
Search Queries
Booking Service
Search Service
DB1
DB Cluster
Partition 1
Client UI
API Gateway
Shard 1
Shard N
Read Replica
Redis Cache
Key Strategies Illustrated:
- Sharding and Partitioning: For horizontal scaling of databases to handle high-volume writes.
- Read Replica: To offload read traffic, ensuring fast query responses.
- Caching: To reduce database load for frequently accessed data.
- Vertical Scaling and Load Balancing: To handle traffic spikes effectively.
Future improvements
1. Enhanced Scalability
- Dynamic Sharding:
- Implement more sophisticated sharding logic that can adjust based on demand or geography, improving distribution of data and balancing the load.
- Automated Scaling:
- Use autoscaling policies in your cloud infrastructure to dynamically adjust resources based on real-world usage patterns and metrics.
2. Performance Optimization
- Query Optimization:
- Continuously review and optimize database queries, introducing indexing and query tuning as usage patterns evolve.
- Advanced Caching Strategies:
- Implement smarter caching strategies like using Machine Learning models to predict popular content and pre-load cache accordingly.
3. Enhanced User Experience
- Personalization:
- Integrate recommendation systems that leverage AI/ML to provide personalized movie/showtime suggestions.
- Offline Access:
- For mobile applications, consider offering offline capabilities for browsing or ticket storage when there's no internet access.
4. Security Improvements
- Enhanced Authentication:
- Move towards passwordless login options using biometrics or secure tokens to simplify user access.
- Fraud Detection:
- Implement advanced anomaly detection systems for real-time monitoring and prevention of fraudulent activities.
5. Integration of Emerging Technologies
- Blockchain for Transactions:
- Explore blockchain to provide immutable records of transactions, enhancing trust and traceability.
- IoT Integration:
- Incorporate devices like smart kiosks for ticket sales, providing more sales channels and improving accessibility.
6. Environment and Cost Efficiency
- Serverless Architectures:
- Transition to serverless models for parts of your application to improve cost efficiency and reduce latency.
- Green Computing Initiatives:
- Implement environmental monitoring to improve energy usage and make the system greener.
Timeline and Evaluation
- Phased Rollouts: Introduce new features in phases, starting with non-critical systems to test user acceptance and technical viability.
- A/B Testing: Implement for feature enhancements or new UI designs to gather data-driven insights.
- User Feedback Loop: Establish channels to gather user feedback continuously, evaluating which improvements deliver the most value