Estimation
- 要評估的指標
- latency
- throughput
- capacity
- Database 估計
- 沒特別指定的話,可以預估 single relational database 可以處理 read & write 10K per second
- single relational database 的容量可以抓 3 TB
- redis 可以抓 100K,但是受限於 memory,可能抓 30GB
- 可以問的問題類型
- 總共有多少用戶?
- 有多少活躍用戶?
- 每個用戶平均每天使用多久?
Network
Load Balancer
- type
- application load balancer (ALB)
- OSI layer 7 (Application layer)
- 可以根據 request header, URL, query string 來做 routing
- 可以 validate / terminate SSL
- network load balancer (NLB)
- OSI layer 4 (Transport layer)
- 可以根據 protocol (TCP, UDP, IP..), destination port etc 來做 routing
- 一般來說預設會 pass through SSL
- 比較適合應付高流量
- strategy
- round robin
- least connection
- resource-based
- weighted variants of the above
- 可以把上面說的各種情況多加入 weight 的考量
- random
- 優點
- resilience
- 可以關注到某個 instance down 了,自動把 request 轉到其他 instance
- scalability
- 後面的 instance 可以 horizontal scale
- 和 API Gateway 的差異
- API Gateway 除了 load balancing 會有更多的功能,例如 rate limiting, authentication, authorization, request validation, caching, logging etc
CDN (Content Delivery Network)
- 把靜態資源放到離使用者地理上比較近的地方,加速存取速度
- html, css, js, image…
- 這些資料不該頻繁改變
- 本質上是靜態資源的 cache
- types
- push
- 把新的資料推到 CDN
- 如果靜態資源很多,開銷會很大
- pull
- lazy
- 當有 request 進來時,且 CDN 沒有該資源,才會去 origin server 拉資源
- 第一個 user 會比較慢
Maintain consistency
- 確保 unique
- bloom filter
- 因為存在 service 的 memory,有最高的 throughput,但是可能會有 false positive
- 不好讓多個 service 共用
Queue / Messaging
- 如果系統是 synchronous,可能會有 scalability 的問題
- 會被最慢的 component 所限制 (ex: payment service)
- role
- 優點
- 缺點
- 現在無法知道 message 被處理的情況,sychronous 可以直接得知成功與否
- 增加 latency
- model
- message queue
- 讓 queue 分配 message 給某個 consumer
- publisher / subscriber (pub/sub)
- 可能會有某個 event 想被 publish 給多個 consumer (subscribers)
Protocol & Send/Receive data
- TCP
- UDP
- http
- websocket
- duplex (two-way) communication
- 只會建立一次 TCP connection
- load balancer 可以會遇到問題
- long polling
- client 送 request 給 server,server 不會立刻 close connection,而是等待有新資料或 timeout 才回應
- 某些不能用 websocket 的情況下,可以用 long polling 來模擬
- 但是在一些框架或語言可能不好實作
- gRPC
- RPC
- remote procedure call
- 把一些 service 包裝成像 local function 一樣,就可以像調用本地函式一樣使用 remote 的服務
- google 開發的 RPC 框架
- 用 protobuf 作為 IDL (Interface Definition Language)
- binary protocol
- 非 readable,需要 encode / decode
- 但比 json 小
- .proto file
- 定義 message 的格式
- 描述了 interface 長怎樣
- protoc
- 用來 compile .proto file,根據指定的程式語言,產生 client / server code
- 用 http/2 來傳輸
- 不能用在 browser
- 適合用在內部服務之間的溝通
- GraphQL
流程
- User perspective
- 描述身為 user 期待看到什麼東西
- 這裡可以先簡單介紹這個 app 的大概邏輯,之後 marketplace 再針對不同 role 探討資料和使用情境
- 也可以詢問使用的平台
- Marketplace
- 詢問要支援的用戶數量,以及活躍用戶數量
- 如果有多種用戶,也要分開討論
- ex: 叫車服務會有司機和乘客
- 有更多角色後,可以開始根據角色討論他們的 perspective
- 取得一些數字
- 考慮 sotrage 以及 throughput
- 叫車服務範例
- 乘客總數量、活躍乘客數、每月乘客需求趟數
- 司機總數量、活躍司機數、單趟平均時間
- throuput
- 活躍用戶
- refresh rate
- 每個 user 平均打開 app 的次數
- 平均打開 app 會用多久
- Rough design
- 探討資料的傳遞
- 根據不同 role 去講他們應該傳送什麼資料,用什麼協定,request 的頻率 (request per second)
- 討論的時候可以用 average,但是會有 peak time,可以考慮 X2, X4, X10
- 探討資料的儲存
- 要準備一些前提,比如假設單一資料庫每秒可以 insert 5K 筆資料
- 可以討論不同的 sharding
- 考慮怎樣存可以讓大小減少
- 評估這樣分是否可能導致 sharding uneven
- 怎樣的切法可以讓 query 盡量不要跨 shard
- 每個階段也可以探討 throughput
- 開始根據情境設計不同的 service 來表達他們的交互
Tips
查找
- 能不能用地理資訊來做 hashing
- 能不能用 geo index
工具 & 技術
- headless browser
- 沒有 user interface 的 browser
- 但是依然有 rendering engine 和 js interpreter。可以用來得到最終的 html
- Cyclic redundancy check (CRC)
- 一般用在檢查封包是否有錯誤,但是我們也可以用來檢查某個檔案是否有被修改,好做 sync
- CQRS (Command Query Responsibility Segregation)
- 把 read 和 write 分開
- 一個 storage 針對 read 做 optimize,另一個 storage 針對 write 做 optimize
Unique ID
- UUID 是 random 且 human-readable(不會有相近的 char,比如 0 和 O)
- 但是太長
- 可以用不同的 encoding 壓縮長度
- 因為 UUID 用的 charactor 是 0-9, a-f,所以可以用有更多種 charactor 的 encoding 來壓縮
- BASE62
- BASE58
- BASE62 但不包含容易混淆的 0, O, I, l
- BASE64
Other
- 每個 Phase 可以多和 interviewer 討論,確認走在正確的方向上
- 面對面試官給的數字可以嘗試為了好算向上抓一些
- 延遲任務
- 如果遇到因為某些原因需要晚點才能做某個任務,可以用 queue 來處理
- Cache 除了用專門的 cache database 做,Server 自身也可以用 memory 來 cache
- 對於先搶先贏的系統不一定要追求公平,只要達成目標即可
- 對於搶票機制可以做 pre-populate,事先在 database 生好指定數量的票,這樣就可以只 lock 某個 row,不用 lock 整個 table