暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL挑战10万并发连接数,能成功吗?

Laravel技术社区 2020-05-17
839








现在的最火的小视频、直播等APP火得已经不能再火了,一个直播间就多则几百万人少则你自导自演,哈哈。那么问题来了,几百万人在线,还有那么多的互动,并发量,高可用怎么解决?单单数据库就能解决,那显然是不能的,数据库哪有那么大的能力支撑,但是也别小看数据库的能力。下面我们用MYSQL做个试验测试一下,MYSQL能力到底有多强?
实际测试客户端与MySQL建立100,000个连接的方法。不限于空闲连接,还有执行查询功能的连接。
你可能会问,使用MySQL的时候真的有必要建立100,000个连接吗?虽然看起来有点过于追求极致,还是可以支撑大量在线连接。实现方案呢还是有很多种不同的设计方案。
有的部署了应用程序连接池,每一个连接池中有100个应用服务和1000个连接。有的应用程序使用了一种很糟糕的技术,“在查询慢时重连或重用”。这有可能会导致雪球效应,并在几秒钟内建立数千个MySQL连接。
所以现在测试一下,设置一个超出预期的目标,看看能否实现。
使用以下硬件配置:
  • 裸机服务器实例大小:c2.medium.x86

  • 物理内核 @ 2.2 GHz (1 X AMD EPYC 7401P) 

  • 内存: 64 GB of ECC RAM 

  • 磁盘: INTEL® SSD DC S4500, 480GB

  • 这是一个服务器级的 SATA SSD。

我们将使用到5台主机,下面作出解释,一个用于MySQL服务器的主机,以及四个用于客户端连接的主机。
在服务器上,我将使用带有线程池插件的Percona Server for MySQL 8.0.13-4。这个插件可以支持数千个数据库连接
一、网络设置(Ansible格式):

这些是推荐用于10Gb网络和高并发工作负载的典型设置。
systemd限制设置:

还有my.cnf文件中MySQL相关设置:

客户端使用sysbench 0.5版本而不是1.0.x版本,原因我们将在下面解释。
二、工作负载配置

这一步很简单,没有太多的事情需要处理。我们可以只用一个客户端实现,需要在客户端设置ulimit -n大小来处理。
我们能观察到的:

使用25,000个连接的时候,在MySQL端会看到错误信息:

如果你查找这个错误的信息的话,但是这并不能解决我们的问题,因为我们已经把限制设置的足够高了:

三、我们是从这里开始使用线程池功能的:-server/8.0/performance/threadpool.html在my.cnf中增加:并重启 Percona 服务器。
打印结果:

现在还是相同的吞吐量,但是实际上95%的响应时间已经从3690毫秒优化到979毫秒(由于使用了线程池)。
这是目前我们遇到的最大的挑战。
1、首先,在尝试从sysbench中获取50,000个连接的时候遇到了以下错误:Error(99)是一个很隐蔽的错误,它表示:无法分配请求地址。
2、它是由应用程序可以打开的端口限制所触发,我的操作系统默认情况下是:这表示有28231个端口可用(60999减32768),或者说是与给定IP地址所能建立的TCP连接的端口数限制。你可以在客户端和服务端上使用一个更大的范围来扩展这些端口。
3、这给我们提供了61000个连接,但是已经非常接近一个IP地址的连接限制了(最大端口号65535)。关键点在于,如果我们想要更多的连接数,那么则需要为MySQL服务器分配更多的IP地址。为了实现100,000连接数,我将在运行MySQL的服务器上使用两个IP地址。
在整理出端口范围后,sysbench又抛出了以下问题

这是sysbench的内存分配问题(即lua子系统)。Sysbench只能为32,351个连接分配内存,这个问题在sysbench 1.0.x版本中尤为严重。
Sysbench 1.0.x使用了一套不同的Lua JIT(Just In Time,即时编译技术),甚至在连接数达到4000的时候就会产生内存问题,所以使用Sysbench 1.0.x想要超过4000连接数都是不可能的。
因此,与Percona Server相比,sysbench会更早达到连接数瓶颈。我们需要使用更多的sysbench客户端来实现更多的连接。如果sysbench的连接上限是32,351,那么至少要使用4个sysbench客户端才能达到100,000个连接。
我使用2台服务器(每个服务器运行单独的sysbench)实现50,000个连接,每个sysbench上运行25,000个线程。
每个sysbench上执行结果如下:

然而同样的吞吐量(总共 16794 * 2 = 33588 tps)的情况下,有95%的响应时间都翻了一倍。这是可以预见的,因为相比于25,000个基准测试连接,我们使用的连接数是原来的两倍。
我们将使用3个sysbench服务器来实现75,000个连接,每个服务器上运行25,000个连接。
每个sysbench的运行结果:

实现连接数从75k到100k并没有什么大的变化,我们只需要启动一个额外的服务器并启动sysbench就可以了。对于100,000个连接,我们需要四个sysbench服务器,每一个服务器显示:
所以相同吞吐量(总共 8065 * 4 = 32260 tps)时,有95%的相应时间为3405ms。
一个很重要的点是:建立100k个连接并使用线程池,95%的响应时间甚至比不带线程池的10k个连接更快。线程池使得Percona Server更有效的管理资源并提供更快的响应时间。
MySQL实现10万连接数是完全可行的,而且我相信我们还可以更进一步。这里有三个组件可以帮助我们实现目标:
  • Percona Server的线程池

  • 适当调整网络限制

  • 服务器主机使用多个IP地址(一个IP地址支持大约60k个连接)


作者整理了部分优质“后台系统”模板
扫 码 免 费 领 取


1、Laravel 最权威实用的Balde模板引擎
2、phpstorm 全网最全的IDEA快捷键总结
3、【干货】一篇文章学会Laravel框架所有路由知识
4、轻松搞定Laravel安装过程中的遇到常见异常问题
5、Laravel对接阿里云SMS发送短信验证码


看完本文有收获?点赞、分享是最大的支持!


文章转载自Laravel技术社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论