面试题:为什么数据库连接池不采用 IO 多路复用?

今天我们聊一个不常见的 Java 面试题:为什么数据库连接池不采用 IO 多路复用?

这是一个非常好的问题。IO多路复用被视为是非常好的性能助力器。但是一般我们在使用 DB 时,还是经常性采用c3p0,tomcat connection pool等技术来与 DB 连接,哪怕整个程序已经变成以Netty为核心。这到底是为什么?

首先纠正一个常见的误解。IO 多路复用听上去好像是多个数据可以共享一个 IO(socket 连接),实际上并非如此。IO 多路复用不是指多个服务共享一个连接,而仅仅是指多个连接的管理可以在同一进程。在网络服务中,IO 多路复用起的作用是一次性把多个连接的事件通知业务代码处理。至于这些事件的处理方式,到底是业务代码循环着处理、丢到队列里,还是交给线程池处理,由业务代码决定。

在这里插入图片描述
对于使用 DB 的程序来讲,不管使用多路复用,还是连接池,都要维护一组网络连接,支持并发的查询。

为什么并发查询一定要使用多个连接才能完成呢?因为 DB 一般是使用连接作为 Session 管理的基本单元。在一个连接中,SQL 语句的执行必须是串行、同步的。这是由于对于每一个 Session,DB 都要维护一组状态来支持查询,比如事务隔离级别,当前 Session 的变量等。只有单 Session 内串行执行,才能维护查询的正确性(试想一下一组 sql 在不断的增减变量,然后这组 sql 乱序执行会发生什么)。维护这些状态需要耗费内存,同时也会消耗 CPU 和磁盘 IO。这样,限制对 DB 的连接数,就是在限制对 DB 资源的消耗。

因此,对 DB 来说,关键是要限制连接的数目。这个要求无论是 DB 连接池还是 NIO 的连接管理都能做到。

图片

这样问题就绕回来了,为什么 DB 连接不能放到 IO 多路复用里一并执行吗?为啥大家都用连接池?

答案是,可以用 IO 多路复用——但是使用 JDBC 不行。JDBC 是一个出现了近 20 年的标准,它的设计核心是 BIO(因为 199X 年时还没有别的 IO 可以用):调用者在通过 JDBC 时执行比如query这样的API,在没有执行完成之前,整个调用线程被卡住。而类似于Mysql Connector/J这样的driver完备的实现了这套语义。

当然如果 DB Client 的协议的连接处理和解析稍微改一下:

  1. 将 IO 模式调整为 Non-Blocking,这样就可以挂到 IO 多路复用的内核上(select、epoll、kqueue……)
  2. 在 Non-Blocking 实现的基础之上实现数据库协议的编码和解析

就可以实现用 IO 多路复用来访问 DB。实际上很多其他语言/框架里都是这么干的。比如 Nodejs,see https://github.com/sidorares/node-mysql2;或者 Vert.X 的 db 客户端https://github.com/mauricio/postgresql-async,不要在意这个名字,它实际上同时支持 mysql 和 postgres)。只不过对于 IO 多路复用,数据库官方似乎都没做这种支持——他们只支持 JDBC、ODBC 等等这些标准协议。

那么为什么基于 IO 多路复用的实现不能成为默认的,官方的,而要成为偏门呢?

对于数据库开发者来说。这种用法在整体的用户里占有量非常小,所以也许不值当的花大力气。只需要把协议写清楚(比如https://dev.mysql.com/doc/internals/en/client-server-protocol.html),就可以做实现。那么社区的有兴趣的人自然就可以去做。

另外一个原因是体系的支持。简单来讲,如果没有一个大的 Reactive 的运行环境,IO 多路复用的使用会非常受限。

IO 多路复用之所以能成立,是需要整个程序要有一个 IO 多路复用的驱动代码——就是 select 那句调用——等待事件来临,一个 blocking 的 API。整个程序必须以这个驱动代码为核心。这样就对整个代码的结构产生重大的影响。这种影响是没法用简单的接口抽象的。

Java Web 容器之所以可以使用 NIO 是因为 NIO 可以被封装到容器内部。Web 容器对外暴露的还是传统的多线程形式的Java EE接口。

如果 DB 和 Web 容器同时使用 NIO,那么调用的 DB 连接库与必须与容器有一个约定描述DB 的连接管理如何接入 Web 容器的 NIO 的驱动代码。在 Java 这个大环境下,不同人,不同的容器写的代码不同;又或者,不使用任何常见的容器,而是自己用 NIO 去封装一个。这样是无法形成代码上的约定的。那么多个独立的组件就不能很好的共享 NIO 的驱动代码。

上面这个用法假设整个程序应该共享一个 NIO 驱动代码。那么 Web 和 DB 可不可以各用各的呢?也是可以的,但是为了保证这两个 NIO 驱动代码不会相互 block,最好要分开两个线程。这样一来就会打破一般 Web 服务一个请求处理用一个线程的一般做法,会让程序边的更复杂——你的业务代码和 DB 查询之间必须做跨线程数据交换。

相反,连接池的实现就相对独立的多,也简单的多。外界只要配好 DB URL,用户名密码和连接池的容量参数,就可以做到自行管理连接。

而Nodejs和Vert.X是完全不同的。他们本质就是Reactive的。他们的NIO的驱动方式是其运行时的基础——所有要在这个基础上开发的代码都必须遵守同样的NIO+异步开发规范,使用同一个NIO的驱动。这样DB与NIO的协作就不成问题了。

最后,有大量场景是需要 BIO 的 DB 查询支持的。批处理数据分析代码都是这样的场景。这样的程序写成 NIO 就会得不偿失——代码不容易懂,也没有任何效率上的优势。类似于Nodejs这样的运行时在此场景下,反而要利用async或等价的语法来让代码看起来是同步的,这样才容易写。

总结一下。DB 访问一般采用连接池这种现象是生态造成的。历史上的 BIO + 连接池的做法经过多年的发展,已经解决了主要的问题。在 Java 的大环境下,这个方案是非常靠谱的,成熟的。而基于 IO 多路复用的方式尽管在性能上可能有优势,但是其对整个程序的代码结构要求过多,过于复杂。当然,如果有特定的需要,希望使用 IO 多路复用管理 DB 连接,是完全可行的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/215089.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++基础 -37- 模板函数与普通函数调用规则

当模板函数比普通函数更好匹配形参的时候&#xff0c;会优先调用模板函数 #include "iostream"using namespace std;template <class T> void show(T a, T b) {cout << a << endl;cout << b << endl;cout << "temp show&…

MQ - KAFKA 高级篇

kafak是一个分布式流处理平台,提供消息持久化,基于发布-订阅的方式的消息中间件&#xff0c;同时通过消费端配置相同的groupId支持点对点通信。 ##适用场景&#xff1a; 构造实时流数据管道,用于系统或应用之间可靠的消息传输.数据采集及处理,例如连接到一个数据库系统,捕捉表…

Redis--15--缓存穿透 击穿 雪崩

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 缓存穿透 击穿 雪崩运行速度:1 缓存穿透问题描述:如何解决: 2 缓存击穿问题描述:如何解决: 3 缓存雪崩说明:解决方案: 缓存穿透 击穿 雪崩 问题描述: 由于海量的用…

漂亮极了!分享我收藏的 16 款 VS Code 主题

你好&#xff0c;我是 EarlGrey&#xff0c;喜欢翻译点东西&#xff0c;偶尔写写代码。 点击下方卡片关注我&#xff0c;一起向上进击&#xff0c;提升自我。后台回复关键词“电子书”&#xff0c;送你一份我收藏的电子书合集。 Visual Studio Code&#xff08;VS Code&#xf…

VMware安装OpenEuler(安装界面)

本文中使用的OpenEuler版本&#xff1a;22.03 LTS SP2 VMware&#xff1a;17.0.0 一、下载镜像 根据CPU和场景&#xff0c;按需下载 https://www.openeuler.org/zh/download/?versionopenEuler%2022.03%20LTS%20SP2 二、初始化VmWare 三、配置操作系统 四、安装操作系统 …

Python:核心知识点整理大全1-笔记

在本章中&#xff0c;你将运行自己的第一个程序——hello_ world.py。为 此&#xff0c;你首先需要检查自己的计算机是否安装了Python&#xff1b;如果没有安装&#xff0c; 你需要安装它。你还要安装一个文本编辑器&#xff0c;用于编写和运行Python 程序。你输入Python代码时…

【GD32307E-START】04 使用TinyMaix进行手写数字识别

【GD32307E-START】04 使用TinyMaix进行手写数字识别 参考博客 【GD32F427开发板试用】使用TinyMaix进行手写数字识别 https://blog.csdn.net/weixin_47569031/article/details/129009839 软硬件平台 GD32F307E-START Board开发板GCC Makefile TinyMaix简介 TinyMaix是国…

从马帮到金蝶云星空通过接口配置打通数据

从马帮到金蝶云星空通过接口配置打通数据 接入系统&#xff1a;马帮 上海马帮科技有限公司&#xff0c;是一家专注于提供全流程跨境电商ERP管理软件解决方案的企业。聚焦服务于各阶段、各领域的跨境电商从业者&#xff0c;旗下包含专业版ERP、亚马逊专用版ERP、东南亚海外版ERP…

SimCSE论文阅读

正负样本对构建原理正样本pair&#xff1a;one sentence two different embeddings as “positive pairs”. (通过dropout 作为噪声)负样本pair&#xff1a;Then we take other sentences in the same mini-batch as “negatives”任务&#xff1a; the model predicts the pos…

cup型号的意思

CPU 在整个计算机硬件中、技术体系中都算是最最重要的东西了。在 10 月 16 号的时候&#xff0c;Intel 正式发布了第 14 代的酷睿处理器。 一、Intel 的 CPU 型号规则 无论是哪家 CPU 厂商&#xff0c;为了更好地管理自己生产的众多型号的产品&#xff0c;也为了能更好地让消…

学生使用台灯到底好不好?学生备考台灯分享

普通台灯的出现只是为了照明&#xff0c;且它的功能也就只有照明&#xff0c;像是眩光、蓝光、频闪、过亮过暗等等都是普通台灯所存在的问题&#xff0c;而这些问题也正是造成我们眼睛近视、诱发眼部疾病的罪魁祸首&#xff0c;特别是正处于发育时期的青少年们&#xff0c;抵抗…

Anaconda【我的入门困惑】

为什么需要安装Anaconda &#xff1f; 方便地安装和管理Python及其相关包&#xff1a;Anaconda提供了一个统一的管理界面&#xff0c;用户可以方便地查看和安装需要的Python版本和相关包。同时&#xff0c;它还提供了一个虚拟环境&#xff0c;可以帮助用户使不同的项目隔离开来…

继续画图带你学习TCP 其他 7 大特性

四、滑动窗口机制 五、流量控制 六、拥塞控制 (安全机制) 七、延迟应答 (效率机制) 八、捎带应答 (效率机制) 九、粘包问题 十、保活机制 TCP总结 四、滑动窗口机制 滑动窗口机制&#xff0c;是在可靠性的前提下&#xff0c;进一步地提高传输效率 认识滑动窗口 一发一收…

LLM-Intro to Large Language Models

LLM some LLM’s model and weight are not opened to user what is? Llama 270b model 2 files parameters file parameter or weight of neural networkparameter – 2bytes, float number code run parameters(inference) c or python, etcfor c, 500 lines code withou…

Matlab和python详解数独谜题问题

&#x1f517; 运行环境&#xff1a;Matlab、Python &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 &#x1f510;#### 防伪水印——左手の明天 ####&#x1f510; &#x1f4…

爱德华|书客|飞利浦护眼台灯好不好用?多方位测评对比爆料!

说到护眼台灯相信大家都不陌生&#xff0c;很多办公族、学生党都会备上一台用于工作、学习。因为长时间的工作或者学习&#xff0c;会明显的感觉到眼睛疲劳和不适。而护眼台灯可以很好的解决这个难题&#xff0c;因为护眼台灯是经过科学的设计和研发的&#xff0c;护眼台灯可以…

苹果录屏功能在哪?提升你的使用体验

屏幕录制已成为人们日常生活中不可或缺的一部分&#xff0c;苹果设备内置了强大的录屏功能&#xff0c;允许用户捕捉屏幕上的活动&#xff0c;可是很多用户不知道苹果录屏功能在哪。本文将详细介绍如何使用苹果内置录屏功能&#xff0c;为用户提供全面的录屏解决方案。 苹果录屏…

ESP32 LVGL Gui-Guider的移植

使用参考&#xff1a; ESP32系列之LVGL&#xff08;三&#xff09;&#xff1a;Gui-Guider的使用_esp32 lvgl-CSDN博客 1、拷贝文件&#xff1a; 按照上面的文章&#xff0c;使用Gui-Guider软件生成C代码之后&#xff0c;custom和generated是我们要使用到的文件&#xff0c;…

36、红外遥控(外部中断)

红外遥控简介 红外遥控是利用红外光进行通信的设备&#xff0c;由红外LED将调制后的信号发出&#xff0c;由专用的红外接收头进行解调输出 通信方式&#xff1a;单工&#xff0c;异步 红外LED波长&#xff1a;940nm 通信协议标准&#xff1a;NEC标准 硬件电路 基本发送与接收…

海云安参与制定《信息安全技术 移动互联网应用程序(App)软件开发工具包(SDK)安全要求》标准正式发布

近日&#xff0c;由TC260&#xff08;全国信息安全标准化技术委员会&#xff09;归口 &#xff0c;主管部门为国家标准化管理委员会&#xff0c;深圳海云安网络安全技术有限公司&#xff08;以下简称“海云安”&#xff09;等多家相关企事业单位共同参与编制的GB/T 43435-2023《…