nodejs + redis/mysql 连接池问题
需不需要连接池
连接池的作用主要是较少每次临时建立连接所带来的开销。初步一看,nodejs运行单线程上,它不能同时使用多个连接,乍一看是不需要连接池的。但是这只是我们初步下意识的感觉,下面我们详细分析来看看这个结论对是不对。
先从简单的redis开始。
redis服务器也是运行在单线程上的。俩都是单线程,看起来更加坚定不需要连接池的结论了。
从详细的图像来看看nodejs 连接 redis用连接池有没有意义。
上图中,nodejs共有俩连接,分别发送查询请求到redis服务器上。因为redis是单线程作业,不管两个查询任务是由一个连接发来还是多个连接发来,也不管任务是串行一前一后先后发送到服务器,还是并行的同时发送到服务器上,redis都将他们一个个按顺序执行,并通过当前连接返回给客户端(这里是nodejs)。nodejs接受到redis的返回后,也管不了并行不并行,都得等他nodejs的主线程空闲的时候才能来一个个处理服务器返回的数据。
所以单从上面结论来看,nodejs + redis只需要公用一个连接就可以了,所以是不需要用连接池的。
再来看看nodejs + mysql下的情况
不同的是mysql不是单线程服务的,也就是它可以并行处理多个查询请求。
如上图所示,mysql会为每个连接创建一个单独的线程来查询。不同于redis数据基本都在内存中,因为mysql会有大量的读取磁盘的IO操作,所以多个线程一起工作会比一个个查询要快。
但是nodejs又是单线程的,它能不能同时发送多个请求到mysql服务器上呢?
这里要理解nodejs的运作,虽然nodejs是一个主线程,但是它调用的IO指令等是通过另外的线程去做的,IO指令完成后就给主线程一个小任务片,也就是回调函数了。
这里有个很关键的点就是,nodejs主线程一个,但是IO线程会有多个。
因此如果用nodejs + mysql只用单个连接的话那么就利用不到mysql能同时服务多个查询的优势了。应该使用类似下图的运作方式,nodejs 使用多个连接来连接mysql。多连接是需要连接池的,有连接池就避免了每次连接都要去创建销毁的消耗了。
所以我们第一步的感觉认为Nodejs是单线程而不是需要连接池是错误的,使用不使用连接池,不光看客户端,还要看数据库服务器等。要全盘理解整个系统的运作模式才能下结论。了解服务器的运作模式,有没有阻塞操作,是否是多线程等。我想redis设计成单线程主要原因在于它的数据基本都在内存中,查询数据过程总不会产生阻塞过程,cpu也不会处于空闲状态。
全局连接断开重连问题
到这里还没完。综上面的分析,nodejs + mysql用线程池是没什么问题的。nodejs + redis只用单个连接就够。不过也还是有人建议需要连接池。为了说明问题得从代码着手。我们使用node-redis这个包来做例子。
例如新建了一个db.js
var redis = require("redis"), client = redis.createClient(6379, "127.0.0.1"); module.exports = client;
上面的连接会在程序启动载入完后就连接上了。使用它的时候引入它就可以使用全局唯一的连接。
var db = require("db.js"); exports.add = function(req, res, next) { db.get("keyName", function() { res.send("ok"); }); }
这里于是有这样的问题存在。
但此处全局只有一个连接,并且这个连接是程序启动的时候创建的。它不同于连接池中的连接那样运行时候动态创建。如果某个时候唯一的连接断掉了,程序又不会动态去创建连接,岂不是需要重新启动服务器才行。
看是来挺可怕,但好在这个问题是不存在的。因为redis的客户端会自动重新连接,所以不需要重新启动服务器。
但是因为连接断开那一小段时间,应用服务器不能正常对外服务,但是连接自动重连是需要一定的时间间隔的。例如一秒之后,所以这一秒之内系统是处在不能服务状态。
也正是基于上面这样的原因,于是就有连接redis使用连接池的做法。如果使用连接池来管理,当连接不可用的时候立即手动去创建新连接。和自动重连相比,一个是手动立即重连,一个是等到一定间隔重连。相对来说手动重连的时间更短,也就是说系统那1秒中不能服务的状态或许可以缩短成0.5秒。于是就有了使用连接池管理redis连接的做法。严格来说这个不能算是连接池,而是一个连接管理模块。
到这里最后的结论nodejs + mysql使用连接池更好, nodejs + redis可以使用也可以不用。
转载:http://www.cnblogs.com/laozhbook/p/nodejs_redis_connection_pool.html
相关推荐
2. **MySQL数据库与连接池**: MySQL是一个广泛使用的开源关系型数据库管理系统,适用于处理大量数据。项目中采用了连接池(Connection Pool)来管理数据库连接,这样可以提高性能,减少创建和销毁连接的开销。连接...
- 数据库连接池:Alibaba Druid - 数据库缓存:Redis - 接口文档引擎:Swagger2 RESTful 风格 API 文档生成 - 全文检索引擎:Elasticsearch - 系统任务调度:Quartz ## 前后分离 - 前端框架:NodeJS + Vue + Axios...
数据库连接池:Alibaba Druid 数据库缓存:Redis 接口文档引擎:Swagger2 RESTful 风格 API 文档生成 全文检索引擎:Elasticsearch 系统任务调度:Quartz 前后分离 前端框架:NodeJS + Vue + Axios 前端模板:...
- 数据库连接池:Alibaba Druid - 数据库缓存:Redis Sentinel - 消息中间件:RocketMQ - 接口文档引擎:Swagger2 RESTful 风格 API 文档生成 - 全文检索引擎:ElasticSearch - 分布式链路追踪:SkyWalking - 分布式...
数据库连接池:Alibaba Druid 数据库缓存:Redis 接口文档引擎:Swagger2 RESTful 风格 API 文档生成 全文检索引擎:Elasticsearch 系统任务调度:Quartz 前后分离 前端框架:NodeJS + Vue + Axios
创建一个`db.js`文件,设置MySQL的连接配置,并提供连接池。 ```javascript const mysql = require('mysql2/promise'); const pool = mysql.createPool({ host: 'localhost', user: 'your_username', password:...
4. **连接池**: 在Node.js应用中,使用连接池可以有效地管理数据库连接,提高并发处理能力,减少资源消耗。 **Sumario论坛模板特点** 1. **前端框架**: Sumario可能采用了React、Vue或Angular等现代前端框架,提供...
## 技术选型- 核心框架:Spring Boot 2.7.1- 安全框架:Apache Shiro 1.9- 持久层框架:MyBatis 3.5- 定时器:Quartz 2.3- 数据库连接池:Druid 1.2- 日志管理:Logback- 页面交互:Vue2.x- 微信小程序:uni-app## ...
这涉及到SQL或NoSQL查询、连接池、ORM(Object-Relational Mapping)等技术。 3. **API设计与交互**: - **RESTful API**:后端通常通过RESTful API与小程序前端通信。这种设计风格使得接口清晰、易懂,遵循HTTP协议...
- 维护MySQL数据源的连接池,减少建立新连接的开销。 - 保证单线程语言的稳定性,防止内存泄漏等问题。 9. **负载均衡与性能优化**: - 利用Nginx和HAProxy进行负载均衡。 - Nginx的配置优化,如关闭代理缓冲...
`mysql`库提供了`Pool`类来创建连接池,可以显著提升性能并减少资源消耗。此外,为了确保代码的健壮性,应该始终处理可能的错误,并在必要时进行异常捕获和处理。 总之,Node.js结合`mysql`库为开发者提供了便捷的...
- 常见的数据库连接库如`mongodb`(MongoDB)、`mysql`(MySQL)、`pg`(PostgreSQL)等,使Node.js能无缝集成到各种数据库系统中。 8. **命令行工具** - Node.js也可用于创建命令行工具,利用`process.argv`获取...
- 数据库连接池:使用如mysql2或pg等库,建立数据库连接池,优化数据库操作并提升性能。 4. 毕业设计实践: - 设计一个基于Node.js的分布式文件存储系统,利用分布式一致性算法保证数据一致性。 - 构建一个实时...