数据库不适合Docker和容器化的7个原因问题是,数据库需要容器化吗?放眼2017年的科技行业,容器和Docker依然是最热门的流行语。我们开始将开发的软件打包到每个域的Docker容器中。从小型初创公司到大型微服务平台,一切都在使用容器技术。从CI平台到RaspberryPi。从数据库到……数据库?您确定要将数据库放入容器中吗?不幸的是,这不是虚构的场景。我看到许多快速增长的项目将数据持久化到容器中。并将计算服务和数据服务放在同一台机器上。笔者希望有经验的人不要使用这个方案。以下是我的观点,数据库容器化以今天的观点来看是非常不合理的。数据库不适合容器化的7大理由1.数据不安全即使想把Docker的数据存储在宿主机上,仍然不能保证数据不丢失。Docker卷是围绕UnionFS镜像层设计的,以提供持久存储,但它仍然缺乏保证。使用当前的存储驱动程序,Docker仍然存在不可靠的风险。如果容器崩溃并且数据库未正确关闭,则数据可能会损坏。2、运行数据库的环境要求经常会看到DBMS容器和其他服务运行在同一台主机上。但是,这些服务具有非常不同的硬件要求。数据库(尤其是关系型数据库)对IO的要求很高。一般的数据库引擎使用专用环境来避免并发资源的争用。如果将数据库放在容器中,就会浪费项目的资源。因为你需要为这个实例配置很多额外的资源。在公有云中,当你需要34G内存时,你启动的实例必须有64G内存。实际上,这些资源并未得到充分利用。如何处理?您可以分层设计并使用固定资源来启动不同层的多个实例。水平缩放总是比垂直缩放更好。3.网络问题要了解Docker网络,您必须对网络虚拟化有扎实的了解。还必须做好应对意外情况的准备。您可能需要在没有支持或其他工具的情况下修复错误。我们知道:数据库需要专用和持续的吞吐量来应对更高的负载。我们还知道,容器是管理程序和主机虚拟机背后的隔离层。然而,网络对于数据库复制至关重要,这需要主从数据库之间24/7的稳定连接。未解决的Docker网络问题在1.9中仍未解决。将这些问题放在一起,容器化使得数据库容器难以管理。我知道你是顶级工程师,任何问题都可以解决。但是,您需要花多少时间来解决Docker网络问题?将数据库放在专用环境中不是更好吗?节省时间专注于真正重要的业务目标。4.State封装Docker中的无状态服务很cool,可以实现容器的编排,解决单点故障问题。但是数据库呢?将数据库放在相同的环境中,它将是有状态的,并使系统更容易发生故障。下次您的应用程序实例或应用程序崩溃时,数据库可能会受到影响。5.数据库不适合与Docker主要功能一起使用。考虑容器中的数据库,我们来思考一下它的价值。我们来看看Docker的官方定义:Docker是一个供开发者和系统管理员构建、分发和运行分布式应用程序的开放平台。Docker包括DockerEngine(一种可移植的、轻量级的运行时和打包工具)和DockerHub(一种用于共享应用程序和自动化工作流的云服务),Docker使应用程序能够快速组装成组件,并消除开发、QA和生产环境之间的差异。因此,IT可以更快地分发程序并在笔记本电脑、数据中心和任何云中的虚拟机上运行相同的应用程序。基于这个答案,我们可以轻松定义Docker的主要特性:易于构建新环境易于重新部署(持续集成)易于水平扩展(来自实践)易于维护一致的环境让我们开始思考这些特性如何适应数据库世界。易于设置数据库?让我们看看在本地容器化或运行数据库是否会对性能产生巨大影响。dockerrun-dmongod:3.4比较:sudoapt-keyadv--keyserverhkp://keyserver.ubuntu.com:80--recv0C49F3730359A14518585931BC711F9BA15703C6echo"deb[arch=amd64,arm64]http://repo.mongodb.org/apt/ubuntuxenial/mongodb-org/3.4multiverse”|sudotee/etc/apt/sources.list.d/mongodb-org-3.4.listsudoapt-getupdate&&sudoapt-getinstall-ymongodb-org搭建新环境容易吗?如果我们谈论MongoDB集群——也许容器化更有效。但是配置管理系统呢?它们旨在通过运行单个命令来解决配置问题。使用Ansible,您可以轻松设置数十个Mongo实例。如您所见,没有显着的价值增加。易于重新部署?您多久重新部署一次数据库以升级到下一个版本?数据库升级不是可用性问题,而是工程问题(即集群中的可用性)。考虑一下您的应用程序将如何使用新的数据库引擎版本。更换发动机时可能导致的问题。横向扩展容易吗?你想在多个实例之间共享数据目录吗?你不怕直接的数据并发问题和可能的数据损坏吗?使用专用数据环境部署多个实例不是更安全吗?最后搞个主从复制?易于维护一致的环境?数据库实例环境多久更改一次?你每天升级你的操作系统吗?或者数据库版本或依赖软件是否经常变化?还是不容易和工程团队达成共识?最后,没有一个特性足以让我考虑数据库容器化。6.额外的隔离对数据库不利其实我在第二个和第三个原因中提到了这一点。但我将此列为一个单独的原因,因为我想再次强调这一事实。我们拥有的隔离级别越多,我们获得的资源开销就越大。与专用环境相比,简单的水平扩展可以给我们带来更多的好处。但是,Docker中的水平扩展只能用于无状态计算服务,不能用于数据库。我们看不到数据库有任何隔离能力,那为什么要把它放在容器里呢?7.云平台的不适用性大多数人通过公有云开始项目。云简化了虚拟机操作和更换的复杂性,因此无需在无人工作的晚上或周末测试新的硬件环境。既然可以快速启动实例,为什么还需要担心实例运行的环境呢?这就是我们向云提供商支付大量费用的原因。当我们为实例放置数据库容器时,上面提到的这些便利是不存在的。因为数据不匹配,所以新实例将与现有实例不兼容。如果要限制实例使用单机服务,应该让DB使用非容器化环境。我们只需要为计算服务层预留弹性扩展的能力即可。这7点是否适用于所有数据库?可能不是全部,但应该是所有需要持久化数据的数据库,所有对硬件环境有特殊要求的数据库。如果我们使用Redis作为缓存或用户会话存储——使用容器应该没有任何问题。因为不需要保证数据落地,所以没有数据丢失的风险。但是如果我们考虑使用Redis作为持久化数据存储,那么你最好把数据放在容器之外,即使不断刷新RDB快照,在瞬息万变的计算集群中也很难找到这个快照。我们还可以谈谈容器内部的Elasticsearch。我们可以在ES中存储索引并从持久数据源重建它们。但是看要求!默认情况下,Elasticsearch需要2到3GB的内存。由于Java的GC,内存使用不一致。您确定Elasticsearch适合资源受限的容器吗?让不同的Elasticsearch实例使用不同的硬件配置不是更好吗?不用担心本地开发环境的数据库容器化。将数据库放在本地容器中将为您节省大量时间和精力。您将能够复制生产操作系统。适用于OSX或Windows的本机Postgres与Linux版本并非100%兼容。在主机操作系统上设置容器而不是包,您将克服此类问题。结论Docker炒作总有一天会消亡。这并不意味着人们将停止使用容器虚拟化技术,而是我们在设计容器化时需要将其带来的价值作为首要考虑。前几天看到一个演讲,讲的是框架是如何在纷乱的Ruby世界中生存下来的。我从这次演讲中得到的灵感是技术炒作周期。借用这个炒作周期的术语,我们看到Docker目前处于第二阶段(充满期待的高峰)太久了(高可用架构编辑:见资源1),当我们看到最后一个阶段的Docker时,事情就会正常化.我认为我们需要对这个过程负责,并且应该加快它的速度。
