轉:http://www.cnblogs.com/qlee/archive/2011/04/08/2009738.htmlhtml
隨着一個網站的業務不斷擴展,數據不斷增長,數據庫的壓力也會愈來愈大,對數據庫或者SQL的基本優化可能達不到最終的效果,咱們能夠採用讀寫分離的策 略來改變現狀。讀寫分離如今被大量應用於不少大型網站,這個技術也不足爲奇了。ebay就作得很是好。ebay用的是oracle,據說是用Quest Share Plex 來實現主從複製數據。mysql
讀寫分離簡單的說是把對數據庫讀和寫的操做分開對應不一樣的數據庫服務器,這樣能有效地減輕數據庫壓力,也能減輕io壓力。主數據庫提供寫操做,從數據庫提 供讀操做,其實在不少系統中,主要是讀的操做。當主數據庫進行寫操做時,數據要同步到從的數據庫,這樣纔能有效保證數據庫完整性。Quest SharePlex就是比較牛的同步數據工具,據說比oracle自己的流複製還好,MySQL也有本身的同步數據技術。mysql只要是經過二進制日誌來複制數據。經過日誌在從數據庫重複主數據庫的操做達到複製數據目的。這個複製比較好的就是經過異步方法,把數據同步到從數據庫。web
主數據庫同步到從數據庫後,從數據庫通常由多臺數據庫組成這樣才能達到減輕壓力的目的。讀的操做怎麼樣分配到從數據庫上?應該根據服務器的壓力把讀的操做分配到服務器,而不是簡單的隨機分配。mysql提供了MySQL-Proxy實現讀寫分離操做。不過MySQL-Proxy好像好久不更新了。oracle能夠經過F5有效分配讀從數據庫的壓力。sql
上面說的數據庫同步複製,都是在從同一種數據庫中,若是我要把oracle的數據同步到mysql中,其實要實現這種方案的理由很簡單,mysql免費,oracle太貴。好像Quest SharePlex也實現不了改功能吧。好像如今市面尚未這個工具吧。那樣應該怎麼實現數據同步?其實咱們能夠考慮本身開發一套同步數據組件,經過消息,實現異步複製數據。其實這個實現起來要考慮不少方面問題,高併發的問題,失敗記錄等。其實這種方法也能夠同步數據到memcache中。據說oracle的Stream也能實現,不過沒有試過。數據庫
讀寫分離,基本的原理是讓主數據庫處理事務性增、改、刪操做(INSERT、UPDATE、DELETE),而從數據庫處理SELECT查詢操做。數據庫複製被用來把事務性操做致使的變動同步到集羣中的從數據庫。緩存
爲何要分庫、分表、讀寫分?服務器
單表的數據量限制,當單表數據量到必定條數以後數據庫性能會顯著降低。數據多了以後,對數據庫的讀、寫就會不少。分庫減小單臺數據庫的壓力。接觸過幾個分庫分表的系統,都是經過主鍵進行散列分褲分表的。這類數據比較特殊,主鍵就是惟一的獲取該條信息的主要途徑。好比:京東的訂單、財付通的交易記錄等。。。該類數據的用法,就是經過訂單號、交易號來查詢該筆訂單、交易。併發
還有一類數據,好比用戶信息,每一個用戶都有系統內部的一個userid,與userid對應的還有用戶看到的登陸名。那麼若是分庫分表的時候單純經過userid進行散列分庫,那麼根據登陸名來獲取用戶的信息,就沒法知道該用戶處於哪一個數據庫中。oracle
或許有朋友會說,咱們能夠維護一個email----userid的映射關係,根據email先查詢到userid,在根據userid的分庫分表規則到對應庫的對應表來獲取用戶的記錄信息。這麼作是能夠的,可是這個映射關係的條數自己也是個瓶頸,原則上是沒有減小單表內數據的條數,算是一個單點。而且要維護這個映射關係和用戶信息的一致性(修改登陸名、多登陸名等其餘特殊需求),最大一個緣由,其實用戶信息是一個讀大於寫的庫,web2.0都是以用戶爲中心,全部信息都和用戶信息相關聯,因此對用戶信息拆分仍是有必定侷限性的。異步
對於這類讀大於寫而且數據量增長不是很明顯的數據庫,推薦採用讀寫分離+緩存的模式,試想一下一個用戶註冊、修改用戶信息、記錄用戶登陸時間、記錄用戶登陸IP、修改登陸密碼,這些是寫操做。可是以上這些操做次數都是很小的,因此整個數據庫的寫壓力是很小的。惟一一個比較大的就是記錄用戶登陸時間、記錄用戶登陸IP這類信息,只要把這些常常變更的信息排除在外,那麼寫操做能夠忽略不計。因此讀寫分離首要解決的就是常常變化的數據的拆分,好比:用戶登陸時間、記錄用戶登陸IP。這類信息能夠單獨獨立出來,記錄在持久化類的緩存中(可靠性要求並不高,登錄時間、IP丟了就丟了,下次來了就又來了)
以oracle爲例,主庫負責寫數據、讀數據。讀庫僅負責讀數據。每次有寫庫操做,同步更新cache,每次讀取先讀cache在讀DB。寫庫就一個,讀庫能夠有多個,採用dataguard來負責主庫和多個讀庫的數據同步。
頂
0
踩