天天看點

資料庫的讀寫分離

讀寫分離,基本的原理是讓主資料庫處理事務性增、改、删操作(insert、update、delete),而從資料庫處理select查詢操作。資料庫複制被用來把事務性操作導緻的變更同步到叢集中的從資料庫。

       為什麼要分庫、分表、讀寫分?

       單表的資料量限制,當單表資料量到一定條數之後資料庫性能會顯著下降。資料多了之後,對資料庫的讀、寫就會很多。分庫減少單台資料庫的壓力。接觸過幾個分庫分表的系統,都是通過主鍵進行散列分庫分表的。這類資料比較特殊,主鍵就是唯一的擷取該條資訊的主要途徑。比如:京東的訂單、财付通的交易記錄等。。。該類資料的用法,就是通過訂單号、交易号來查詢該筆訂單、交易。

        還有一類資料,比如使用者資訊,每個使用者都有系統内部的一個userid,與userid對應的還有使用者看到的登入名。那麼如果分庫分表的時候單純通過userid進行散列分庫,那麼根據登入名來擷取使用者的資訊,就無法知道該使用者處于哪個資料庫中。

       或許有朋友會說,我們可以維護一個email----userid的映射關系,根據email先查詢到userid,在根據userid的分庫分表規則到對應庫的對應表來擷取使用者的記錄資訊。這麼做是可以的,但是這個映射關系的條數本身也是個瓶頸,原則上是沒有減少單表内資料的條數,算是一個單點。并且要維護這個映射關系和使用者資訊的一緻性(修改登入名、多登入名等其他特殊需求),最大一個原因,其實使用者資訊是一個讀大于寫的庫,web2.0都是以使用者為中心,所有資訊都和使用者資訊相關聯,是以對使用者資訊拆分還是有一定局限性的。

       對于這類讀大于寫并且資料量增加不是很明顯的資料庫,推薦采用讀寫分離+緩存的模式,試想一下一個使用者注冊、修改使用者資訊、記錄使用者登入時間、記錄使用者登入ip、修改登入密碼,這些是寫操作。但是以上這些操作次數都是很小的,是以整個資料庫的寫壓力是很小的。唯一一個比較大的就是記錄使用者登入時間、記錄使用者登入ip這類資訊,隻要把這些經常變動的資訊排除在外,那麼寫操作可以忽略不計。是以讀寫分離首要解決的就是經常變化的資料的拆分,比如:使用者登入時間、記錄使用者登入ip。這類資訊可以單獨獨立出來,記錄在持久化類的緩存中(可靠性要求并不高,登陸時間、ip丢了就丢了,下次來了就又來了)

        以oracle為例,主庫負責寫資料、讀資料。讀庫僅負責讀資料。每次有寫庫操作,同步更新cache,每次讀取先讀cache在讀db。寫庫就一個,讀庫可以有多個,采用dataguard來負責主庫和多個讀庫的資料同步。

資料庫的讀寫分離