Important things

302 http response with Location header for url redirection(GET and Head) - 307 for temporary redirection ,==> Spring Sleuth - tracing in microservices, ==> https://astikanand.github.io/techblogs/high-level-system-design/design-bookmyshow, https://www.hellointerview.com/learn/system-design/in-a-hurry/introduction

Sunday, 20 June 2021

Snapchat System Design

 

Snap Chat

  • This messenger sends snaps. Plain text cannot be sent or send very rarely.
    • snap = Text + Video OR
    • snap = Text + Image.
FB-MessengerWhatsappSnapchat
Creating Groupsyyn
Encryptionyyn
MediaImages/video/documents/audiosame as fb-msgImages/video
Location sharingyyn
Storage/Backupimages,text gets stored in gallerysame as fb-msgnot allowed
Automatic Deletion on Imagesnnyes in 24 hours
Use case-messaging & sharing important documentsFor entertainment

1. Requirements

  • Functional
    • a. Sending snaps: User-A can send snap(Video, images, text) to user-B.
    • b. Holding & Deleting snaps:
      • Snapchat service should hold the message for 24 hours, if in case user is not online and snap cannot be delivered instantly. Eg: User is Flight, once user comes online snap gets delivered to him, then snapchat server can delete from its DB.
      • if user is online, service will deliver message and delete snap instantly from DB.
    • c. Searching a user: Unique userId is provided to users and all users are searched on basis of userId not phone numbers.
  • Non-Functional
    • a. User-A can add any user as his friend based on userid and send snap.
    • b. [Thumbnail to be shown to reciever.
    • c. Normal filters on video,image provided to sender
    • d. System should be Eventual consistent & Highly available.
  • Extended
    • a. Blocking the users
    • b. Following a user

2. BOE

snapchat revleaved in 2018 that number of snaps sent per day = 4 Billion. Assumed in 2021 = 10 Billion

  • QPS(Queries per second)
    • 10 Billion / 86400 = 1010 / 105 = 105 = 1 lac queries per second
  • Storage Estimates: Will try overestimate
App Message: Metadata:75 bytes, Video:1MB
  Dst_user_id(10 bytes)   Allowed 20 characters. 1 character:4 bytes
  self_user_id(10 bytes)  Apart from IP address, client will send its unique user id
  timestamp(4 bytes)      Time elapsed from epoch(1 Jan 1970) in seconds
  Text(50 bytes)          Text sent with vieo or image
  Video(1 MB)             Video message

|App message|TCP(20 bytes)|IP(20 bytes)|DL(18 bytes)|         
//Note TCP,IP,DL Headers are not stored, these are used by router not snapchat.

                    1 day         //Assuming snapchat stores offline user data for 24 hours only
Metadata  = 75B x 10 Billion = 750 Billion  = .7 TB   //1 High end computer having 1 TB Hard disk
Videos    = 1MB x 10 Billion = 10 pow 15    = 1 PB    //1000 High end computers having 1 TB Hard disk

3. API Design

  • All API's should be extensible, ie if in future want to add new parameters that can be added). Variadic Templates C++.

A. Sender call these APIs

  • Deduplication is avoided using messageId. if server finds messageId already in DB, it will consider message as duplicate and discard it.
sendMessage ( string dst_user_id,
              string src_user_id,
              uint32_t timestamp,           //sec elapsed from Epoch(1/1/1970)
              string text,                  //
              uint8_t video, 
              uint32_t messageId)           //Identifies every message Uniquely.

B. Reciever call these APIs

  • Reciever will get snaps from server in 2 ways:
    • a. PUSH: Whenever reciever comes online, server pushes the pending messages.
    • b. PULL: Whenever reciever want to get messages it refreshes and takes message from server.
struct Message_details {
  string text,
  string video_url_on_object_store,
  string src_user_id
}
GetMessages (string self_user_id,        //Pull API
             uint32_t get_messages_after_timestamp,
             Message_details[]
)

PushAllMessages (Message_details[])    //Push API

4. HLD

Requirement-1: Sending snap from UserA to UserB Steps(7-10)

  • 1. User opens snapchat app. Name resolution done using DNS.
  • 2. CDN will be hosting user feed, periodically updating the page from App Server. CDN renders the feed.
  • 3. User creates a snap, upload a (photo, Video).
  • 4. User-B and sends to App-Server using ISP in JSON/XML in http.
App-Server                                                                                  User-A
      <- HTTPS(UserA_id, dst=UserB_id, timestamp, text, Video, messageId) | TCP | IP | DL |-
  • 5. HTTPS message is decrypted using SSL Terminators.
  • 6. Load Balancer selects App server based on Least Response Time Scheduling algo and sends packet.
  • 7. Application-Server will send User_B_id, timestamp, messageId to DBFinder service.
  • 8. DBFinder:
    • Purpose of DBFinder?
      • Find and searches DB which stores table of User_B, that messageId exists or not, if not updates DB //See DB Design
      • Respond to AppServer, if messageId exits its duplicate else not
    • Avoiding Deduplication?
      • Every user's snaps are stored in DB until he reads them. Eg: When User_A sends snap to User_B. This snap is stored in User_B's table in DB.
      • AppServer will check User_B's SQL Database table that messageId exists in table or not?
        • Worldwide all snapchat clients But once message is delivered, AppServer will inform clients to reuse/reset the messageId
      • if messageId exists then its duplicate message, drop it.
    • We will place a Cache(Eg: Redis or Memcached). Redis preferred between Application server and DB.
  • 9. Video,text,images are stored in different Databases(See DB Design), user-B,timestamp are pushed on MOM, user is acknowledged using zookeeper.
  • 10. Sender Service will be subscriber to MOM and recieves (userB, timestamp). It will read DB_userB and send video,image,text to userB.

Requirement-2: Holding & Deleting snap (Steps 11,12)

  • 11. After sender service receives ACK from user that message is read, it will push MessageId, userId on MOM.
  • 12. Deletor service gets notifcation, reads messageID,userID from MOM, checks same in DB and deletes promptly.
    • cronjob would be running on Database to delete the contents if age>24 hours.

Requirement-3: Searching the user

  • Application server will delegate task to DB-Finder to search userB database, if database is not found this means user is not present.

image

5. DB Design

  • We can store information in SQL or noSQL database.

1. SQL DB Design

  • User's Table
    • Has one-to-many relationship with photo table, since 1 user can have multiple photos.
Primary Key: userID

| UserID | messageID | TextURL | VideoURL | Timestamp | src_UserID | email |
| ------ | --------- | ------- | -------- | --------- | ---------- | ----- |
| User_B | kanskna   | <>      |  <>      | 123       | User_A     |a@a.com|
  • Photo Table
    • All photos which are posted by particular user. Each photo will have incremental photo-ID
    • Photos will be stored in any distributed File Storage server: HDFS or GFS.
Primary Key: photo ID

| Photo-IDs | User-ID | Caption | location | Time of upload |   URL  |
| --------- | ------- | ------- | -------- | -------------- | ------ |
|    1      | user-A  | <>      |   <>     |  epoch time    |   -    |
|    4      | user-B  | <>      |   <>     |  epoch time    |   -    |
|    6      | user-A  | <>      |   <>     |  epoch time    |   -    |
  • Video Table //Similar to Photo Table
  • Follower Table
    • let userA(follower) follows userB(followee).
| Followee | map<Followers> |
| -------- | -------------- |
| UserB    | UserA          |

2. NoSQL DB Design

  • We can store same data in noSQL Databases(Eg: dynamoDB, Cassandra) since noSQL are highly scalable, hence highly available and low latency.
  • Photo Table (Key, value)
    • Key would photoId and value would be object containing all metadata related to photo(Eg: location/url, timestamp, size etc)
| UserID    |       <Key=PhotoIDs, value=Object_Containing_all_metadata>     |
| --------- | -------------------------------------------------------------- |
| userA     | key=photo-1, Value=Object<Location_of_photo, timestamp, size > |
            | key=photo-2, ...                                               |
```![image](https://assets.leetcode.com/users/images/a1de0852-522e-4185-ae24-6dcc09704453_1624202166.826889.jpeg)

Thursday, 17 June 2021

System Design : HOTEL booking system

 Question 1 : 

The purpose of the channel manager is to provide an easy way for hoteliers to host their listings on multiple online travel agents to increase global reach. A software that automates the tasks from updating rates to managing inventory. You have one interface to manage all of your channels


Users

  • Hotel management Systems like Taj Hotels Group: Hotel owners and managers who independently run their operations will be direct consumers. eg : Hotel Anshuman in Mahipalpur Delhi. 


  • Online Travel Agents : The channel manager will be connected to world wide travel agents like Booking.com, Expedia, Agoda.

.


USECASES

  • AS HOTEL MANAGEMENT SYSTEMS

    • Onboard onto the Channel Manager

    • Sync property information

    • Sync availability & pricing information

    • Consume Bookings 

  • AS CHANNEL MANAGER

    • Connect to different OTA’s

    • Sync Property Data  & Availability & Pricing

    • Retrieve Bookings



Friday, 11 June 2021

Design Online Coding Platform CODING BLOX (Design Leetcode LLD)

Design Online Coding Platform CODING BLOX (Design Leetcode LLD)

  • Coding Blox is an Online Coding Platform that allows a user to Sign Up, Create Contests and participate in Contests hosted by Others.
  • Each contest can have a level (LOW, MEDIUM, HIGH) and will contain a set of questions.
  • Each question will have different levels of difficulty(LOW, MEDIUM, HIGH) and score.
  • Based on the contest level, the question set is going to be decided. Contest level with LOW difficulty will have questions with LOW difficulty level.
  • Final score will be decided based on the difficulty LEVEL chosen for a contest
  • Users solve problems and get points based on the difficulty of the problems and after the contests scores of the users are updated.

Functionalities/Requirements:

  1. CreateUser <user_name>
  2. CreateQuestion <difficulty_level>
  3. ListQuestion <difficulty_level>
  4. CreateContest <contest_name> <contest_level> <contest_creator_user_name>
  5. ListContest <difficulty_level>
  6. AttendContest <contest_id> <user_name>
  7. RunContest <contest_id> <contest_creator_user_name>
  8. LeaderBoard <sorting order asc/desc>
  9. ContestHistory <contest_id>
  10. WithdrawContest <contest_id>

full problem statement & solution (Time given 90min) : http://bit.ly/leetcode-low-level-design


Simply I follow these steps for any LLD.

  1. Find out entities
  2. Find out the relationship between entities
  3. Write entities CRUD (use hashmap or JPA)
  4. Start implementing requirements

Step 1,2 and 3 => approx 30min
Step 4 => +1hr

Step 1, 2: Domain layer
Step 3: Database/dao layer
Step 4: Service layer

(Use this hashmap template to quick start: http://bit.ly/lld-hashmap-as-db-template )


Step 0Understand the problem statement and requirements

Step 1List down important entities/model/domain

In the above question list of entities are -> UserContest, and Question

image

Step 2List down the relationship between entities.
e.g.
User can register for multiple contests

User:
	List<Contest> contests

The contest can have multiple Questions

Contest:
	List<Question> questions

Now Add other fields of entities

User:
	username
	score
	List<Contest> contests -- (A)
Contest:
	name
	level
	status
	List<Question> questions
Question:
	question
	level
	score

image

image

Step 3Store entities and write entities CRUD methods (Use Method 1)
Method 1: Use hashMap to store entities,

Map<Long, User> userDb
Map<Long, Question> questionDb
Map<Long, Contest> contestDb

Write CRUD method for each entity (HashMap sample example)

Method 2: Use H2 in memory using JPA, (simple to use but need to practice more)
Create 3 DAO class, internally with the help of the JPA class we can get all CRUD methods so no need to create any methods (JPA sample example)

Step 4Create a service class for each entity and start implementing the requirement (service classes)

UserService:
	createUser(username)
	attendContest(contest id or contest object, username)
	leaderBoard()
	withdrawContest(contest id or contest object, username)
QuestionService:
	createQuestion(question)
	listAllQuestion()
ContestService:
	createContest(contestId or contest object, username)
	listAllContest()
	runContest(contestid or contest object, username)
	contestHistory()

add logic for above methods plus entity validation

image

Step 5Refactor code : extract class to an Interface, Abstract class, add enum, add exceptions, add constant, read from config
List<Contest> contests --(A) become --> Map<Long, List<Long>> userContestQuestions = new HashMap<>(); KEY : Contest Id, Value: list of question ids


If we do Step-1 and Step-2 correctly then finally we can see entities tables (these tables are only visible in case of JPA but this entity relationships are also valid if we are using HashMap)

Contest entity

image

Question entity

image

User entity

image

Wednesday, 9 June 2021

design elevator using event driven programming

 We can divide into three main components:

  1. User

    • User presses the floor button (can be up or down direction) to summon the elevator.
    • User presses the elevator button to go to the destination floor.
  2. Button

    • An elevator has buttons (ElevatorButton) inside allowing user to choose the destination floor.
    • Each floor has two buttons (FloorButton) to summon the elevator to go up or down from that floor.
    • When the user presses the button, it illuminates.
    • When the elevator reaches the desired floor, the button stops illuminating.
    • Calls placeRequest() to insert into the ElevatorRequest queue when button is pressed.
  3. Elevator

    • Open or close door.
    • Moves up/down.
    • Stores states such as direction (up/down), speed, currentFloor.

We need a queue to store all request, this can all be encapsulated in an ElevatorRequests class. When a user presses a button, this request has to be served and is added to the processing queue. Elevator requests can be scheduled using different scheduling algorithms. ElevatorController controls the elevator by giving it instructions such as move up/down, or start/shutdown. The elevator controller reads the next elevator request and serves it.

This diagram may help :)

0_1462439050435_elevator-class diagram.png