用戶系統設計

      網友投稿 1108 2022-05-28

      1 系統分析

      1.1 Scenario 場景

      注冊、登錄、查詢、用戶信息修改,哪個需求量最大?

      支持100M DAU。注冊,登錄,信息修改 QPS 約:

      100M * 0.1 / 86400 ~ 100

      0.1 = 平均每個用戶每天登錄+注冊+信息修改

      Peak = 100 * 3 = 300

      查詢QPS約

      100 M * 100 / 86400 ~ 100k

      100 = 平均每個用戶每天與查詢用戶信息相關的操作次數(查看好友,發信息,更新消息主頁)

      Peak = 100k * 3 = 300 k

      1.2 Service 服務

      AuthenticationService 負責登錄注冊

      UserService 負責用戶信息存儲與查詢

      FriendshipService 負責好友關系存儲

      1.3 Storage

      QPS 與 常用數據存儲系統。

      MySQL、PosgreSQL 等 SQL 數據庫性能約 1k QPS

      MongoDB、Cassandra 等硬盤型NoSQL數據庫性能約 10k QPS

      Redis / Memcached 等內存型NoSQL數據庫性能約100k ~ 1m QPS

      (根據機器性能和硬盤數量及硬盤讀寫速度會有區別)

      用戶系統特點:讀非常多,寫非常少。讀多寫少的系統一定要使用 Cache 進行優化。

      用戶系統設計

      使用緩存,也就會帶來數據不一致問題,數據庫和緩存是兩臺機器,兩套系統,并不支持加鎖。如果是用一些第三方分布式鎖,會導致存取效率降低,得不償失。業界最常用的方法:

      database.set(key, user); cache.delete(key)

      class UserService { def getUser(self, user_id): key = 'user::%s' % user_id user = cache.get(user) if user: return user user = db.get(user_id) cache.set(key, user) return user def setUser(self, user): key = 'user::%s' % user.id db.set(user) cache.delete(key) }

      并發情況下依舊會出問題,在getUser執行到如下兩行之間時:

      另一個進程執行setUser(),cache 里會放入舊數據

      問題2:db set 成功,cache delete 失敗

      但這兩種情況發生概率<< cache.delete + db.set。

      解決一致性問題?

      利用 cache 的 TTL。

      任何一個 cache 中的 key 都不要永久有效,設置一個短暫有效時間,如 7 天。則即便在極低概率下出現數據不一致,也就最多不一致7天。即允許數據庫和緩存有“短時”不一致,但最終一致。

      在每次數據修改的時候,會在 cache 中 delete 這個數據。若寫多讀少,則此時 cache 沒有任何優化效果。

      Authentication Service 登錄系統

      Session 會話

      用戶 Login 后,為之創建一個 session 對象

      并把 session_key 返回給瀏覽器,讓瀏覽器存儲起來

      瀏覽器將該值記錄在瀏覽器的 cookie 中

      用戶每次向服務器發送的訪問,都會自動帶上該網站所有的 cookie

      此時服務器拿到 cookie 中的 session_key,在 Session Table 中檢測是否存在,是否過期

      Cookie

      HTTP 協議中瀏覽器和服務器的溝通機制,服務器把一些用于標記用戶身份的信息,傳遞給瀏覽器,瀏覽器每次訪問任何網頁鏈接的時候,都會在 HTTP 請求中帶上所有的該網站相關的Cookie 信息。Cookie 可理解為一個 Client 端的 hash table。

      Session 記錄過期以后,服務器會主動刪除么?

      只支持在一臺機器登陸和在多臺機器同時登陸的區別是什么?

      Session 適合存在什么數據存儲系統中

      Friendship Service

      好友關系的存儲與查詢

      雙向好友關系

      單向好友關系

      Twitter、Instagram、微博

      存在 SQL 數據庫時:

      查詢x所有的關注對象

      select * from friendship where from_user_id=x

      查詢x所有的粉絲:

      select * from friendship where to_user_id=x;

      存在 NoSQL 數據庫時:

      Friendship:

      雙向好友關系

      微信,Facebook,WhatsApp

      select * from friendship where smaller_user_id = x or bigger_user_id=x

      為何區分 smaller / bigger?

      SQL 可以按照這種方案,但NoSQL 很多不支持 Multi-index 不能使用這種方案。

      select * from friendship where from_user_id=x

      NoSQL 和 SQL 都可按照這種方案

      你覺得哪種更好呢?

      Cassandra

      三層結構的 NoSQL 數據庫

      ? http://www.lintcode.com/problem/mini-cassandra/

      第一層:row_key

      第二層:column_key

      第三層:value

      Cassandra 的 Key = row_key + column_key,同一個 Key只對應一個 value

      結構化信息如何存儲?

      將其他需要同時存儲的數據,序列化(Serialize)到 value 里進行存儲。

      Serialization:把一個 object / hash 序列化為一個 string,比如把一棵二叉樹序列化

      ? http://www.lintcode.com/problem/binary-tree-serialization/

      row_key

      又稱為 Hash Key, Partition Key。Cassandra 會根據這個 key 算一個 hash 值,然后決定整條數據存儲在哪兒。無法 Range Query

      常用:user_id

      Column Key

      insert(row_key, column_key, value)

      任何一條數據,都包含上面三個部分。可指定 column_key 按何排序。

      Cassandra 支持這樣的“范圍查詢”:

      query(row_key, column_start, column_end)

      可以是復合值,如 timestamp + user_id

      SQL vs NoSQL

      SQL的column是在Schema中預先指定好的,不能隨意添加

      一條數據一般以 row 為單位(取出整個row作為一條數據)

      NoSQL的column是動態的,無限大,可以隨意添加

      一條數據一般以 grid 為單位,row_key + column_key + value = 一條數據

      只需要提前定義好 column_key 本身的格式(是一個 int 還是一個 int+string)

      Cassandra 存儲Friendship表

      Cassandra 存儲 NewsFeed

      Friendship Table適合什么數據庫?

      SQL 和 NoSQL 的選擇標準

      原則1 大部分情況,都能用

      原則2 需要支持事務,則禁選 NoSQL

      原則3 想在什么地方偷懶,很大程度決定選什么數據庫

      SQL

      結構化數據,自由創建索引

      NoSQL

      分布式,Auto-scale,Replica

      原則4 一般一個網站會同時用多種數據庫系統

      不同的表單放在不同的數據庫。

      User Table 存在哪兒?

      大部分公司選擇了 SQL,因為信任度,Multi-Index!

      Friendship 存在哪兒?

      大部分公司選擇了 NoSQL,因為數據結構簡單,都是 key-value 的查詢/存儲需求,NoSQL效率更高!

      SQL 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:寫在Github被微軟收購之際 - Github的那些另類用法
      下一篇:Linux 系統啟動過程
      相關文章
      亚洲中文字幕无码一区二区三区| 中文字幕亚洲码在线| 亚洲国产AV无码一区二区三区| 亚洲色图黄色小说| 精品亚洲综合在线第一区| 亚洲精品无码午夜福利中文字幕| 国产成人亚洲综合| 国产成人亚洲精品狼色在线| 久久99亚洲综合精品首页| 国产精品亚洲美女久久久 | 另类小说亚洲色图| 国产精品亚洲专区在线播放 | 亚洲爆乳无码专区www| 亚洲色大情网站www| 亚洲国产成人无码AV在线| 亚洲成a人无码亚洲成www牛牛| 亚洲AV无码专区亚洲AV桃| 精品亚洲国产成人av| 成人亚洲综合天堂| 亚洲精品WWW久久久久久| 国产精品V亚洲精品V日韩精品| av在线亚洲欧洲日产一区二区| 亚洲一区二区三区在线播放| 久久亚洲高清综合| 国产亚洲精品岁国产微拍精品| 亚洲av伊人久久综合密臀性色| 亚洲成人激情在线| 亚洲欧洲精品在线| 亚洲色欲啪啪久久WWW综合网| 亚洲欧美综合精品成人导航| 色偷偷亚洲男人天堂| 亚洲精品tv久久久久久久久久| 在线亚洲人成电影网站色www| 国产亚洲一区二区三区在线观看| 久久久久亚洲精品成人网小说| 91亚洲国产在人线播放午夜| 亚洲二区在线视频| 亚洲欧美日韩中文无线码| 国产产在线精品亚洲AAVV| 国产亚洲精品精品国产亚洲综合| 亚洲国产精品一区二区成人片国内 |