應用層優化
緩存
作為基礎組件的緩存
緩存有可能成為基礎設施的重要組成部分。也很容易陷入一個陷阱,認為緩存雖然很好用,但并不是重要到非有不可得東西。你也許會辯駁,如果緩存服務器宕機或者緩存被清空,請求也可以直接落在數據庫上,系統依然可以正常運行。如果是剛剛將緩存加入應用系統,這也許是對的,但緩存的加入可以使得在應用壓力顯著增長時不需要對系統的某些部分同比增加資源投入——通常是數據部分。因此,系統可能慢慢地變得對緩存非常依賴,卻沒有被發覺。
例如,如果高速緩存命中率是90%,當由于某種原因失去緩存,數據庫上的負載將增加到原來的10倍。這很可能導致壓力超過數據庫服務器的性能極限。為了避免像這樣的意外,應該設計一些高可用性緩存(包括數據和服務)的解決方案,或者至少是評估好禁用緩存或丟失緩存時的性能影響。比如說可以設計應用在遇到這樣的情況時能夠進行降級處理。
使用HandlerSocket和memcached
相對于數據存儲在MySQL中而緩存在MySQL外部的緩存方案,另外有一種替代方法是為MySQL創建一個更快的訪問路徑,直接繞過使用緩存。對于小兒簡單的查詢語句,很大一部分開銷來自解析SQL,檢查權限,生成執行計劃,等等。如果這種開銷可以避免,MySQL在處理簡單查詢時將非常快。目前有兩個解決方案可以用所謂的NoSQL方式訪問MySQL。第一種時一個后臺進程插件,成為HandlerSocket,由DeNA開發,這是日本最大的社交網站。HandlerSocket允許通過一個簡單的協議訪問InnoDB Handler對象。實際上,也就是繞過了上層的服務器層,通過網絡直接連接到了InnoDB引擎層。有報告稱HandlerSocket每秒可以執行超過750 000條查詢。Percona Server分支中自帶了HandlerSocket插件引擎層。第二個方案時通過memcached協議訪問InnoDB。MySQL5.6的實驗室版本有一個插件提供了這個接口。兩種方法都有一些限制——特別是memcached的方法,這種方法對很多訪問數據的方法都不支持。為什么會希望采用SQL以外的辦法訪問數據呢?除了速度之外,最大的可能是簡單。這樣做最大的好處是可以擺脫緩存,以及所有的失效邏輯,還有為它們服務的額外的基礎設施
拓展MySQL
如果MySQL不能做你需要的事,一種可能是拓展其功能。在這里不會展示如何去做到這一點,但會提供一些可能的方向。如果你對進一步探索有興趣,那么有很多很好的在線資源。當我們說"MySQL不能做你需要的事",我們指的是兩件事情:MySQL根本做不到這一點或者MySQL可以做到,但是只能通過緩慢或笨拙的方法,總之做得不夠好。無論哪個都是需要對MySQL拓展的原因。好消息事,MySQL已經越來越模塊化和通用。存儲引擎是拓展MySQL的一個很好的方式。Brian Aker已經寫了一個存儲引擎的框架,還有一系列介紹有關如何開始編寫自己的存儲引擎的文章。這是目前幾個主要的第三方存儲引擎的基礎。許多公司都編寫了它們自己的內部存儲引擎。例如,一些社交網站公司使用了特殊的為社交圖形操作設計的存儲引擎,我們還知道有個公司定制了一個用于模糊搜索的引擎。寫一個簡單的自定義存儲引擎并不難。還可以使用存儲引擎作為另一個軟件的接口。Sphinx引擎就是一個很好的例子,該引擎是Spinx全文檢索軟件的接口
MySQL的替代品
MySQL并不是適合每一個場景的解決方案。有些工作通常在MySQL以外來做會更好,即使MySQL理論上也可以做到。最明顯的一個例子是在傳統的文件系統中存儲文件,而不是在表中。圖像文件是靜丹案例:雖然可以把它們放到一個BLOB列,但這通常不是個好辦法(使用MySQL的復制來快速分布鏡像到其他機器更有優勢,我們知道一些程序使用這種技術)。一般的做法是,在文件系統中存儲圖片或其他大型二進制文件,而在MySQL中只存儲文件名;然后應用程序在MySQL之外存取文件。對于Web應用程序,可以把文件名放在元素的src屬性中,這樣就可以實現對文件的存取。
全文檢索是另一個最好放在MySQL之外處理額例子——MySQL在全文搜索方面明顯不如Lucene和Sphinx。 NDB API也可能對某些任務有用。例如,盡管MySQL的NDB集群存儲引擎(目前還)不適合存儲一個高性能Web應用程序的全部數據,但用NDB API直接存儲網站會話數據或用戶注冊信息還是可能的。在如下網站可以了解到更多NDB API的內容.還有供Apache使用的NDB模塊,mod_ndb.
最后,對于某些操作——如圖形關系和樹遍歷——關系型數據并不總是正確的典范,MySQL并不擅長分布式數據處理,因為它缺乏并行執行查詢的能力。處于這些目的情況還是建議使用其他工具(可能與MySQL結合).現在想到的例子包括:
- 1.對于簡單的鍵——值存儲,在復制嚴重落后的非常高速的訪問場景中,我們建議用Redis替換MySQL.即使MySQL主庫可以承擔這樣的壓力,備庫的延遲也是非常讓人頭疼的。Redis也常用來做隊列,因為它對隊列操作支持得很好
- 2.Hadoop是房間中得大象,一語雙關。混合MySQL/Hadoop得部署在處理大型或半結構化數據時非常常見
備份與恢復
概述
如果沒有提前做好備份規劃,也許以后會發現已經錯失了一些最佳得選擇。例如,在服務器已經配置好了以后,才想起應該使用LVM,以便可以獲取文件系統的快照——但這時已經太遲了。在為別分配置系統參數時,可能沒有注意到某些系統配置對性能有著重要影響。如果沒有計劃做定期的恢復演練,當真的需要恢復時,就會發現并沒有那么順利。在此假設大部分用戶主要使用InnoDB而不是MyISAM。也不會涵蓋一個精心設計的備份和恢復解決方案的所有部分——而僅涉及與MySQL相關的部分。不打算包括的話題如下:
- 1.安全(訪問備份,恢復數據的權限,文件是否需要加密)
- 2.備份存儲在哪里,包括它們應該離數據多遠(在一塊不同的盤上,一臺不同的服務器上,或離線存儲),以及如何將數據從源頭移動到目的地
- 3.保留策略、審計、法律要求,以及相關的條款
- 4.存儲解決方案和介質,壓縮,以及增量備份
- 5.存儲的格式
- 6.對備份的監控和報告
- 7.存儲層內置備份功能,或者其他專用設備,例如預制式文件服務器
讓我們先澄清幾個核心術語。首先,經常可以聽到所謂的熱備份、暖備份和冷備份。人們經常使用這些詞來表示一個備份的影響:例如"熱"備份不需要任何的服務停機時間。問題是對這些術語的理解因人而異。有些工具雖然在名字中使用了"熱備份",但實際上并不是所認為的那樣。我們盡量避開這些術語,而直接說明某個特別的技術或工具對服務器的影響。另外兩個讓人困惑的詞是還原和恢復。還原意味著從備份文件中獲取數據,可以加載這些文件到MySQL里,也可以將這些文件放置到MySQL期望的路徑中。恢復一般意味著當某些異常發生后對一個系統或其部分的拯救。包括從備份中還原數據,以及使服務器完全恢復功能的所有必要步驟,例如重啟MySQL、改變配置和預熱服務器的緩存等。
在很多人的概念中,恢復僅意味著修復崩潰后損壞的表。這與恢復一個完整的服務器使不同的。存儲引擎的崩潰恢復要求數據和日志文件一致。要確保數據文件中只包含已經提交的事務所做的修改,恢復操作會將日志中還沒有應用到數據文件的事務重新執行。這也許是恢復過程的一部分,甚至是備份的一部分。然而,這和一個意外的DROP TABLE事故后需要做的事是不一樣的。
為什么要備份?
下面是備份非常重要的幾個理由:
- 1.災難恢復
災難恢復是下列場景下需要做的事情:硬件故障、一個不經意的Bug導致數據損壞,或者服務器及其數據由于歐協原因不可獲取或無法使用等。你需要準備好應付很多問題:某人偶爾連錯數據庫服務器執行了一個ALTER TABLE的操作,計放大樓被炸毀,惡意的黑客攻擊或MySQL的Bug等。盡管遭受任何一個特殊的災難的幾率都非常低,但所有的風險疊加在一起就很有可能會碰到 - 2.人們改變象發
不必驚訝,很多人經常會在刪除某些數據后又想要恢復這些數據 - 3.審計
有時候需要知道數據或Schema在過去的某個時間點是什么樣的。例如,你也許被卷入一場法律官司,或發現了應用的一個Bug,想知道這段代碼之前干了什么(有時候僅僅依靠代碼的版本控制還不夠) - 4.測試
一個最簡單的基于實際數據來測試的方法是,定期用最新的生產環境數據更i性能測試服務器。如果使用備份的方案就非常簡單:只要把備份文件還原到測試服務器上即可。
檢查你的假設。例如, 你認為共享虛擬主機供應商會提供MySQL服務器的備份?許多主機供應商根本不備份MySQL服務器,另外一些也僅僅在服務器運行時復制文件,這可能會創建一個損壞的沒有用處的備份