List functional requirements for the system (Ask interviewer if stuck)...
Upload video
Watch video
search for video
List non-functional requirements for the system...
high availability
large volume of videos
low latency
Estimate the scale of the system you are going to design...
10,000 tv shows and movies
60 minutes average length of content
1 GB average size of content
upload 100 new pieces of content daily
10 million concurrent users
uploaded media transcoded into 4 different formats
3 different resolutions offered to each user
content chunked for every 10 minutes of content
content estimate:
10,000 * 1 GB = 10,000 GB of content or 10 TB of content (1 format) which means 40 TB of content for all formats
upload estimate:
100 * 1 GB = 100 GB of content added daily
streaming estimate:
10,000,000 users * 1 GB of streaming content = 10,000,000 GB of data streamed concurrently or 10 PB of data streamed concurrently, with 3 different resolutions this means 30 PB of data streamed
I think the best way to store the content would be a blob storage solution such as AWS s3.
Define what APIs are expected from the system...
Several APIs would necessary for this system. Auth would be the first system which would take a username and password and return an auth token on successful login or return a failure when a invalid username or password is encountered. This system would also need to account for changing passwords.
The next API would handle uploading videos to the library and then transcoding the raw video into several formats that would be useful for streaming videos on different content viewers such as tv or mobile. As well as handle transcoding to different resolutions. This is useful for volatile internet connection i.e. user wants to stream in high resolution but their internet connection doesn't allow for such large formats so we stream a lower resolution for the user. The transcoder will interact with the blob storage to store the transcoded media in unique paths.
Watching videos will also require a seperate API which will interact with the blob storage. When a user streams a video the video player will queue up chunks of the video based on the user's goal video format and video resolution. At the beginning of the video the chunk 0 will be queued up and ready to watch. As the user watches the chunk0 the chunk1 will be queued up to buffer and so on. After chunks of video are watched they can be removed from the video player. If a user wants to backtrack a video or rewind we may need to queue up a previous chunk to the viewer. This API will require calls to retrieve chunks of video from the blob storage.
Searching and browsing the content will require interaction with the blob storage as well. The landing page will display to the user curated content that the user may find enjoyable. This is determined using an algorithm to match content to the user based off of viewing history and similar videos consumed.
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
Blob storage makes sense to store the media and their different formats, resolutions, and chunks.
NoSQL or SQL DB will be required to keep track of the content and its path to the blob storage. Fields necessary would be content id, chunk no, path to blob, resolution, and format, content name, description, tags or subjects
SQL DB to keep track of user information such as names, profiles, passwords, emails, settings
NoSQL DB to keep track of viewing history and search history and recommended content
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design...
User/Client
LB which first determines user location will route to an open server in a DB near the user for the Auth endpoint for validation
Successful validation will forward the request to the main API which will make requests to the search API. This request prepares the landing page which will display recently watched content as well as recommended content, preparing preview content for the user
When a user selects content to stream the streaming API will prepare the initial chunks of content based on desired format and resolution, preparing the viewer for streaming the content
If a user wants to search for content the search API will make requests to the local CDN which houses user favorite content and popular content a user is most likely to watch based on the suggestion algorithm. If the content isn't available in the CDN then a request is made to retrieve the content from the blob storage, preparing initial chunks to be streamed to the video player.
Uploading content is a admin feature which isn't available to the common user. An admin will prepare content to be uploaded which is queued up for the transcoder service. The transcoder service picks up the raw content and transcodes to several different formats and resolutions which is written to the blob storage and an entry is written to the SQL DB to keep track of the paths in the blob storage.
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
user/client -> LB -> Auth Service -> Main API -> OpenConnect CDN
-> Main API -> Search -> OpenConnect CDN -> DB -> Blob Storage
-> Main API -> Stream -> OpenConnect
-> Main API -> Stream -> DB -> Blob Storage
-> Main API -> Upload -> Queue -> Transcoder -> DB -> Blob Storage
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Main API
The main API interfaces with all the APIs that handle the most common features such as search, stream, and upload. The main API determines which steps are necessary for a request depending on the goal of the request. For example, the upload API will need to interface with the queue, the transcoder, and then finally output transcoded media to the blob storage and DB to keep track of the transcoded media's destination. The search API needs to first check the OpenConnect CDN to see if the media is available in the cache. Doing so is much quicker than searching the entire library, keeping latency to a minimum. This means it is important to keep the CDN up to date based on a user's recently viewed content and recommended content. Searches to the entire library are inevitable. When a search does need to check the library the search API will query the DB to determine the path to the blob storage and return the initial chunk for streaming. Similar for the Streaming API, initial content chunks will need to be readied for the goal format and resolution as well as similar resolution chunks in case internet quality fluctuates.
Explain any trade offs you have made and why you made certain tech choices...
Blob storage makes sense for storing large amounts of content for relatively affordable price.
CDN or OpenConnect was chosen to help reduce latency and buffering when streaming content. Keeping the most likely to be streamed content ready means we can eliminate the need to stream large quantities of data from the entire library.
NoSQL DB for storing content information and viewing history makes sense the DB scales well horizontally and can be partitioned relatively easily. Since the service is read heavy the nosql DB makes sense since reads are performant.
SQL DB for user information makes sense since we have a general schema for this type of information that really doesn't need to be flexible.
2 tier Load balancer to direct users to nearby zones based on location and server availability to help spread the load. Since users in one zone may consume different content than users in another zone this makes sense to keep separate CDN Open Connect based on zone.
Try to discuss as many failure scenarios/bottlenecks as possible.
Scale is challenging for streaming millions of concurrent users. This will require the system to have many servers available to handle auth, search, upload, and streaming capabilities.
Uploading content and keeping the CDN current can run in a background process with a priority queue and data messaging system.
Bottleneck could include many users trying to consume the same popular content at the same time. All the more reason to make sure this popular content is available in the CDN for quicker viewing.
Several resources become unhealthy at the same time. Need additional resources to replace the unhealthy resources
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?
Auto scaling API services based on current user demand. When user demand is high will want more resources available to help keep the system at a healthy load. Scaling could be determined on current load. When load is light resources can be scaled down to prevent resources from sitting idle i.e paying for resources when they are not used.
Uploading content runs in the background. This could be a candidate for using spot resources which are far cheaper than on demand resources. The only tradeoff here is it may take longer to upload content when AWS needs the spot resources in a pinch.
Displaying trailers or previews. This would required storing a small chunk of content for each video in the CDN to be readily available. Think of this as the content that plays when a user hovers their mouse or cursor over the video thumbnail. This creates a nice user experience and the user may be more likely to watch the content as a result.