比如 知乎文章,簡書,豆瓣,掘金,等有大篇幅文章的網站,文章的內容,可能幾千字,甚至好幾萬字,如何存儲呢

1.用mysql 的 TEXT類型,mysql 的 Text最大可以4GB怎麼都夠了,但是那麼大放在一行中不知是不是影響讀寫速度

2.直接用 mogodb 存,Bson裏就放1個key,value卻幾百k或上兆,總覺得也不好

3.持久性KV資料庫,如果是既支持單機又方便擴展,各位可以推薦一下哪個比較好用的嗎?

4.OSS對象存儲,OSS是不是就必須存成文件了?IO是不是對比KV會很慢,如果頻繁讀又頻繁寫,更不適合了吧

熱點的話還是要存資料庫吧,不熱的可以落盤成文件?如果總結場景的話

A: 頻繁讀 不頻繁寫:新聞,諮訊,知識付費文章,公眾號文章,論壇帖子

B: 頻繁讀 也頻繁寫:筆記,協作文檔

大廠都是如何做的,對比一下不同方案


基於kv存儲吧


以下所有條目都來源於互聯網文章的二次加工,如有雷同,概不承認

沒做過相關工作,純理論分析一波,歡迎討論:

條目一:如果是創業初期,直接用最熟悉的資料庫就好

比如MySQL。

這樣的做是有好處的,就是糙快猛。創業初期,最重要的是把項目做出來並上線。業務能不能活下來還不一定呢,想太多高性能、高可靠、易運維的事都沒有太大的意義。

簡單可靠纔是最需要關注的。

條目二:不建議使用MySQL的TEXT類型

像blob和text這樣的欄位,名義上是為存儲很大的數據而設計的類型。但這正因為如此,這跟關係資料庫使用table的設計理念是衝突的。table中的每一列數據都是定長的,比如varchar(32)。但blob和text的上限太長了,MySQL不可能將它們存儲在table中,因而會使用專門的外部存儲區域進行存儲,數據行內存儲指針。這樣做的其中一個結果是會導到多一次磁碟IO,性能開銷比較嚴重。

條目三:新聞類文本直接靜態化扔Nginx或OSS就好

頻繁讀不頻繁寫的新聞資訊類文本,在保存的時候,直接寫成靜態的html,訪問的時候直接從nginx返回。這樣做,不僅可以節省伺服器資源,還可以利用CDN加速,把文件放到離用戶最近的CDN伺服器上,既便宜又快。

OSS是另一個可選的方案。OSS的優勢是對圖片和視頻存儲做了大師針對性優化,比如縮放圖片和視頻轉碼。另外,幾乎所有的OSS雲服務都自帶CDN加速服務。

熟悉程度和價格可能仍然是很重要的選擇因素。

條目四:筆記類產品MongoDB可能是個不錯的選擇

簡述MongoDB的特點如下:

  1. 偶爾丟數據:在開發者水平相當的情況下,MongoDB更容易鼓勵開發者做出不恰當的設計從而導致數據丟失。如果你的數據特別重要(金融、交易),那麼關係型資料庫可能是個更好的選擇。對筆記類產品吧,可能沒那麼疼,忍一忍就過去了。
  2. 無schema:不需要預定義的schema,以文檔(json, bson)形式保存數據,同一個集合(對應關係資料庫的表)中的不同文檔可以使用不同的結構,並支持隨時向擴展任意欄位。這個特點導致MongoDB特別適合存儲商品參數這類名目繁多又不盡相同的參數。在在遊戲、電商、社交、直播、物流等領域都能看到MongoDB的身影。

    當然,隨之而來的問題就是如果代碼結構不夠清晰,很可能導致沒有任何人知道資料庫中存儲的數據是什麼格式。對接手他人代碼的人員,如果不能確定文檔中有哪些欄位 ,則可能導致相當危險的結果。如果你的數據模式比較固定的話,一個變通的方案是通過protobuf這種序列化協議引入外部模式。

    這對筆記類產品談不上好或者壞,畢竟筆記的主要內容是大段不需要解析的文本。
  3. 單文檔查詢速度快:MongoDB使用BTree結構(對比MySQL使用B+Tree),針對單文檔的查詢做了大量節約IO的優化,因此查詢速度很快,當然喫內存也是毫不含糊。 修訂:MongoDB使用的也是B+Tree,原來的理解有誤。
  4. 多表聯查功能弱:筆記產品不太需要。
  5. 事務功能弱:4.0以上的版本已經支持基於Replica Set的事務,但在此之前只支持單文檔的原子操作。對筆記來產品來說,弱化事務的使用可以提高數據寫入效率。
  6. 提供全文索引,這個對筆記類搜索有用(但中文支持弱不少 = = )。
  7. 原生支持sharding(分片),升級資料庫容量時分片間的數據可以自動遷移,這對海量數據的擴容簡直不要太nice。

條目五:其它資料庫產品

  1. MySQL,關係資料庫,強在事務和關聯查詢
  2. Redis/Memcache,內存資料庫,主要用作緩存,不適用於長文本處理
  3. ElasticSearch,全文搜索,雖然樓主沒提,但在筆記類產品的確有這種需求。但仔細想一下,個人筆記量是否真的需要上ES才能滿足需要呢?


這個問題,我經歷過,我面對的情況比你所說的還要複雜些,現在看來解決得還算不錯,有大量客戶使用,驗證是可行的。總體思路是,要兼顧使用頻度與性能代價,對於長內容,無論是長文本,還是圖片、文件等,要從設計上考慮用戶使用情況與後臺運行負載,再決定如何存儲。

具體來說,對於需要高頻度讀取並展現的,放入資料庫;否則,不存入資料庫,而是放入磁碟,資料庫裏只存放其文件路徑,需要展現時依據路徑讀取並展現,即可。但有個例外,對於內容可能很大,會對資料庫造成重大性能瓶頸的欄位,堅決放入磁碟,不要提供高頻度讀取展現的支持,不能因為這一件小事而影響全局。

結合實際來說吧,會更清楚些。當時是在開發華創信息管理平臺,一款信息管理的平臺軟體,允許用戶可按需建表、設欄位,以便讓普通用戶快速搭建各種管理系統。欄位的數據類型支持長文本、附件等長欄位,長文本的最大長度32K中文字,附件可以是圖片、word、excel、.zip等各種文件。

這種平臺軟體,既然允許用戶自由設置,那麼問題就來了,因為一個表可能會設置多個長欄位,所以我前面說,比你說的情況還要複雜些。比如,利用平臺搭建一個售後服務管理系統,他可能設置一個客戶報修表,並設置以下欄位:故障現象描述、故障現場照片、解決措施描述、維修後照片...等等,其中,描述欄位可能較長,數據類型一般用長文本,照片是文件,數據類型只能用附件。

該怎麼決策呢。對於長文本,我們允許在用戶界面上直接顯示,一頁數據就包含100行,假如每行包含2個長文本,一頁就要讀取200個長文本,因此,其讀取展現頻度是較高的,只能放入資料庫。而對於圖片等附件型欄位,由於附件可能較大,假如每個限制5M,算正常吧,但你架不住記錄數可能巨多啊,直接放入資料庫會讓資料庫的大小急劇膨脹,後果不堪設想。因此,附件型欄位的文件型數據必須放入磁碟,在用戶界面上不支持批量展現,而是點擊它才顯示。這樣,就從設計上兼顧了用戶使用方便性與後臺運行負載,效果不錯。


看html的具體內容和篇幅。

是我的話,不考慮mogo


這個需要看你自己的能力,技術投入,後續擴展,性能要求等因素考慮。

如果從易用性上,mysql簡單易用,門檻低,後續維護方便,但是他對於text,blob等格式在性能上效果不佳,主要還是因為它並不擅長文檔等海量存儲場景。

如果追求性能,可以考慮使用redis,基於內存性能高但是功能比mysql欠缺寫。

基於文檔存儲,也可以選擇mongodb,先天支持海量存儲。


推薦閱讀:
相關文章