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却苦于没有开发环境,服务器也 ...
随机推荐
- 廖雪峰Java11多线程编程-3高级concurrent包-3Condition
Condition实现等待和唤醒线程 java.util.locks.ReentrantLock用于替代synchronized加锁 synchronized可以使用wait和notify实现在条件不 ...
- 洛谷 P1242 新汉诺塔
原题链接 题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案 ...
- System.Web.Mvc.EmptyResult.cs
ylbtech-System.Web.Mvc.EmptyResult.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral, Public ...
- Installer - 使用Maven自动布署至外部Tomcat
一.配置相关文件 1.配置tomcat的conf/tomcat-users.xml文件 <tomcat-users> <role rolename="manager-scr ...
- CentOS6.5下源码安装多个MySQL实例及复制搭建
多实例安装本节是在CentOS6.5下源码安装MySQL5.6.35的基础上,在同一台机器增加一个MySQL实例.参考Centos中安装多个mysql数据的配置实例,安装目录为/usr/local/m ...
- <每日一题>题目22:简单的python练习题(31-40)
#31.分布式爬虫主要解决什么问题? ''' ip 带宽 CPU IO ''' #32.网络传输层 ''' 应用层—http ftp dns nfs 传输层—tcp --udp 网络层—ip icmp ...
- C#Image和Icon的相互转化
Image img = Image.FromHbitmap(icon.ToBitmap().GetHbitmap()); Graphics g = Graphics.FromImage(img); g ...
- Activiti流程图部署及流程图部分操作
流程图部署有两种方式,一种是通过classpath,另一种是通过zip文件 通过classpath方式如下 public void deploymentProcessDefinition_classp ...
- Joining Byte Blocks(哈希+带花树)
题目链接 Problem Statement As you are probably aware, the Internet protocols specify a canonical byte or ...
- 自己动手编写JEECMS自定义栏目统计标签
今天想在给Java客二级版面加入栏目文章统计效果,如下图, 查看JEECMS的源代码发现开发者版本还没有类似现成的统计标签,一种解决的办法是使用现有的JEECMS标签,像这样Struts( [@cms ...