這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
導讀:所有的服務都開始了容器化升級,在一切皆容器的主流思想下,無狀態的服務採用容器化已經是大勢所趨,常常困擾架構師的一個問題是,資料庫是否需要容器化,本文作者 Mikhail Chinkov 提出了自己否定觀點,由高可用架構翻譯。
如果我們觀察 2017 年技術行業,容器和 Docker 依然將是最熱門的流行語。我們開始在每個領域的 Docker 容器中打包開發的軟體。從小型初創公司到巨大的微服務平台都在使用容器技術。從 CI 平台到 Raspberry Pi 。從資料庫到……
資料庫?您確定要將資料庫放在容器中嗎?
不幸的是,這不是虛構的情境。我看到許多快速增長的項目將資料持久化到容器中。並且將計算服務和資料服務放在同一台機器上。筆者希望有經驗的人不會用這個解決方案。
下面是我的觀點,資料庫容器化從今天來看是非常不合理的。
資料庫不適合容器化的7大原因
1. 資料不安全
即使你要把 Docker 資料放在主機來儲存 ,它依然不能保證不丟資料。 Docker volumes 的設計圍繞 Union FS 鏡像層提供持久儲存,但它仍然缺乏保證。
使用當前的儲存區驅動程式,Docker 仍然存在不可靠的風險。 如果容器崩潰並資料庫未正確關閉,則可能會損壞資料。
2. 運行資料庫的環境需求
常看到 DBMS 容器和其他服務運行在同一主機上。 然而這些服務對硬體要求是非常不同的。
資料庫(特別是關係型資料庫)對 IO 的要求較高。 一般資料庫引擎為了避免並發資源競爭而使用專用環境。如果將你的資料庫放在容器中,那麼將浪費你的項目的資源。 因為你需要為該執行個體配置大量額外的資源。 在公用雲端,當你需要 34G 記憶體時,你啟動的執行個體卻必須開 64G 記憶體。在實踐中,這些資源並未完全使用。
怎麼解決? 您可以分層設計,並使用固定資源來啟動不同層次的多個執行個體。 水平伸縮總是比垂直伸縮更好。
3. 網路問題
要理解 Docker 網路,您必須對網路虛擬化有深入的瞭解。也必須準備應付好意外情況。你可能需要在沒有支援或沒有額外工具的情況下,進行 bug 修複。
我們知道:資料庫需要專用的和持久的輸送量,以實現更高的負載。我們還知道容器是虛擬機器管理程式和主機虛擬機器背後的一個隔離層。然而網路對於資料庫複寫是至關重要的,其中需要主從資料庫間 24/7 的穩定串連。未解決的 Docker 網路問題在1.9版本依然沒有得到解決。
把這些問題放在一起,容器化使資料庫容器很難管理。我知道你是一個頂級的工程師,什麼問題都可以得到解決。但是,你需要花多少時間解決 Docker 網路問題?將資料庫放在專用環境不會更好嗎?節省時間來專註於真正重要的營運目標。
4. 狀態
在 Docker 中打包無狀態服務是很酷的,可以實現編排容器並解決單點故障問題。 但是資料庫呢? 將資料庫放在同一個環境中,它將會是有狀態的,並使系統故障的範圍更大。下次您的應用程式執行個體或應用程式崩潰,可能會影響資料庫。
5. 資料庫不適合使用主要的 Docker 功能
考慮容器中的資料庫,我們來思考它的價值。 我們先看看 Docker 官方對其的定義:
Docker 是為開發人員和系統管理員構建,分發和運行分布式應用程式的開放平台。 Docker 包括 Docker Engine(攜帶型,輕量級運行時和打包工具)以及 Docker Hub(用於共用應用程式和自動化工作流程的雲端服務),Docker 使應用程式能夠以組件快速組裝,並消除開發,QA 和生產環境之間的不同。 因此,IT 可以更快地分發程式,並在膝上型電腦,資料中心虛擬機器和任何雲上運行相同的應用程式。
根據該答案,我們可以很容易定義 Docke r的主要特性:
易於構建新環境
易於重新部署(持續整合)
容易水平伸縮(從實踐得出)
易於維護環境一致
讓我們開始思考這些功能如何適應資料庫世界。
容易設定資料庫? 讓我們看看,容器化或者在本地運行資料庫,在運行上是否有巨大的差異。
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叢集 - 可能容器化效率更高。但是組態管理系統呢?它們旨在通過運行一個命令來解決配置問題。使用 Ansible 你可以輕鬆設定幾十個 Mongo 執行個體。正如你所看到的,沒有顯著的價值增長。
容易重新部署?您重新部署資料庫升級到下一個版本的頻率是多少呢?資料庫升級不是可用性問題,而是工程問題(即在群集中的可用性)。想想你的應用程式將如何使用新的資料庫引擎版本。引擎更換時可能導致的問題。
容易水平伸縮?是否要在多個執行個體之間共用資料目錄?你不害怕直接資料並發問題和可能的資料損毀嗎?使用專用資料環境部署多個執行個體不會更安全嗎?最後搞一個主從複製?
易於維護環境一致?資料庫執行個體環境的變化頻率如何?每天升級作業系統嗎?還是資料庫版本或依賴軟體變化頻繁?或者是不容易與工程團隊達成共識?
最後看來,沒有一個特性足以讓我考慮資料庫容器化。
6. 額外的隔離對資料庫是不利的
其實我在第二點和第三點原因中提到了這一點。 但我把這個列為單獨的原因,因為我想再次強調這一事實。 我們擁有的隔離等級越多,我們獲得的資源開銷就越多。 相比專用環境而言,容易水平伸縮可以使我們得到更多的好處。 然而在 Docker 中水平伸縮只能用於無狀態計算服務,而不是資料庫。
我們沒有看到任何針對資料庫的隔離功能,那為什麼我們應該把它放在容器中?
7. 雲平台的不適用性
大部分人通過共有雲開始項目。 雲簡化了虛擬機器操作和替換的複雜性,因此不需要在夜間或周末沒有人工作時間來測試新的硬體環境。當我們可以迅速啟動一個執行個體的時候,為什麼我們需要擔心這個執行個體啟動並執行環境?
這就是為什麼我們向雲供應商支付很多費用的原因。 當我們為執行個體放置資料庫容器時,上面說的這些便利性就不存在了。因為資料不匹配,新執行個體不會與現有的執行個體相容,如果要限制執行個體使用單機服務,應該讓 DB 使用非容器化環境,我們僅僅需要為計算服務層保留彈性擴充的能力。
這 7 點適用於所有資料庫嗎?
也許不是全部,但是應該是一切需要持久化資料的資料庫,以及所有具有特殊硬體環境要求的資料庫。
如果我們使用 Redis 作為緩衝或使用者會話儲存- 使用容器就不應該有任何問題。因為不需要保證該資料落地,那麼資料沒有丟失的風險。但是如果我們考慮使用 Redis 作為一個持久的資料存放區,那麼你最好把資料放在容器外面,即使您不斷重新整理 RDB 快照集,在快速變化的計算叢集中找到這個快照也會很複雜。
我們還可以談談容器內的 Elasticsearch。我們可以儲存在 ES 中的索引,並且可以從持久性資料來源重建它們。但是看看要求!預設情況下,Elasticsearch 需要 2 到 3GB 的記憶體。由於 Java 的 GC,記憶體使用量並不一致。您確定Elasticsearch 適合用於資源限制的容器嗎?讓不同的 Elasticsearch 執行個體使用不同的硬體設定不是更好嗎?
不要擔心本地開發環境的資料庫容器化。將資料庫放在本地環境的容器中,你將節省大量的時間和精力。你將能夠複製生產環境作業系統。原生Postgres for OS X或Windows不是100%相容Linux版本。在主機作業系統上設定容器而不是軟體包,你會克服這種問題。
結論
Docker 的炒作應該有一天會冷下來。 這並不意味著人們將停止使用容器虛擬化技術,而是說我們在將容器化設計時,需要將其帶來的價值放在首要考量因素。
幾天前我看到了一個關於在零亂的 Ruby 世界中架構如何生存的演講。 從這個演講中我得到的啟發是技術炒作周期,借用這個炒作周期的說法,我們看到 Docker 目前在第二階段(充滿期望的高峰)太長時間(高可用架構小編:參看資源1),當我們在最後一個階段看到 Docker 時,情況將會正常化。 我認為我們需要對這種過程負責,並應該加快這一進程。
參考資源
https://www.youtube.com/watch?v=9zc4DSTRGeM#7m40s
英文原文:https://myopsblog.wordpress.com/2017/02/06/why-databases-is-not-for-containers/
推薦閱讀
一場技術人的年終盛典:9個老兵對2016年總結與思考
一鍵搭建深度學習平台,基於Docker/Mesos和NVIDIA GPU詳細教程
Docker儲存方式選型建議
Joyent CTO談容器在2016年亟需改變的問題
本文最初出現在(http://myopsblog.wordpress.com/),由高可用架構翻譯,轉載請註明出處,技術原創及架構實踐文章,歡迎通過公眾號菜單「聯絡我們」進行投稿。
高可用架構
改變互連網的構建方式
長按二維碼 關注「高可用架構」公眾號