新的一年,如果我們對信息技術領域有所留意的話,就會發現“containers”和“Docker”成為了熱詞。在每個地方,我們都會將開發好的軟件打包放入Docker容器,到處使用容器。從小型創業企業到大型微服務平臺;從CI(Corporate Identity)平臺到樹莓派的研發;從數據庫管理系統到……
你說什么?確定在產品級的項目中要將數據庫放到容器內嗎?真的假的!遺憾之處在于這就是事實。我見過很多快速成長的項目將持久化的數據放到容器內。不僅如此,在同一臺主機上還部署了計算服務!不幸中的萬幸是有識者不會這樣做,但很多新手都是這么干的。
下面我要拋出自己的觀點,回答“為什么”不要這樣做。注意,所談論的一切都基于當前,即2017年01月29日當前的狀況。我們也看到過一些項目,研究如何在Docker中安全地管理數據庫。但是,目前數據庫容器化完全是不合理的。
下面,我來逐一闡述其中的原因!共有7大理由:
從“Banned from DBA”這部分開始,Docker in Production: A History of Failure這篇文章中關于Docker的觀點完全正確。即使是把Docker的volume創建在了數據原有的目錄,也不能說就有了什么保障。沒錯,Docker的volume被設計成與聯合文件系統(Unions FS)鏡像層一起,提供持久化存儲功能。但這并不意味著能得到什么保障。
目前Docker的存儲機制仍然是不可靠的。一旦數據庫未正確關閉而引發容器崩潰,數據就亂了,就會將服務重要的部分丟失掉。
我看到過運行在同一主機的DBMS容器作為服務層容器。但這些服務層的容器與硬件需求并不兼容。
數據庫,特別是關系型數據庫,都需要額外的資源。這包括內存、磁盤I/O等。通常我們把數據庫引擎專門用來避免資源并發的情況出現。將數據庫放到容器內,會是一種浪費項目經費的行為。為啥呢?因為這種做法是將許多額外的資源放到了一個單一的實例,這會導致無法控制的局面。在云平臺中,如果運行實例需要34G的內存資源,那我們就要創建64G的內存空間。而實際上很多這些資源是用不上的。
如何去解決這樣的問題呢?我們可以把這些層分開,然后綁定固定資源的實例。橫向擴展總是優于縱向擴展,基本就是這樣的。
要理解Docker的網絡部分,就必須對網絡虛擬化有深刻的認識。并準備好處理意料之外的情況發生。還可能被環境所迫在沒有幫助的情況下修復bug,或者為了徹底修復而使用額外的工具。
我們知道,數據庫為了更高的負載需要特定且持續的吞吐量,還知道容器是hypervisor和虛擬主機之后更獨立的一層。還有網絡對數據的復制來說也至關重要。復制需要7x24小時不間斷的網絡連接。當然,還有Docker自身存在的網絡問題,自從Docker 1.9以后還未解決的問題。
將上面這些問題匯總起來,我們可以斷定,數據庫容器是不容易被管理的。如果再加上網絡,就會變得非常困難。盡管你是頂尖的工程師,從不知道什么叫“困難”和“不可能”。但是解決Docker的網絡問題你要花費多長時間?而將數據庫放到特定的環境,抓緊時間聚精會神去做真正重要的事情不是更好嗎?
使用Docker的時候,我們時常遇到“無狀態”這個熱詞。順便提一下,你知道現在的熱詞都有哪些嗎?別告訴我還是“DevOps”!
在Docker中將無狀態的服務打包是件很酷的事情,把這些服務放到一起,不再關注單點的失敗。那數據庫呢?把數據庫放到相同的環境中,這樣就變成了有狀態的。我們將應用可能失敗的可能性加大了。下次應用實例或應用程序本身崩潰的時候,很可能就要觸及整個數據庫的工作流程了。
就算我對Docker一無所知,還是學校里一位無足輕重的系統管理員,并不關心商業價值和創新。但我們考慮容器中的數據庫,必須要評估其價值和收益。Docker的實質是什么,我們來看看官方的說法:
Docker是為開發人員和系統管理人員開發、裝載和運行分布式應用程序的開放平臺。由Docker Engine和Docker Hub兩個部分組成,Docker Engine是輕量級的實時運行的打包工具,Docker Hub為應用程序的共享和工作流的自動化提供云服務。Docker能夠快速裝配組件狀態的應用程序,并消除開發,測試和產品環境之間的差異。因此,IT人員無須作任何修改,就可以更加快捷地在筆記本、數據中心虛擬機和任何云端裝載并運行同樣的應用程序。
根據上述說法,我們就可以輕松地對Docker的價值給出定義:
接下來我們考慮一下,這些功能特性如何與數據庫相匹配。易于安裝數據庫?在運行時與數據庫有什么特別不同之處嗎?
docker run -d mongod:3.4 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6 echo "deb [ arch=amd64,arm64 ] http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list sudo apt-get update && sudo apt-get install -y mongodb-org
如果拿MongoDB集群舉例,那么集群的配置管理(Configuration Management)系統會是什么情況呢?配置管理系統被設計成執行一條命令就可以完成例行的程序。就拿MongoDB的安裝來說,Ansible模塊可以用在十幾個實例上。無論怎么樣,開發自己喜歡的配置管理系統就可以。我們可以了解到,這并不像火箭科學那樣,并不能帶來太多的價值。
易于重復部署?為了升級將數據庫升級到下一個版本而重新部署數據庫的頻度有多大?即使集群存在適用性(usability)的問題,但數據庫升級不屬于此類問題,而屬于工程問題。思考一下,我們的應用程序如何與新版的數據庫引擎協同工作,數據庫引擎發生變化時會產生哪些破壞性的影響,這才是更有價值的思考。而Docker是無法解決這些問題的。
易于水平擴展?我們是否要在很多不同實例之間共享數據目錄?難道不怕直接發生數據并發和可能發生的數據崩潰?不是在特定的數據環境下部署多個實例更安全嗎?還有后去完成主從服務的復制。
易于保持各環境的平等地位?數據庫實例環境發生變化的頻度有多大?我們每天都升級操作系統嗎?也許數據庫的版本或依賴軟件就像類庫和模塊一樣的形式存在呢?與工程團隊保持一致豈不是更容易嗎?
我們就當這些說法都成立。但是是否存在這種可能性,“蹩腳”的工程師不遵守規則,堅持要使用不同版本的數據庫進行開發?或者“出色”的工程師遵守規則但難于理解使用什么?我想對于上述后兩個問題是這樣。Docker并不是解決環境平等地位問題的有效解決方案。
至此,與數據庫容器化相關的所有功能特性都被梳理了一遍。
實際上,我在上述第二條和第三條的理由中已經表明了這一觀點。但我把它單獨作為一個主題是因為想再次重申一遍。被隔離的層級越多,我們獲取資源就越容易。可以獲得如此多的收益而不限于特定的環境并不是個問題。但是在Docker中,這些功能特性存在于無狀態的服務中,而不適用于數據庫。
在數據庫當中并沒有看到任何具有隔離屬性的功能特性。因此,我們又何必將數據庫放到容器中呢?
我們當中的大多數人已經開始使用云平臺做項目了。云平臺可以對虛擬機進行編排,實現彈性資源調度。例如,在夜間或周末無人值守的時候,為什么需要測試(testing)環境和上先前(staging)的環境?我們能夠啟動另一個有著相同配置和服務啟動進程的實例時,為什么還會擔心目前正常運行的實例?
這就是云平臺主要的功能特性,也是我們向云服務商付費的原因。當把實例放到數據庫容器當中后,云平臺的這個功能特性就不存在了。由于數據不匹配,放到容器當中的實例與原有的實例不兼容。因此,我們會限制于只使用單個的物理機,也不會存在虛擬機編排的事情。數據庫好使用非容器化的環境。虛擬機的編排和自動擴展只放在計算服務層去完成。
并不是所有的數據庫都存在同樣的問題。這些問題只存在于數據需要持久化的情況下。并且還要與特定資源需求相關的數據庫才存在這樣的問題。
如果拿Redis來做緩存或者會話數據的存儲,就不存在這樣的問題。由于這些數據不需要存儲在硬盤上,因而也就不存在數據丟失的風險。但如果我們拿Redis用作持久化的數據存儲,那就好將數據庫放在容器之外。即使我們不斷獲得了RDB快照文件,在不斷快速變化的計算集群中找到快照也是一件復雜的事情。
我們也可以談談容器中的ES(ElasticSearch)搜索引擎。在ES中,可能只存儲索引,并從持久化的數據源中不斷重復構建索引。別忘了我們對特定資源的需求!默認情況下,ES需要占用2~3GB內存空間。內存是非持久化的,用作Java垃圾回收階段。我們能夠確定ES就是解決特定資源限制好的容器嗎?根據硬件的不同情況安排為ES組織不同的實例不是更好嘛?
本地的開發環境就不用擔心了。在本地開發環境中將數據庫放到容器中會節省很多時間和力氣。在產品環境中也是一樣。要知道OS X或Windows系統下原生的PostgreSQL都不會百分百地與Linux版本兼容。所以構建起容器代替在主機系統上直接部署可以彌補這點不足。
與Docker相關的大肆宣傳終將落幕,但這并不意味著人們會停止使用容器虛擬化技術。而是意味著人們開始正確地使用容器,并將其使用價值放在首位。
幾天前,我觀看了有關Ruby架構的精彩對話,并從中指出無關Ruby本身而與技術炒作周期相關的看法。通過這個炒作周期我們看到Docker正處在第二階段,也就是膨脹預期的頂峰,已經很久了。在后階段我們會看到這種情況會趨于正常化。我覺得我們要認真負責地對待這樣的過程,甚至有必要加速該過程的發展。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。