# mysql连接池

先阅读官方文档[MySQL的连接池、异步、断线重连](https://wiki.swoole.com/wiki/page/350.html)章节

* 一、mysql连接池
* 二、mysql连接池创建

## 一、mysql连接池

&#x20;**1、什么是mysql连接池**

数据库连接池（Connection pooling）是程序启动时建立足够的数据库连接，并将这些连接组成一个连接池，由程序动态地对池中的连接进行申请，使用，释放。

**2、为什么需要mysql连接池**

创建数据库连接是一个很耗时的操作，MySQL短连接每次请求操作数据库都需要建立与MySQL服务器建立TCP连接，这是需要时间开销的，TCP连接需要3次网络通信。这样就增加了一定的延时和额外的IO消耗，在并发量非常大的情况就会有影响

假设有100台PHP的应用服务器，每个机器需要启动100个apache或fpm工作进程，那每个进程都会产生一个长连接到MySQL。这一共会产生1万个My SQL连接。大家都知道MySQL是每个连接会占用1个线程。那MYSQL就需要创建1万个线程，这样大量的系统资源被浪费在线程间上下文切换上。而你的业务代码中并不是所有地方都在做数据库操作，所以这个就是浪费的。

**3、如何解决**

如果有连接池就不同了，如并发100个请求，实际上并不是每个请求的所有时间都在执行SQL查询。这样100个请求，共享20个MySQL连接就可以满足需求了。当一个请求操作完数据库后，开始进入模板渲染等流程，这时就会释放数据库连接给其他的请求使用。

**4、适合场景**

连接池仅在超大型应用中才有价值，连接池并没有提高sql的查询速度，连接池是用来保护数据库的,限制连接数,为了避免连接过多导致数据库崩溃，不是用来提升性能的

建立连接----执行业务逻辑-----销毁

长连接性能是优于短连接,不需要重复的去建立连接,常驻内存要复用连接

普通的应用采用MySQL长连接方案，每个worker创建一个MySQL连接，每台机器开启100个worker进程。如果有10台机器，每台机器并发的请求为100。实际上只需要创建1000个MySQL连接就能满足需求，数据库的压力并不大。即使有100台机器，硬件配置好的存储服务器依然可以承受。

达到数百或者数千台应用服务器时，MySQL服务器就需要维持十万级的连接。这时数据库的压力就会非常大了。连接池技术就可以派上用场了，可以大大降低数据库连接数,减入服务器压力。

## 二、mysql连接池创建

数据的连接池为维持若干个长连接，当新请求到达的时候，如果连接池有空闲连接，就分配给连接池去处理，否则，后面的数据库连接请求将被加入到等待队列中。

**数据库连接池的机制：**

* （1）程序初始化时创建连接池
* （2）使用时向连接池申请可用连接
* （3）使用完毕，将连接返还给连接池
* （4）程序退出时，断开连接，并释放资源

  ![](https://3149448975-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LfnT31GMG1d9KiXwANW%2F-LfnT7UNILQRAFnaeTSW%2F-LfnTCmADgsVNBuJddsg%2F1.png?generation=1558862956430656\&alt=media)

**数据库连接池设计**

连接池中到底应该放置多少连接，才能使系统的性能最佳

* 1、最小连接数:

是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.

* 2、 最大连接数:

是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作

* 3、连接池的配置与维护

如何确保连接池中的最小连接数呢？有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测，如果发现连接数量小于最小连接数，则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

* 4、等待队列

SQL请求到达时如果没有空闲的数据库连接，那会自动加入到等待队列当中。一旦有SQL完成操作，将自动从等待队列中取出等待的请求进行处理。

**程序的逻辑：**

* 1、启动时创建N个MySQL连接，收到客户端发来的SQL后，分配1个MySQL连接，将SQL发往数据库服务器。然后等待数据库返回查询结果。当数据库返回结果后，再发给对应的客户端连接。
* 2、核心的数据结构是3个PHP队列结构。idle\_pool是空闲的数据库连接，当有SQL请求时,从idle\_pool中移到worker\_pool中。当数据库返回结果后从worker\_pool中再移到idle\_pool中，以供新的请求使用。当SQL请求到达时如果没有空闲的数据库连接，那会自动加入到wait\_queue中。一旦有SQL完成操作，将自动从wait\_queue中取出等待的请求进行处理。
