Contents
docker启动mysql时内存占用过多
转载: https://chenwx.top/p/docker-mysql-event1.html
参考: https://github.com/containerd/containerd/issues/6707
参考: https://github.com/docker-library/mysql/issues/579、
简述
使用 docker-compose 搭建一个 mysql 环境; 8.0 版本启动正常; 5.7 版本启动后内存占用非常高, 16G 的主机内存占用了 14G, 且内存波动幅度大;
排查后认定是 ulimt 资源限制的问题, 加以限制后解决此问题
现象
使用 docker-compose 搭建一个 mysql 环境, 内容如下
version: '3'
services:
dbmysql:
image: mysql:5.7.43
restart: always
# mem_limit: 3G
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Shanghai
ports:
- 3306:3306
volumes:
- mysql_data:/var/lib/mysql
- ./my.cnf:/etc/mysql/conf.d/my.cnf:ro
volumes:
mysql_data:
启动成功, 但是主机的内存使用率非常高; top 查看时发现, mysqld 进程的 VIRT 和 RES 都很高, 明显的异常;
开始以为是版本的原因, 但是更换了几个5.7的版本也是这样;
解决
那就 google 一下吧; 筛选到一篇文章; https://github.com/containerd/containerd/issues/6707
增加资源限制后的配置
version: '3'
services:
dbmysql:
image: mysql:5.7.43
restart: always
# mem_limit: 3G
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Shanghai
ulimits:
nproc: 65535
nofile:
soft: 26677
hard: 46677
ports:
- 3306:3306
volumes:
- mysql_data:/var/lib/mysql
- ./my.cnf:/etc/mysql/conf.d/my.cnf:ro
volumes:
mysql_data:
问题解决, 内存使用稳定了;
原因分析
这个问题的直接原因是文件描述符上限太大了;
以前的很多软件在启动的时候都会有一些初始化的动作; 如关闭所有能关闭的文件描述符, 关闭所有能关闭的网络 socket 这一类的动作, 避免之前程序的干扰,或者是确认资源能使用;
但是早期版本的 linux 文件描述符上限, 默认一般是 1024, SA优化一般也就修改为 65535, 所以软件启动时很快就能执行完了, 说多也就1-2s; 也不会占用太多内存;
普通软件在未配置的情况也是继承操作系统的这个数值;
可是新版本的 kernel 和 el9+ 等新发行版把这个 系统级别的限制数值提高了非常多; 就导致很多传统软件在未适配的情况要么启动时CPU使用率极高, 要么启动时内存占用非常大;
这里应该是新版本的 containerd 自己单独修改的 ulimit 的上限导致的; 所以这个对容器单独进行资源限制解决了这个问题;
同时此问题未在 mysql 8.0+ 上出现, 猜测应该是程序自己有做优化;
此问题在目前这个过度阶段里面很常见;
比如在 el9 上部署 ceph 集群时, 一旦创建 pool 后, mon 主节点的 CPU使用率就满了,然后被迫自动切换 leader, 然后下一个 leader 又接着打满; 这个问题排查了几天, 最后也还是这这个原因, 限制了 mon 的 limit 资源后就正常了;
docker ulimit 配置
转载来源: https://sukbeta.github.io/docker-ulimit-configure/
一:通过docker run –ulimit 参数设置这个容器的 ulimit 值
如
docker run --ulimit nofile=1024:1024 --rm debian sh -c "ulimit -n"
官网说明: https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container—ulimit
二: 修改 docker 服务的 默认设置
vim /usr/lib/systemd/system/docker.service
[Service]
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
systemctl daemon-reload systemctl restart docker
文档: https://blog.csdn.net/signmem/article/details/51365006
- 注释 设置为 infinity 时,值为 65536 ,如 LimitNOFILE=infinity,ulimit -n 值为 65536
三 : daemon.json 文件中配置
vim /etc/docker/daemon.json
{
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
}
}
systemctl restart docker
文档 https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
- 注释: daemon.json 和 docker.service 两个都配置 ,daemon.json 中的配置生效。
For Example
- 一个es memlock 的例子
docker run --rm -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1 docker.elastic.co/elasticsearch/elasticsearch:6.5.0
发表回复