本文原文链接
尼恩说在前面
在45岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团、蚂蚁、得物的面试资格,遇到很多很重要的相关面试题:
问题:MySQL为什么不推荐使用Docker部署?
最近有小伙伴面试美团 问到此 面试题。 小伙伴没有系统的去梳理和总结,所以支支吾吾的说了几句,面试官不满意,面试挂了。
所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。
当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V175版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。
《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取
MySQL为什么不推荐使用Docker部署
docker可以从远程仓库拉取镜像然后通过镜像快速的部署应用,非常的方便快捷,
但是 , 为什么 一般公司的 Mysql 不用docker部署,而是部署在 物理机器上呢?
接下来, 45岁老架构师尼恩, 给大家彻底的梳理一下, 让面试官口水直流。
第一大问题:DB有状态,不方便扩容
1.1 Docker容器的两大类型: 有状态 、无状态的区分
Docker容器的两大类型: 有状态 、无状态的区分,它们在数据存储、应用场景、管理方式等方面存在明显区别。
有状态容器:
容器在运行过程中, 需要 持久化 和管理数据状态信息的容器。
有状态容器需要对这些数据进行持久化存储,以便在容器重启或迁移后能够恢复到之前的状态,保证应用程序的正常运行。
有状态容器 需要使用数据卷(Volumes)、绑定挂载(Bind Mounts)或网络存储等方式将数据持久化到宿主机或外部存储设备上,确保数据在容器的生命周期之外也能保存。
有状态容器 适用于需要保存和管理数据的应用,如数据库系统、消息队列、文件服务器等。这些应用需要在不同的请求之间保持数据的一致性和完整性,并且能够在容器重启或故障转移后恢复到之前的状态。
有状态容器 扩容 复杂。 需要考虑数据的一致性和分布问题,确保新启动的容器能够正确地访问和更新共享数据。
无状态容器:
容器在运行过程中不保存任何数据状态信息 。
无状态容器通常只负责处理输入请求并返回结果,不依赖于之前的运行状态。
它们可以随时被销毁、重启或替换,而不会对应用程序的整体功能产生影响,因为所有需要的信息都通过外部输入或共享资源提供。
无状态容器 一般不需要专门的数据持久化机制,容器内产生的临时数据通常存储在容器的可写层,但这些数据在容器重启或删除后会丢失。
无状态容器 常用于处理无状态的任务,如 Web 应用程序的前端服务、负载均衡器、API 网关等。这些应用可以根据接收到的请求即时生成响应,不需要依赖于内部的状态信息。
有状态容器 扩容 简单。由于容器之间没有状态依赖关系,可以根据负载情况轻松地增加或减少容器实例,实现水平扩展。容器编排工具(如 Kubernetes)可以很方便地对无状态容器进行调度和管理,实现高可用性和弹性伸缩。
1.2 Mysql 是有状态的,不方便扩容
1.3 为什么 MySQL 是有状态的?
- 数据持久化:MySQL 需要将数据存储在磁盘上,以便在容器重启后数据仍然存在。
- 配置文件:MySQL 的配置文件(如
my.cnf
)也需要持久化,以便在容器重启后仍然生效。 - 日志文件:MySQL 的日志文件(如错误日志、二进制日志等)也需要持久化,以便在需要时进行故障排查和数据恢复。
如何在 Docker 中实现 MySQL 的数据持久化?
Mysql是用来存储的数据,docker部署Mysql之后, 数据文件 不会存储在容器内部,因为容器关闭之后,内部数据就丢失了。
所以, 为了确保 MySQL 数据在 Docker 容器关闭后不会丢失,需要将数据文件、配置文件和日志文件挂载到宿主机上
数据文件 需要挂载到容器外部,也就是 宿主机器上,如下图所示:
Docker部署MySQL并实现数据持久化, 以下是实现步骤:
第一步,在宿主机上,创建存储目录:
在宿主机上创建目录来存储MySQL的数据、日志和配置文件:
mkdir -p /data/mysql/{
data,logs,conf}
第2步,拉取MySQL镜像: 通过Docker Hub拉取MySQL的官方镜像:
docker pull mysql:latest
第3步,配置MySQL: 在 /data/mysql/conf
目录下,创建一个名为 my.cnf
的配置文件,用于设置MySQL的字符集、排序规则等参数:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
datadir=/var/lib/mysql
log-error=/var/log/mysqld.log
第4步,启动MySQL容器:
使用以下命令启动MySQL容器,并将其宿主机目录挂载到容器内部:
docker run -d \
--name mysql-server \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=your_password \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/logs:/var/log/mysqld \
-v /data/mysql/conf/my.cnf:/etc/mysql/my.cnf \
mysql:latest
1.4 容器化部署mysql 带来的扩容困境
一个容器的资源,是非常有限的。
随着业务的持续不断的发展,Mysql难免会出现需要扩容的情况。
但是,如何扩容呢?
扩容的时候就会出现一些困难,如下所示:
此时 Mysql2是无法挂载到文件1上的,因为宿主机的数据文件是容器独占的,无法实现两个容器实例共享一份数据文件。