日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

高并发系统设计 --基于MySQL构建评论系统

發布時間:2024/1/8 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高并发系统设计 --基于MySQL构建评论系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如何用MySQL來實現評論系統

為什么我不用mongodb?

  • 社區成熟度不如MySQL,redis
  • 需要學習的東西很多,遷移,擴容,片建,集群
  • redis > mongodb
  • 架構設計

    使用MySQL進行存儲的話,就必須要用到Redis來做緩存,后臺admin需要接通ES來進行查詢,comment-service通過異步來進行寫Redis和MySQL評論數據,MySQL和ES通過Canal進行binlog同步。

    緩存模式

    首先我們需要預讀,我們讀第一頁的時候,也需要把第二頁的內容加載出來。讀第二頁的時候,我們預先讀第三頁,這樣可以避免大量的cache miss。

    但是這里有一個致命的問題就是:當緩存抖動的時候,會觸發大量的cache rebuild,因為我們使用了預加載,容易造成OOM(內存溢出)。因此我們需要使用消息隊列來進行邏輯異步化,對于當前請求,只返回MySQL中的部分數據即可。

    寫的邏輯

    至于寫的操作,我們要穿透到存儲層,因此最好使用消息隊列異步削峰。例如我的評論發布出去了,用戶過100ms才看到評論,這是無所謂的。

    存儲設計

    comment_subject表

    idint主鍵
    obj_idint對象id
    obj_typeint對象類型
    member_idint作者id
    countint評論總數
    root_countint跟評總數
    all_countint評論+回復總數
    stateint狀態 0:正常 1:隱藏
    attrsint屬性 0:置頂 1:不置頂
    create_time+update_timedatatime創建時間,修改時間

    obj_id+obj_type把評論系統設計成中臺。 一般是指搭建一個靈活快速應對變化的架構,快速實現前端提的需求,避免重復建設,達到提高工作效率目的。

    obj_id+obj_type形成了一個業務鍵,比如微博,發帖,發視頻,你可以發視頻,你也可以發文章,評論系統設計成中臺。

    comment_index

    idint主鍵id
    obj_idint對象id
    obj_typeint對象類型
    member_idint發表者id
    rootint根評論id,不為0是回復評論
    parentint父評論id,為0是root評論
    floorint評論樓層
    countint評論總數
    root_countint根評論總數
    likeint點贊數
    hateint點踩數
    stateint狀態,0:正常;1:隱藏
    attrsint屬性
    create_timedatetime創建時間
    update_timedatetime修改時間

    parent:父評論id,其實就是記錄是否是回復評論。

    comment_content表:

    comment_idint主鍵
    at_member_idsvarchar對象id
    ipint對象類型
    platformint發表者id
    devicevarchar跟評論id,不為0是回復評論
    messagevarchar評論內容
    metavarchar評論元數據:背景,字體
    create_timedatetime創建時間
    update_timedatetime修改時間

    index是索引表,content是內容表。

    數據寫入:事務更新comment_subject,comment_index,comment_content三張表,其中content是非強制性需要一致性考慮的。因此可以先寫入content,之后事務更新其他表。即便content更新成功,后續失敗僅僅存在一條ghost數據。

    數據讀取:基于obj_id + obj_type在comment_index表找到評論列表,where root=0 order by floor。之后根據comment_index的id字段撈出comment_content的評論內容。對于二級的子樓層,where parent/root in(id...)。

    為什么要把index和content分成兩個表

    comment_index:評論樓層的索引表,實際并不包含內容。comment_content:評論內容的表,包含評論的具體內容。其中comment_index的id字段和comment_content是1對1的關系,這里面包含了幾種設計思想。

    • 表都有主鍵,comment_content沒有id,是為了減少一次二級索引查找,直接基于主鍵檢索,同時comment_id在寫入要盡可能的順序自增。
    • 索引,內容分離,方便mysql_datapage緩存更多的row,如果和content耦合,會導致更大的IO。長遠來看content信息可以直接使用KV storage存儲。

    緩存設計

    comment_subject_cache【string】

    keystringoid_type
    valueintsubject marshal string
    expireduration24h

    comment_index_cache【sorted set】

    keystringcache key:oid_type_sort其中sort為排序方式,0:樓層,1:回復數量
    memberintcomment_id:評論id
    scoredouble樓層號,回復數量,排序得分
    expireduration8h

    comment_content_cache

    keystringcomment_id
    valueintcontent
    expireduration24h

    comment_subject_cache:對應主題的緩存,value使用protobuf序列化的方式存入,這樣調用rpc的時候速度可以更塊一點。

    comment_index_cache:使用redis sorted set進行索引的緩存,索引即數據的組織順序,而非數據內容。通過預加載少量數據,通過增量加載的方式逐漸預熱填充緩存,而redis sorted set skiplist的實現可以做到O(logN) + O(M)的時間復雜度,效率很高

    sorted set是要增量追加的,因此必須判定key存在,才能zadd

    comment_content_cache:對應評論內容數據,使用protobuf序列化的方式存入。

    增量加載(目標表僅更新源數據表中變化的內容)+lazy加載(延遲加載,種將資源標識為非阻塞(非關鍵)資源并僅在需要時加載它們的策略)

    可用性設計

    其實就是各種緩存問題,消息隊列消息等問題。

    如果這個key是熱點的key的話可以使用本地緩存+分布式緩存。

    那么如何統計是否是熱點呢?

    這里,我們就移步到我們的下一篇文章了,謝謝大家。

    總結

    以上是生活随笔為你收集整理的高并发系统设计 --基于MySQL构建评论系统的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。