1. 程式人生 > >大規模分散式應用之海量資料和高併發解決方案總結

大規模分散式應用之海量資料和高併發解決方案總結

一、網站應用背景

開發一個網站的應用程式,當用戶規模比較小的時候,使用簡單的:一臺應用伺服器+一臺資料庫伺服器+一臺檔案伺服器,這樣的話完全可以解決一部分問題,也可以通過堆硬體的方式來提高網站應用的訪問效能,當然,也要考慮成本的問題。

當問題的規模在經濟條件下通過堆硬體的方式解決不了的時候,我們應該通過其他的思路去解決問題,網際網路發展至今,已經提供了很多成熟的解決方案,但並不是都具有適用性,你把淘寶的技術全部都搬過來也不一定達到現在淘寶的水平,道理很簡單。

當然,很多文章都在強調,一個網站的發展水平,是逐漸的演變過來的,並不是一朝一夕的事情。雖然目前的情況網際網路的泡沫越來越大,但是整個網際網路技術的發展確實為我們提供了方便快捷的上網體驗。下邊是一張早期的淘寶官網的介面:

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

下邊整理的是一些針對海量資料和高併發情況下的解決方案,技術水平有限,歡迎留言指導。

二、針對海量資料和高併發的主要解決方案

海量資料的解決方案:

  1. 使用快取;

  2. 頁面靜態化技術;

  3. 資料庫優化;

  4. 分離資料庫中活躍的資料;

  5. 批量讀取和延遲修改;

  6. 讀寫分離;

  7. 使用NoSQL和Hadoop等技術;

  8. 分散式部署資料庫;

  9. 應用服務和資料服務分離;

  10. 使用搜索引擎搜尋資料庫中的資料;

  11. 進行業務的拆分;

高併發情況下的解決方案:

  1. 應用程式和靜態資原始檔進行分離;

  2. 頁面快取;

  3. 叢集與分散式;

  4. 反向代理;

  5. CDN;

三、海量資料的解決方案

(1)使用快取

網站訪問資料的特點大多數呈現為“二八定律”:80%的業務訪問集中在20%的資料上。

例如:在某一段時間內百度的搜尋熱詞可能集中在少部分的熱門詞彙上;新浪微博某一時期也可能大家廣泛關注的主題也是少部分事件。

總的來說就是使用者只用到了總資料條目的一小部分,當網站發展到一定規模,資料庫IO操作成為效能瓶頸的時候,使用快取將這一小部分的熱門資料快取在記憶體中是一個很不錯的選擇,不但可以減輕資料庫的壓力,還可以提高整體網站的資料訪問速度。

使用快取的方式可以通過程式程式碼將資料直接儲存到記憶體中,例如通過使用Map或者ConcurrentHashMap;另一種,就是使用快取框架:Redis、Ehcache、Memcache等。 

640?wx_fmt=png

使用快取框架的時候,我們需要關心的就是什麼時候建立快取和快取失效策略。

快取的建立可以通過很多的方式進行建立,具體也需要根據自己的業務進行選擇。例如,新聞首頁的新聞應該在第一次讀取資料的時候就進行快取;對於點選率比較高的文章,可以將其文章內容進行快取等。

記憶體資源有限,選擇如何建立快取是一個值得思考的問題。另外,對於快取的失效機制也是需要好好研究的,可以通過設定失效時間的方式進行設定;也可以通過對熱門資料設定優先順序,根據不同的優先順序設定不同的失效時間等;

需要注意的是,當我們刪除一條資料的時候,我們要考慮到刪除該條快取,還要考慮在刪除該條快取之前該條資料是否已經到達快取失效時間等各種情況!

使用快取的時候還要考慮到快取伺服器發生故障時候如何進行容錯處理,是使用N多臺伺服器快取相同的資料,通過分散式部署的方式對快取資料進行控制,當一臺發生故障的時候自動切換到其他的機器上去;還是通過Hash一致性的方式,等待快取伺服器恢復正常使用的時候重新指定到該快取伺服器。Hash一致性的另一個作用就是在分散式快取伺服器下對資料進行定位,將資料分佈在不用快取伺服器上。關於資料快取的Hash一致性也是一個比較打的問題,這裡只能大致描述一下,關於Hash一致性的瞭解,推薦一篇文章:http://blog.csdn.net/liu765023051/article/details/49408099

(2)頁面靜態化技術

使用傳統的JSP介面,前端介面的顯示是通過後臺伺服器進行渲染後返回給前端遊覽器進行解析執行,如下圖: 640?wx_fmt=png

當然,現在提倡前後端分離,前端介面基本都是HTML網頁程式碼,通過Angular JS或者NodeJS提供的路由向後端伺服器發出請求獲取資料,然後在遊覽器對資料進行渲染,這樣在很大程度上降低了後端伺服器的壓力。

還可以將這些靜態的HTML、CSS、JS、圖片資源等放置在快取伺服器上或者CDN伺服器上,一般使用最多的應該是CDN伺服器或者Nginx伺服器提供的靜態資源功能。

另外,在《高效能網站建設進階指南-Web開發者效能優化最佳實踐(口碑網前端團隊 翻譯)》這本書中,對網站效能的前端介面提供了一些很寶貴的經驗,如下:

640?wx_fmt=png

因此,在這些靜態資源的處理上,選擇正確的處理方式還是對整體網站效能還是有很大幫助的!

(3)資料庫優化

資料庫優化是整個網站效能優化的最基礎的一個環節,因為,大多數網站效能的瓶頸都是開在資料庫IO操作上,雖然提供了快取技術,但是對資料庫的優化還是一個需要認真的對待。一般公司都有自己的DBA團隊,負責資料庫的建立,資料模型的確立等問題,不像我們現在幾個不懂資料庫優化的人只能在網上找一篇篇資料庫優化的文章,自己去摸索,並沒有形成一個系統的資料庫優化思路。

對於資料庫的優化來說,是一種用技術換金錢的方式。資料庫優化的方式很多,常見的可以分為:資料庫表結構優化、SQL語句優化、分割槽、分表、索引優化、使用儲存過程代替直接操作等 。

1、表結構優化

對於資料庫的 開發規範與使用技巧以及設計和優化,前邊的時候總結了一些文章,這裡偷個懶直接放地址,有需要的可以移步看一下:  a) MySQL開發規範與使用技巧總結:http://blog.csdn.net/xlgen157387/article/details/48086607  b) 在一個千萬級的資料庫查尋中,如何提高查詢效率?:http://blog.csdn.net/xlgen157387/article/details/44156679

另外,再設計資料庫表的時候需不需要建立外來鍵,使用外來鍵的好處之一可以方便的進行級聯刪除操作,但是現在在進行資料業務操作的時候,我們都通過事物的方式來保證資料讀取操作的一致性,我感覺相比於使用外來鍵關聯MySQL自動幫我們完成級聯刪除的操作來說,還是自己使用事物進行刪除操作來的更放心一些。當然可能也是有適用的場景,大家如有很好的建議,歡迎留言!

2、SQL優化

對於SQL的優化,主要是針對SQL語句處理邏輯的優化,而且還要根據索引進行配合使用。另外,對於SQL語句的優化我們可以針對具體的業務方法進行優化,我們可以將執行業務邏輯操作的資料庫執行時間記錄下來,來進行有針對性的優化,這樣的話效果還是很不錯的!例如下圖,展示了一條資料庫操作執行呼叫的時間: