Docker容器中MySQL最大连接数被限制为214的解决方案
原文:Docker容器中MySQL最大连接数被限制为214的解决方案
一、背景
话说笔者在上次的博客里简单的讲了一下调整MySQL最大连接数的方法。在文章的最后笔者提到了还有一些特殊情况比如说Docker中,会导致MySQL的最大连接数被限制在一个值上。今天笔者就要来讲一下为什么在Docker环境中会出现这个问题。
这次的问题也是在公司实习的时候碰到的。当时导师要笔者去部署一个LAMP环境(不要问笔者为什么用docker还要把apache+PHP和MySQL塞在一起,这个问题您得问笔者导师),然后要调整一下Apache和MySQL的最大连接数。在调整结束之后笔者就想着要不进去看看有没有设置成功,就进入Docker容器的MySQL控制台,查看MySQL的最大连接数,结果是笔者之前设置的最大连接数并没有生效,MySQL的最大连接数被限制在了214。

二、解决方案
今天就先讲一下解决方案吧,因为当时遇到这个问题的时候真的是没有一点思路。去百度搜索了很久都没有找到什么靠谱的结果。最后抱着赌一赌的决心去Google上用英文搜了一下,结果在第一页就搜到了有人在stackoverflow提出的类似问题《Increasing mysql max_connections to 1024 in a docker container》,里面提出了一个解决方案:
在启动容器时加入参数:
--ulimit nofile=65536:65536
好的,那让我们试验一下行不行,在启动容器的时候加入--ulimit参数:

用docker exec命令进入容器,检查MySQL的max_connections变量值:

成功了!
三、思考
问题是解决了,但到底是为什么呢?
我们来看一下Docker官方对ulimit这个参数是怎么解释吧。
ulimit这个参数最初出现于Docker 1.6版本,在官方博客《Docker 1.6: Engine & Orchestration Updates, Registry 2.0, & Windows Client Preview》里,他们对ulimit参数的是这么解释的:
Ulimits
Up until now, containers inherit the ulimit settings from the docker daemon. This tends to be extremely high to account for production workloads, but is not ideal inside the container. Ulimits allow you to limit the resources of a given process (you may be familiar with the command line tool ulimit). With this new feature, you can now specify the default ulimit settings for all containers, when configuring the daemon. For example:
docker -d --default-ulimit nproc=1024:2048
This will set a soft limit of 1,024 and a hard limit of 2,048 child processes for all containers. You can set this option multiple times for different ulimit values: --default-ulimit nproc=1024:2408 --default-ulimit nofile=100:200
These settings can be overwritten when creating a container as such:
docker run -d --ulimit nproc=2048:4096 httpd
This will overwrite the default nproc value passed into the daemon.
Thanks to Brian Goff for this patch. If you are interested in the original pull request you can view it here.
个人渣翻:
Ulimits
直至当前,容器通过从docker守护进程继承ulimit设置,这对于生产工作量来说往往是非常高的,但在容器的内部却并不理想。Ulimits将允许您去限制给予进程的资源(您可能熟悉命令行工具ulimit)。通过这个新功能,您现在可以在设置守护程序时向所有的容器指定默认的ulimit设置。例如:
docker -d --default-ulimit nproc = 1024:2048
这将为所有容器设置1024个软限制和2048个硬限制的子进程限制。您可以对不同的ulimit值多次设置此选项:--default-ulimit nproc=1024:2408 --default-ulimit nofile=100:200
这些设置可以在创建容器本身时被重写:
docker run -d --ulimit nproc=2048:4096 httpd
这将重写之前传入守护程序中的默认nproc值。
感谢Brian Goff提供的补丁。如果您对原始的pull request感兴趣,您可以去这里查看。
简单的说呢就是,在Docker容器将继承Docker守护进程的ulimit设置,我们通过在启动容器的时候加上--ulimit nofile=65536:65536参数,重写了容器内部的nofile限制值。
四、其他修改默认设置方法
由于笔者要部署的容器都需要提高MySQL的最大连接数,每次启动的时候都要设置ulimit参数会变的非常繁琐。如果使用文档中提到的docker -d --ulimit这种方式如果以后突然要返回默认值就比较麻烦了。有没有什么一劳永逸且设置方便取消也方便的方法呢?答案当然是有的——修改docker守护进程ulimit设置。
由于这里用的系统是CentOS 6.9,所以不存在docker.service文件。但我们可以通过修改服务启动脚本来实现:
vim /etc/init.d/docker
在文件的开始部分加入以下代码:
ulimit -u 65536 -HSn 65536

保存后退出vim。
现在我们回到容器中,这次我们不添加--ulimit参数,看看能不能解除MySQL最大连接数214的限制。

和刚刚一样,用docker exec进入lamp容器内部,检查MySQL当前max_connections变量值:

可以看到,现在就算没有加入--ulimit参数,MySQL最大连接数也可以突破214的限制了。
五、写在最后
为什么在第四章笔者给出了一种修改服务配置文件的方式而不是通过官方提供的docker -d --ulimit方法去调整docker守护进程的ulimit值呢?主要的原因大概就是docker官方在后面的更新中,也是使用修改服务配置文件的方式设置了默认的ulimit设置。
在写本文时,笔者因为需要截图,所以打算在自己的笔记本中搭建环境,但一开始用的是CentOS 7系统,在实际的操作过程中就算没有加--ulimit参数,容器内的MySQL也可以突破最大连接数为214的限制,Ubuntu 16.04也是如此。只有CentOS 6才出现了这个问题。通过查看CentOS 7和Ubuntu 16.04的docker.service文件后,笔者发现在docker.service中,已经默认加入了LimitNOFILE和LimitNPROC这两项设置并默认给予了一个非常大的数值,所以这个问题就不会出现在CentOS 7和Ubuntu 16.04上了。
CentOS 7 docker.service文件部分截图:

Ubuntu16.04 docker.service文件部分截图:

所以笔者个人觉得通过修改docker守护进程的配置文件来设置ulimit值的方法更为妥善。
Docker容器中MySQL最大连接数被限制为214的解决方案的更多相关文章
- docker容器下mysql更改WordPress的site address和home(URL)------局域网
先简单介绍下,用docker安装的WordPress,mysql是在docker容器中的,并未在Ubuntu(我把WordPress是安装Ubuntu系统上),即WordPress和Ubuntu是独立 ...
- docker多个容器连接 将 Rails 程序部署到 Docker 容器中
在docker中使用MySQL数据库 https://yq.aliyun.com/articles/583765 将 Rails 程序部署到 Docker 容器中
- Elasticsearch核心技术(1)--- Docker容器中运行ES、Kibana、Cerebro
Docker容器中运行ES,Kibana,Cerebro和Logstash安装与数据导入ES 想加强ES有关的知识,看了阮一鸣老师讲的<Elasticsearch核心技术与实战>收获很大, ...
- Docker容器内Mysql大小写敏感方案解决
Docker容器内Mysql大小写敏感方案解决 一.(lower_case_table_names)参数说明 二.Docker 部署 MySql 并修改为大小写不敏感 2.1直接在Docker启动的时 ...
- Docker容器中运行ASP.NET Core
在Linux和Windows的Docker容器中运行ASP.NET Core 译者序:其实过去这周我都在研究这方面的内容,结果周末有事没有来得及总结为文章,Scott Hanselman就捷足先登了. ...
- 在 docker 容器中捕获信号
我们可能都使用过 docker stop 命令来停止正在运行的容器,有时可能会使用 docker kill 命令强行关闭容器或者把某个信号传递给容器中的进程.这些操作的本质都是通过从主机向容器发送信号 ...
- Docker容器中开始.NETCore之路
一.引言 开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境 ...
- 隔离 docker 容器中的用户
笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果 ...
- Docker容器中开始.Net Core之路
开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境,服务器也 ...
随机推荐
- 可持久化线段树(主席树)——静态区间第k大
主席树基本操作:静态区间第k大 #include<bits/stdc++.h> using namespace std; typedef long long LL; ,MAXN=2e5+, ...
- 莫烦pytorch学习笔记(二)——variable
.简介 torch.autograd.Variable是Autograd的核心类,它封装了Tensor,并整合了反向传播的相关实现 Variable和tensor的区别和联系 Variable是篮子, ...
- CentOS源码安装Wireshark
(2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2016年8月25日) Wireshark为网络管理员常用的一个网络管理工具,通过使用这个软件,我们可以对本机网卡上的经过的 ...
- mysql数据库创建数据库创建用户授权
Liunx下登录数据库 >mysql -u 用户名 -p 创建myblog用户,本地登录,口令是myblog create user 'myblog'@'localhost' identifie ...
- GitHub:如何构建一个股票市场知识图谱?(附代码&链接)
来源:专知 本文约 600007 董事⻓/董事 高燕 女 60 600007 执⾏董事 刘永政 男 50 600008 董事⻓/董事 ··· ··· ··· ··· ··· 注:建议表头最好用相应的英 ...
- 近期开发storm遇到一些问题的解决点
storm开发解决问题点1.kafka消费速度跟不上问题 这个问题可以从加大topic partition进行解决,可以在topic正在运行时候运行命令 ./kafka-topics --alter ...
- 二进制操作(1)–Bytes
1,Bytes的单元被当作字符串处理. 例如: 有些介绍会声称上述程序会得到这样的结果:b'\x00\x00\x00\x00' 在python v2.7.10上是得不到此结果的. 实际上,如果 typ ...
- 如何使用Tunnel SDK上传/下载MaxCompute复杂类型数据
基于Tunnel SDK如何上传复杂类型数据到MaxCompute?首先介绍一下MaxCompute复杂数据类型: 复杂数据类型 MaxCompute采用基于ODPS2.0的SQL引擎,丰富了对复杂数 ...
- WIN32_FIND_DATA 详细结构(附循环读取文件代码)
//去除路径最后多余的斜杠和反斜杠 std::string TrimPath(std::string path) { //string test3("内容"); 使用引用字符数组作 ...
- bzoj4574:Zjoi2016线段树 dp
传送门 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #includ ...