容器的定義:容器是為了解決“在切換運行環境時,如何保證軟件能夠正常運行”這一問題。
目前,容器和 Docker 依舊是技術領域最熱門的詞語,無狀態的服務容器化已經是大勢所趨,同時也帶來了一個熱點問題被大家所爭論不已:數據庫 MySQL 是否需要容器化?
認真分析大家的各種觀點,發現贊同者僅僅是從容器優勢的角度來闡述 MySQL 需要容器化,幾乎沒有什么業務場景進行驗證自己的觀點; 反過來再看反對者,他們從性能、數據安全等多個因素進行闡述 MySQL不需要容器化,也舉證了一些不適合的業務場景。 下面,我們就聊一下 Docker 不適合跑 MySQL 的 N 個原因!
數據安全問題
不要將數據儲存在容器中,這也是 Docker 官方容器使用技巧中的一條。容器隨時可以停止、或者刪除。當容器被rm掉,容器里的數據將會丟失。為了避免數據丟失,用戶可以使用數據卷掛載來存儲數據。但是容器的 Volumes 設計是圍繞 Union FS 鏡像層提供持久存儲,數據安全缺乏保證。如果容器突然崩潰,數據庫未正常關閉,可能會損壞數據。另外,容器里共享數據卷組,對物理機硬件損傷也比較大。
性能問題
大家都知道,MySQL 屬于關系型數據庫,對 IO 要求較高。當一臺物理機跑多個時,IO 就會累加,導致 IO 瓶頸,大大降低 MySQL 的讀寫性能。
在一次 Docker 應用的十大難點專場上,某國有銀行的一位架構師也曾提出過:“數據庫的性能瓶頸一般出現在 IO 上面,如果按 Docker 的思路,那么多個 Docker 最終 IO 請求又會出現在存儲上面。現在互聯網的數據庫多是 share nothing 的架構,可能這也是不考慮遷移到 Docker 的一個因素吧”。
其實也有相對應的一些策略來解決這個問題,比如:
數據庫程序與數據分離
如果使用 Docker 跑 MySQL,數據庫程序與數據需要進行分離,將數據存放到共享存儲,程序放到容器里。如果容器有異常或 MySQL 服務異常,自動啟動一個全新的容器。另外,建議不要把數據存放到宿主機里,宿主機和容器共享卷組,對宿主機損壞的影響比較大。
跑輕量級或分布式數據庫
Docker 里部署輕量級或分布式數據庫,Docker 本身就推薦服務掛掉,自動啟動新容器,而不是繼續重啟容器服務。
合理布局應用
對于 IO 要求比較高的應用或者服務,將數據庫部署在物理機或者 KVM 中比較合適。目前騰訊云的 TDSQL 和阿里的 Oceanbase 都是直接部署在物理機器,而非 Docker 。
狀態問題
在 Docker 中水平伸縮只能用于無狀態計算服務,而不是數據庫。
Docker 快速擴展的一個重要特征就是無狀態,具有數據狀態的都不適合直接放在 Docker 里面,如果 Docker 中安裝數據庫,存儲服務需要單獨提供。
目前,騰訊云的 TDSQL(金融分布式數據庫)和阿里云的 Oceanbase(分布式數據庫系統)都直接運行中在物理機器上,并非使用便于管理的 Docker 上。
資源隔離方面
資源隔離方面,Docker 確實不如虛擬機 KVM,Docker 是利用 Cgroup 實現資源限制的,只能限制資源消耗的最大值,而不能隔絕其他程序占用自己的資源。如果其他應用過度占用物理機資源,將會影響容器里 MySQL 的讀寫效率。
需要的隔離級別越多,獲得的資源開銷就越多。相比專用環境而言,容易水平伸縮是Docker的一大優勢。然而在 Docker 中水平伸縮只能用于無狀態計算服務,數據庫并不適用。
難道 MySQL 不能泡在容器里嗎?
MySQL 也不是全然不能容器化。
對數據丟失不敏感的業務(例如用戶搜索商品)就可以數據化,利用數據庫分片來增加實例數,從而增加吞吐量。
Docker 適合跑輕量級或分布式數據庫,當 Docker 服務掛掉,會自動啟動新容器,而不是繼續重啟容器服務。
數據庫利用中間件和容器化系統能夠自動伸縮、容災、切換、自帶多個節點,也是可以進行容器化的。
典型案例:同程旅游、京東、阿里的數據庫容器化都是不錯的案例,大家可以自行去查看。
免責聲明:
本公眾號部分分享的資料來自網絡收集和整理,所有文字和圖片版權歸屬于原作者所有,且僅代表作者個人觀點,文章僅供讀者學習交流使用,并請自行核實相關內容,如文章內容涉及侵權,請聯系后臺管理員刪除。