一、緩存式的Web應用程序架構:
在Web層和db層之間加一層cache層,主要目的:減少數據庫讀取負擔,提高數據讀取速度。cache存取的媒介是內存,可以考慮采用分布式的cache層,這樣更容易破除內存容量的限制,同時增加了靈活性。
二、業務拆分:
電商平台,包含了用戶、商品、評價、訂單等幾大模塊,最簡單的做法就是在一個數據庫中分別創建users、shops、comment、order四張表。
但是,隨着業務規模的增大,訪問量的增大,我們不得不對業務進行拆分。每一個模塊都使用單獨的數據庫來進行存儲,不同的業務訪問不同的數據庫,將原本對一個數據庫的依賴拆分為對4個數據庫的依賴,這樣的話就變成了4個數據庫同時承擔壓力,系統的吞吐量自然就提高了。

三、MySQL主從復制,讀寫分離:
當數據庫的寫壓力增加,cache層(如Memcached)只能緩解數據庫的讀取壓力。讀寫集中在一個數據庫上讓數據庫不堪重負。使用主從復制技術(master-slave模式)來達到讀寫分離,以提高讀寫性能和讀庫的可擴展性。讀寫分離就是只在主服務器上寫,只在從服務器上讀,基本原理是讓主數據庫處理事務性查詢,而從數據庫處理select查詢,數據庫復制被用於把事務性查詢(增刪改)導致的改變更新同步到集群中的從數據庫。
MySQL讀寫分離提升系統性能:
1、主從只負責各自的讀和寫,極大程度緩解X鎖和S鎖爭用。
2、slave可以配置MyISAM引擎,提升查詢性能以及節約系統開銷。
3、master直接寫是並發的,slave通過主庫發送來的binlog恢復數據是異步的。
4、slave可以單獨設置一些參數來提升其讀的性能。
5、增加冗余,提高可用性。
實現主從分離可以使用MySQL中間件如:Atlas
MySQL主從復制的原理:數據復制的實際就是Slave從Master獲取Binary log文件,然后再本地鏡像的執行日志中記錄的操作。由於主從復制的過程是異步的,因此Slave和Master之間的數據有可能存在延遲的現象,此時只能保證數據最終的一致性。
四、分表分庫:
在cache層的高速緩存,MySQL的主從復制,讀寫分離的基礎上,這時MySQL主庫的寫壓力開始出現瓶頸,而數據量的持續猛增,由於MyISAM使用表鎖,在高並發下會出現嚴重的鎖問題,大量的高並發MySQL應用開始使用InnoDB引擎代替MyISAM。采用Master-Slave復制模式的MySQL架構,只能對數據庫的讀進行擴展,而對數據的寫操作還是集中在Master上。這時需要對數據庫的吞吐能力進一步地擴展,以滿足高並發訪問與海量數據存儲的需求。
對於訪問極為頻繁且數據量巨大的單表來說,首先要做的是減少單表的記錄條數,以便減少數據查詢所需的時間,提高數據庫的吞吐,這就是所謂的分表。在分表之前,首先需要選擇適當的分表策略,使得數據能夠較為均衡地分布到多張表中,並且不影響正常的查詢。
分表能夠解決單表數據量過大帶來的查詢效率下降的問題,但是卻無法給數據庫的並發處理能力帶來質的提升。面對高並發的讀寫訪問,當數據庫master服務器無法承載寫操作壓力時,不管如何擴展Slave服務器都是沒有意義的,對數據庫進行拆分,從而提高數據庫寫入能力,即分庫。
數據庫經過業務拆分及分庫分表,雖然查詢性能和並發處理能力提高了。但是原本跨表的事務上升為分布式事務;由於記錄被切分到不同的庫和不同的表中,難以進行多表關聯查詢,並且不能不指定路由字段對數據進行查詢。且分庫分表后需要進一步對系統進行擴容(路由策略變更)將變得非常不方便,需要重新進行數據遷移。
分表策略:
使用用戶ID是最常用的分庫的路由策略。
當數據比較大的時候,對數據進行分表操作,首先要確定需要將數據平均分配到多少張表中,也就是:表容量。
這里假設有100張表進行存儲,則我們在進行存儲數據的時候,首先對用戶ID進行取模操作,根據 user_id%100 獲取對應的表進行存儲查詢操作。
在實際的開發中,我們的用戶ID更多的可能是通過UUID生成的,這樣的話,我們可以首先將UUID進行hash獲取到整數值,然后在進行取模操作。
分庫策略:
數據庫分表能夠解決單表數據量很大的時候數據查詢的效率問題,但是無法給數據庫的並發操作帶來效率上的提高,因為分表的實質還是在一個數據庫上進行的操作,很容易受數據庫IO性能的限制。
因此,如何將數據庫IO性能的問題平均分配出來,很顯然將數據進行分庫操作可以很好地解決單台數據庫的性能問題。
分庫策略與分表策略的實現很相似,最簡單的都是可以通過取模的方式進行路由。
分庫與分表實現策略:
上述的配置中,數據庫分表可以解決單表海量數據的查詢性能問題,分庫可以解決單台數據庫的並發訪問壓力問題。
有時候,我們需要同時考慮這兩個問題,因此,我們既需要對單表進行分表操作,還需要進行分庫操作,以便同時擴展系統的並發處理能力和提升單表的查詢性能,就是我們使用到的分庫分表。
分庫分表的策略相對於前邊兩種復雜一些,一種常見的路由策略如下:
1、中間變量 = user_id%(庫數量*每個庫的表數量);
2、庫序號 = 取整(中間變量/每個庫的表數量);
3、表序號 = 中間變量%每個庫的表數量;
參考:
https://blog.csdn.net/u010832551/article/details/77836681
