Ordering and Inventoring Management

System DesignE-commerce & Payments

Materials — open to everyone, no sign-in

Topic: Ordering and Inventoring Management

Interviewer: 慢羊羊 Tom

Level: L6 (Staff)

Additional Resources:


System Design Interview - Distributed System

8/16/2024

YouTube for the event:

https://www.youtube.com/watch?v=DT9W8vvJqrQ

Coach Ken LinkedIn:

https://commitway.com/linkedin

| 系统设计活动群 | | 职场提升俱乐部 |

Design ebay inventory system

[40]

Requirement gathering

Inventory similar to amazon

[38]

[36]

Functional requirements

[34]

[30]

Design [30 minutes remaining]

[28]

Q: return purchase ID or order ID?

A: yes

Q: why have both purchase ID and order ID?

A: let’s just use order ID

[24]

[23]

Design schema

[22]

Q: Using mysql?

A: yes. Using relational database for strong consistency

Q: are they in same database?

A: yes

Q: product, product_unit in one database, users and orders in another database?

A: let’s keep everything in one database for now

[20:24]

High level system design

[17:55]

API gateway: throttling / routing

Q: let’s skip payment part

A: ok

100k QPS, each service has multiple instances

Let’s optimize write path (order server)

Add a queue

Q: let’s talk about read QPS. Will we hit db for all read requests?

Add CDN

Q: let’s not care about images but only the items and counts

A: ok.

Let’s add a cache

[14:35]

Q: User first read from cache or DB

A: first read from cache, if there is a miss, then read from DB

Q: what’s the reading order? Tradeoffs?

A: reading from cache is much faster

[12:53]

Q: still using mysql / relational?

A: we can use both relational and non-relational

Q: 4 tables. Go through each one. May or may not belong to the same database

A:

[11]

Product and order table together in same database

Q: same DB or separate DB?

A: same DB

Q: can one DB support amazon/ebay level data

A: user can be out

Q: user table cannot be out due to a foreign key

A: change the user_id

Q: can one order contain multiple product

A: multiple

Q: how to shard order table based on product ID?

A: we just find product and inventory

[8:33]

Q: how do we shard the order table because each order contains multiple product

Q: how to shard order table?

[7:16]

A: when reading the order, we need to fan out to check the products

Q: if order table has one billion records

A: don’t shard it.

Q: so 1 bill records records in one DB?

A: let’s put order and product in separate database

[4:33]

Add queue

Q: Order ID in API, how do we generate order ID?

A: we can do plus one. We can have a unique number generator, separate service

[3]

Q: how do we get a global unique ID? High level how to get unique ID?

A: I don’t know this one

[1:40]

Q: message queue. How does the user know whether the order succeeded or not?

A: it’s a small waiting server.

Self assessment:

Order - noSQL is better

Database selection, one SQL, noSQL

Queue

Interviewer

Design incomplete

Like to know justification. Sometimes explaining why is more important

L6: no hire

Potentially downgrade to L5 may not meet L5 bar

Whole workflow. This question is difficult

Discussion:

Explain tradeoff and why

Q: Should we first explain why or first explain choice

A: First explain choice

===

Discussion

Audience: single machine machine postgres 10k is fine

Interviewer: may depend on memory, storage

Interviewee: what may be a better answer?

Interviewer: 秒杀系统

Audience: sharding not solution

Interviewer: NoSQL, partition key

Audience: 秒杀系统

Interview: Write-cache: item, remaining count

Cache: memcache paper

Machine-id (mac address) + timestamp + sequence / random number

Mysql Sequence number for multiple mysql replica

A: 1,3,5,7….

B: 2,4,6,8 …

User server + user database

Order server + order database

Inventory server + Product, Product item

Audience: Order, may be partially filled

SAGA

Databases: A & B

1 Prepare A

2 Prepare B

3 Commit A

4 Commit B

SAGA:

A: reserve 1 apple

B: reserve credit card

Fail: A: unreserve 1 apple

Succeed:

A: ship apple

B: charge credit card

Inventory

Implementation 1: write the result to database and commit

ItemID, availableCount,reserveCount,shipCount

5, 5, 0, 0

reserve 1 apple user 1

5, 4, 1, 0

Commit to database

Implementation 2: lock row

5, 5, 0, 0

reserve 1 apple user 1

[lock] 5, 5, 0, 0

Ship apple to user 1 / reverse reservation

[unlock] 5, 5, 0, 0

[unlock] 5, 4, 0, 1

====

Write to cache

Cache: inventory:

ItemID, Available, Reserved, [Shipped]

DB: inventory

ItemID, Available, Reserved, Shipped

Place order:

Application layer code:

Write to cache, available -=1

Try { Write to database, available -=1, reserved += 1

} catch (RPCException e) { … }

Conditional write, read after write