V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OldCarMan
V2EX  ›  Java

关于 non-blocking 数据库 Connector 大家是怎么看待的?

  •  
  •   OldCarMan · 2023-02-17 17:45:56 +08:00 · 2527 次点击
    这是一个创建于 627 天前的主题,其中的信息可能已经有所发展或是发生改变。

    rt

    • 最近浏览到一些 IO 多路复用的文章时,有人指出现有高并发场景很多时候瓶颈在于 Connector (比如 JDBC ),这点个人也赞同,毕竟高并发时,对于 IO 密集型的服务,需要进行大量的磁盘 IO 请求。
    • 但假如确实是这样,个人好奇为啥像 mysql 这样的数据库,为啥到现在还采用连接池的方式来实现连接管理而不是 NIO ,这点跟我上面的看法又有点矛盾,所以请问一下大家是怎么看待的?
    • 最后大家觉得 non-blocking reactive connector 的必要性,另外现在有没有相对成熟的解决方案了?
    25 条回复    2023-02-19 13:54:15 +08:00
    liprais
        1
    liprais  
       2023-02-17 17:47:24 +08:00
    "有人指出现有高并发场景很多时候瓶颈在于 Connector (比如 JDBC )"
    典型的外行观点
    就算数据库能接受 c10k 的链接,他也处理不过来这么多啊
    OldCarMan
        2
    OldCarMan  
    OP
       2023-02-17 18:04:05 +08:00
    @liprais 哈哈,观点确实是来自别人的,只不过我觉得他说的有道理而已,但跟很多事情一样,自己觉得对的,不一定是正确的,所以才发贴问大家看法‘。另外个人觉得 non-blocking connector 想解决的是一个应用层的数据库连接吞吐量和伸缩性的问题,而不是一个数据库的消费速度问题,数据库的消费能力决定因素应该是其本身而不在于客户端连接工具上;跟比如 spring webflux 一样,相比 spring mvc 提高了请求吞吐量。
    @liprais
    oxromantic
        3
    oxromantic  
       2023-02-17 18:09:32 +08:00
    数据库使用场景一般在内网,尤其绝大部分都是多线程模型下,nio 带来的优势不明显

    你应该是想问 mysql 的 java connector 为什么没有 nio 的实现吧,这个和 db server 是否是无阻塞模型也毫无关系,即使 java client 支持了,也会提高使用者的门槛,毕竟绝大多数使用 connector 环境都没有 nio 模型

    补充一点,印象中 mariadb 5.x 就有 client nio 的实现
    akira
        4
    akira  
       2023-02-17 18:16:08 +08:00
    高并发的瓶颈点辣么多。。这个应该是排位前十都进不去的点把
    vgbw
        5
    vgbw  
       2023-02-17 18:46:52 +08:00
    最近有接手一个 reactive 的项目,前期上手写起来有点难度,而且还要内部的库都使用 reactive 的才能有性能提升.个人感觉 reactive 很难推广开,还不如等 loomGA 了更靠谱一些.
    OldCarMan
        6
    OldCarMan  
    OP
       2023-02-17 18:55:06 +08:00
    @oxromantic 对,确实没关系,这里说的是数据库客户端 connector (就像 JDBC );虽然是内网,但是数据库大部分操作是 IO 密集型的,即使少了网络方面的开销,但个人觉得一次数据库操作的主要瓶颈还是在于磁盘 IO 吧;确实很多 connector 不支持 nio 模型,但不支持是因为没必要吗? mariadb 确实有版本支持了。

    @akira 可能不同的应用,不同的需求面临的高并发问题都不一样吧,不过个人觉得数据库瓶颈是很多高并发场景的瓶颈,而假如存在一个自带 NIO 的客户端去处理来自调用者的请求,还是能有效增加数据库操作吞吐量的。

    PS:谢谢大家回复。
    OldCarMan
        7
    OldCarMan  
    OP
       2023-02-17 19:06:56 +08:00
    @vgbw 嗯嗯,不过个人觉得 Reactor 在有些接入层的应用是一个趋势,比如 spring webflux ,spring gateway 之类的。
    hhjswf
        8
    hhjswf  
       2023-02-17 20:16:00 +08:00 via Android
    数据库瓶颈肯定是在磁盘 io 啦。你弄一套 redis 的网络 io 模型来也是慢。qps 小负载也小,这情况才是连接数的问题
    billlee
        9
    billlee  
       2023-02-17 20:32:47 +08:00
    机械硬盘是 blocking 的,磁盘 I/O 的系统调用也是 blocking 的,网络链接并发再高最后还是要阻塞在等待磁盘 I/O 上,在数据库进程里等待还不如在应用进程等待呢。等 NVMe 和 io_uring 普及吧
    zeni123
        10
    zeni123  
       2023-02-17 20:52:02 +08:00
    不需要了,virtual thread 出来后就不需要了。都变成了 non blocking.
    dreamlike
        11
    dreamlike  
       2023-02-17 23:11:52 +08:00 via Android
    从响应式时间来看 没有帮助
    但是由于我们的服务请求类型往往是比较混合的,如果用过 reactive 的 connector 可以帮助我们及时释放服务线程去处理其他请求 即下游的访问瓶颈不会限制我的整体服务性能
    no block connector 最大的问题在于要提供 eventloop or 它自己维护 eventloop 同时接口也是异步的 要想利用好这种异步优势就得从头到尾改代码 我觉得不好
    所以说我非常推崇有栈协程包揽整个 io 的 runtime 相当于提供了一个全局共享的 eventloop 来做这些事情,让出调度全交给 runtime 就好,同步的代码才是最好写的
    ychost
        12
    ychost  
       2023-02-17 23:43:21 +08:00
    因为 Oracle 认为现有的 NIO 写法太麻烦了(停止了异步 JDBC 来开发),应该由 JVM 来实现线程挂起 /恢复( project loom ),所以就没有 JDBC NIO 版本,但是 Spring 倒是在推 r2dbc
    yazinnnn
        13
    yazinnnn  
       2023-02-17 23:57:35 +08:00
    咱还是聊聊结构化并发吧
    liuxu
        14
    liuxu  
       2023-02-18 00:55:42 +08:00
    可以看看 rust 的 tokio_postgres

    https://docs.rs/tokio-postgres/latest/tokio_postgres/


    我之前用 1C1G 的服务器,弄了个 CRUD 的 demo ,读写都能达到 10k qps

    https://www.liuquanhao.com/posts/%E4%BB%8A%E5%A4%A9%E6%88%91%E7%94%A81C1G%E7%9A%84VPS%E5%AE%9E%E7%8E%B0%E4%BA%86CRUD-10K-QPS/
    OldCarMan
        15
    OldCarMan  
    OP
       2023-02-18 01:09:56 +08:00
    @hhjswf @billlee 谢谢回复,你们可能把主要问题集中在 I/O 延迟这方面了,当然 I/O 是延迟的主要原因,但根据科特尔定律高并发下一个程序的理想并发量(比如 VU ),除了跟响应时间(包括 I/O 延迟)有关,还跟吞吐量有关,两者都是影响理想并发量的指标,可能我表达不好,个人觉得 nio connector 的主要目的是为了解决后者的问题。
    OldCarMan
        16
    OldCarMan  
    OP
       2023-02-18 01:25:03 +08:00
    @zeni123 哈哈,java 版“协程”是吧,确实 non-blocking 了,但这也意味着相关的框架和库也得跟进
    @dreamlike 是的,RT 确实不是重点,正如我了解的一样,真正的异步非阻塞最好得是整套代码(比如 java web 项目从控制层到数据访问层)都使用 reactive 编程
    @ychost 是的,你说的 r2dbc 确实我发这个帖子的原因,https://r2dbc.io/ 这好像是他们搞的一系列 reactive 库,感谢你告知我了 oracle 那段。
    @yazinnnn 哈哈,有请课代表“协程”出场?
    @liuxu 谢谢分享
    PS:谢谢大家抽空回复
    NXzCH8fP20468ML5
        17
    NXzCH8fP20468ML5  
       2023-02-18 06:30:18 +08:00
    1. 应用侧有没有必要用 non-blocking 的 Connector 到数据库?
    我的回答是有必要。目的是不要让数据库连接时占用珍贵的线程资源。
    上面说没必要的,我怀疑是只写 java 的程序员。

    2. 数据库有没有必要用 non-blocking ?
    数据库存储引擎都是 callback+绑核,non-blocking 了就是写起来蛋疼。
    数据库执行引擎瓶颈往往在 cpu 和 io 上,各种大锁一挂,即使用 non-blocking 接受请求也不会快到那里去。
    因此接收请求是不是 non-blcking ,无关紧要,你看 tidb 不也是 go 得飞起。

    3.non-blocking 有没有相对成熟的解决方案?
    等 Virtual Threads

    oracle jdbc 是支持最新 Virtual Threads ,不知道 mysql jdbc 什么时候支持了。
    https://medium.com/oracledevs/introduction-to-oracle-jdbc-21c-driver-support-for-virtual-threads-189b918c56f4
    litchinn
        18
    litchinn  
       2023-02-18 08:35:58 +08:00
    对数据库不是很了解,想这里问问:
    r2dbc 和这里讲的 non-blocking 有关系吗?
    non-blocking reactive connector 与数据库事务会有关联吗,或者说会影响事务吗?
    如果是应对高并发的问题,分布式数据库如 TiDB 这种会是更好的, 成本更低的解决方案吗?当然它们应该是两个不同维度的东西
    OldCarMan
        19
    OldCarMan  
    OP
       2023-02-18 12:44:43 +08:00
    @xxfye 嗯,确实,不过除了解决连接池占用线程资源外,我认为顺带还有一个提高吞吐量的衍生功能;
    你说的 non-blocking 数据库这点即使有必要,但实施起来更加艰难,因为数据库厂商太多了,各家有各家的利益,当然开源的可能阻力稍微少点;
    虚拟线程确实是个好东西,不过如果应用层语言是 java,生产环境中应用短时间可行性可能比较低,毕竟 jdk19 才支持虚拟线程,当然如果是其他语言,比如 go 的协程,可能好点,历史包袱没那么大。
    OldCarMan
        20
    OldCarMan  
    OP
       2023-02-18 12:57:45 +08:00
    @litchinn 如果你想了解 r2dbc 可以看看我上面#16 楼发的那个链接,r2dbc 是 fully-reactive non-blocking 的
    r2dbc 跟 jdbc 一样,只是一个数据库的客户端。
    如果想了解 classic jdbc ,r2dbc 跟 virtual thread 的区别,你可以看看这位大佬说的,我觉得讲的很好。https://www.slideshare.net/juarezjunior/revolutionize-java-db-app-dev-with-reactive-streams-and-virtual-threadspdf
    两者确实是不同维度的东西,个人觉得现有很多企业的生成环境业务都是使用传统的数据库( mysql,postgresql 等),而 non-blocking connector 是为了解决这些传统方案的,另外不是每个企业都是随便就能用上分布式数据库的
    echoless
        21
    echoless  
       2023-02-18 16:03:52 +08:00
    python 是有的 https://github.com/MagicStack/asyncpg

    主要是 async io 传染, 写起来更麻烦, python 语言层级支持 async, 用的人还不多.

    大部分应用不需要 async 带来的好处, 当然不愿意付出代价.
    dreamlike
        22
    dreamlike  
       2023-02-18 17:31:54 +08:00 via Android
    我上面的评论有些跳跃了
    https://juejin.cn/post/7181664513559625788
    其实可以扩大一些说 client 是否有必要都是 non blocking 的 我之前写过一篇文章来表述自己的观点
    我觉得 api 是没必要的 但是底层实现是有必要的 这种应该交由 runtime 全做了
    OldCarMan
        23
    OldCarMan  
    OP
       2023-02-18 23:51:35 +08:00
    @wuhaoecho 嗯嗯,不过个人感觉未来 non-blocking 数据库客户端将会是趋势,现在麻烦主要是,语言生态没有整体发力,就如 java ,最近版本才支持 virtual Thread,市面上又缺乏一整套从控制层到数据访问层的成熟框架,所以推广起来稍微麻烦,不过随着 reactive coding 的发展,未来大概率各个环节都趋向于 reactive 的风格。
    @dreamlike 谢谢补充,话说你这里提的 runtime 是指 java 运行时吗?意思是通过重返 runtime 环境,使用 mounting /unmounted (虚拟线程) 来控制程序 blocking 的方式吗?
    dreamlike
        24
    dreamlike  
       2023-02-19 03:18:35 +08:00 via Android
    @OldCarMan 可以理解为语言的 runtime 的一部分
    我用 rust 举个例子,所谓的协程 runtime 就是指的从 io 轮询器(eventloop),到基于这些 eventloop 做的 io api(async read) 一整套包揽,提供一组同步风格但是底层为异步的 io 操作
    OldCarMan
        25
    OldCarMan  
    OP
       2023-02-19 13:54:15 +08:00   ❤️ 1
    @dreamlike 你意思是语言层面要支持异步 io ,对吧?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3443 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:42 · PVG 19:42 · LAX 03:42 · JFK 06:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.