持久性存储是指以非易失性的方式保留数据,这样即使在设备或应用程序关闭或重新启动后,数据仍然可用。数据的存储和检索允许网络应用保存用户信息和状态并可靠地运行。
在单体应用中,存储访问是直接的,因为服务器和存储是住在一起的。然而,地理上的分布式系统使访问变得更加复杂,因为存储系统必须保持对全球所有组件可用。
容器化使问题进一步复杂化,因为容器是轻量级的、无状态的和短暂的–不适合存储数据的特性。因此,任何持久性存储解决方案必须能够与容器无缝工作,这又增加了一层复杂性。
本文通过探索持久性存储的类型、架构和使用案例,深入研究了持久性存储。它还提供了一个实践演示,说明Docker中卷存储和持久化卷存储之间的区别。
非易失性存储有几种类型,包括传统的旋转磁盘(硬盘驱动器或HDD)、固态驱动器(SSD)、网络附加存储(NAS)和存储区域网络(SAN)。
持久性存储有三种方法,每种方法都有独特的使用情况和限制。
对象持久化架构方法使用对象关系映射(ORM),将数据作为对象存储在关系数据库或键值数据库中。当数据没有定义模式时,这种方法很有用,因为ORM处理其存储和检索。
块持久化架构使用块级存储设备,在存储大文件时很有用。这种方法在存储大量数据时很有好处,因为你可以使用多个块来增加存储容量。
顾名思义,文件存储持久性架构方法使用文件系统来存储数据。一种方法是使用数据库服务器,它提供了一种集中的数据存储方式。像Kinsta的云主机解决方案使用数据库服务器,它很容易连接到应用程序并提供持久性。
文件存储的持久性架构在需要频繁检索文件的应用中很有帮助,而且当你需要一个界面来管理它们时。
本节讨论了每种存储类型的一些使用案例。
对象持久性存储
块持久性存储
文件存储持久性存储
容器是轻量级的、可移植的、安全的和直接的,提供了不同应用程序之间的融合。它们必须有一种机制,在容器重启和移除之间持续保存数据。容器有文件存储或像传统应用程序一样的文件系统,但每当你用新的变化重建它们时,你会失去所有非持久性的数据。
这就是为什么容器提供了包括卷存储或挂载存储卷的选项。容器将存储卷视为一个目录。任何写入卷的数据都会进入主机文件系统。
容器的持久化存储必须以这种方式工作,因为重新启动容器会创建一个新的实例,并丢弃旧的实例。如果一个容器没有一个一致的数据视图,当容器重新启动时,数据就会消失。一个存储卷可以跨会话和容器重启来保存数据,使容器即使被移动或重启也能保持其状态。
容器提供了2种存储持久性数据的方法:使用卷和持久性卷。它们之间存在着显著的区别。容器管理着卷存储中的数据。当你停止一个容器时,数据仍然存在,并且在你重新启动容器时是可用的。然而,当你删除或移除一个容器时,数据会丢失,因为你也删除了底层卷存储。
持久卷存储或绑定挂载是一种将数据存储在容器的文件系统之外的方式。这样一来,即使你删除了容器,数据也不会丢失。它是持久的,直到手动删除。
下面的章节用例子演示了这两种卷的类型。
我们已经创建了一个小型的网络应用程序来演示Docker容器的持久化存储。你可以通过安装Docker和从这个GitHub仓库抓取代码来跟随。
该应用程序是一个基本的表单,有两个字段供用户输入:
演示应用程序的GUI,有Title和Document Text字段。
一旦你保存了用户的输入,你就可以通过打开feedback目录中的文件来访问它,文件的名称在Title字段中提供。Document Text字段的输入是文件的内容。
一旦你在自己的机器上安装了该应用程序,它就可以使用Dockerfile中显示的卷存储。
Docker文件显示了卷存储的使用。
现在,你构建镜像并运行容器。要做到这一点,执行以下命令。
docker build -t feedback-node:volumes .
docker run -d -p 3000:80 --name feedback-app feedback-node:volumes
用卷存储构建应用程序。
运行该容器显示它正在管理卷存储。
一旦应用程序运行,导航到localhost:3000来提交反馈。
提交对应用程序的反馈。
点击 “Save“,并导航到localhost:3000/feedback/test.txt,看看输入是否被成功存储。
成功的反馈得到确认。
移除并重启容器,看看输入是否持续存在。
docker stop feedback-app
docker start feedback-app
如果你现在访问同一个网址,你会发现反馈仍然在那里。但是,如果你删除容器并重新启动它会发生什么?
docker stop feedback-app
docker rm feedback-app
docker run -d -p 3000:80 --name feedback-app feedback-node:volumes
一旦重新启动,如果你返回到那个URL,它就不再存在了,因为数据在你删除容器时已经丢失了。卷数据只在停止容器时持续存在,而不是在移除容器时持续存在。
反馈数据已经丢失。
为了缓解这个问题,即使你删除了容器,也要坚持数据,你必须使用持久性卷存储或命名存储。首先,你应该清理容器和镜像。
docker stop feedback-app
docker rm feedback-app
docker rmi feedback-node:volumes
在测试之前,你必须从Dockerfile中删除VOLUME属性并重建镜像。
更新了Dockerfile,删除了VOLUME属性。
docker build -t feedback-node:volumes .
docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback feedback-node:volumes
正如你所看到的,在第二条命令中,你使用 -v
标志来定义容器外的持久化卷,即使你移除容器,它也会持续存在。
像上一步一样,尝试添加反馈,一旦你停止、移除和重启容器,就可以访问它。
为一个持久性测试添加新的反馈。
docker stop feedback-app
docker rm feedback-app
docker run -d -p 3000:80 --name feedback-app -v feedback:/app/feedback feedback-node:volumes
正如你所看到的,即使在停止和移除容器之后,数据仍然可以被访问,并且保持不变。
在停止和移除容器后,数据仍然存在。
持久性存储对于容器化应用来说至关重要,因为它可以在容器的生命周期之外持久保存数据。容器化应用的2种主要持久性存储是卷和绑定挂载,每一种都有其好处和用例。
卷存储在容器的文件系统中,而绑定挂载可以在主机上直接访问。
持久性存储使数据可以在容器之间共享,从而使建立复杂的多层应用成为可能。持久性存储对于确保容器化应用的稳定性和连续性至关重要,它提供了一种可靠和灵活的方式来存储关键数据。