Doris数据库连接数限制配置与优化方案

16 次阅读

连接数限制的作用

Apache Doris 采用 FE(Frontend)提供 MySQL 协议服务,常见客户端、JDBC、Python、Go 以及可视化工具都可以通过 FE 的 query_port 建立连接,默认端口通常为 9030。

当应用访问量增加后,数据库连接数很容易成为新的瓶颈。连接数设置过低,应用可能出现连接被拒绝、连接池获取超时等问题;设置过高,又会增加 FE 的内存、线程以及网络资源压力。

Doris 的连接数控制并不是单一参数,而是包含单个用户连接数限制和单个 FE 节点总连接数限制两个层次。

其中比较关键的配置包括:

  • max_user_connections:限制单个 Doris 用户可以建立的最大连接数。

  • qe_max_connection:限制单个 FE 的最大连接数。

  • mysql_service_io_threads_num:影响 MySQL 服务的 I/O 处理能力。

  • max_mysql_service_task_threads_num:限制 MySQL 服务处理任务的线程资源。

  • mysql_nio_backlog_num:控制 MySQL NIO 服务的连接等待队列大小。

当前 Doris 官方文档中,max_user_connections 默认值为 100,而 qe_max_connection 默认值为 1024。

因此,排查 Doris“连接数不够”问题时,不能只修改一个参数。

一、Doris连接数限制的两个核心层级

1. 单用户连接数:max_user_connections

max_user_connections 是用户级别的连接数限制,只针对指定 Doris 用户生效。

例如:

SHOW PROPERTY FOR 'root' LIKE '%max_user_connections%';

如果需要将 root 用户最大连接数调整为 500,可以执行:

SET PROPERTY FOR 'root' 'max_user_connections' = '500';

Doris 官方文档明确说明,User Property 只对指定用户生效,不会影响其他用户。

也就是说,如果系统中存在:

app_user
etl_user
report_user
admin_user

可以分别设置不同的连接数。

例如:

SET PROPERTY FOR 'app_user'
'max_user_connections' = '300';

SET PROPERTY FOR 'etl_user'
'max_user_connections' = '100';

SET PROPERTY FOR 'report_user'
'max_user_connections' = '200';

这种方式比简单地提高全局连接上限更加容易控制资源。

2. FE总连接数:qe_max_connection

qe_max_connection 是 FE 级别的连接数限制,用于控制单个 FE 节点能够承载的最大连接数量。

官方配置文档显示,该参数默认值为:

qe_max_connection=1024

即每个 FE 的最大连接数默认是 1024。

例如一个 FE 上存在多个用户:

app_user       300
etl_user       100
report_user    200
admin_user      50

即使各用户的连接数限制加起来超过 1024,实际能够同时建立的连接仍然会受到 FE 总连接数上限约束。

因此可以简单理解为:

单用户限制
    ↓
max_user_connections

       +
       
FE节点总限制
    ↓
qe_max_connection

实际可使用的连接资源需要同时满足这两个层级。

二、如何查看当前Doris连接数

调整参数之前,建议先查看实际连接情况,而不是直接提高限制。

可以通过 Doris 的系统表或连接信息进行分析。

首先查看当前用户属性:

SHOW PROPERTY FOR 'root' LIKE '%max_user_connections%';

也可以查看用户信息:

SELECT
    User,
    Host,
    max_user_connections
FROM mysql.user;

Doris 的 mysql.user 表中包含 max_user_connections 字段,用于表示允许的最大连接数量。

如果发现某个应用用户长期接近连接上限,就需要继续判断这些连接究竟来自哪里。

重点检查:

应用服务器数量
↓
每台服务器连接池大小
↓
连接是否长期保持
↓
连接是否及时释放
↓
是否存在大量空闲连接

很多所谓的“Doris连接数不足”,真正原因并不是 Doris 的默认限制太小,而是应用连接池配置不合理。

三、修改qe_max_connection的方法

qe_max_connection 属于 FE 配置项。

Doris 支持通过 fe.conf 进行静态配置,也支持部分 FE 配置项通过 MySQL 协议动态修改。官方文档说明,可以通过 SHOW FRONTEND CONFIG 查看配置,并通过 ADMIN SET FRONTEND CONFIG 修改支持动态调整的参数。

首先查看当前配置:

SHOW FRONTEND CONFIG;

也可以使用:

SHOW FRONTEND CONFIG LIKE 'qe_max_connection';

如果当前版本允许动态修改,可以使用:

ADMIN SET FRONTEND CONFIG (
    "qe_max_connection" = "2048"
);

是否支持动态修改,应以当前 Doris 版本中 SHOW FRONTEND CONFIG 返回的 IsMutable 属性为准。

如果采用静态配置,则在 FE 的 fe.conf 中增加:

qe_max_connection=2048

然后按照实际部署方式重启对应 FE。

需要注意的是,不能简单认为“连接数越大越好”。提高 qe_max_connection 后,FE 需要面对更多并发连接,连接本身也会占用一定的系统资源。如果应用端存在连接泄漏,单纯扩大连接上限反而可能把问题进一步放大。

四、max_user_connections如何合理设置

对于应用系统,更建议采用“按业务用户分配连接额度”的方式。

例如:

业务应用:300
BI报表:150
ETL任务:100
管理账号:50

对应配置:

SET PROPERTY FOR 'app_user'
'max_user_connections' = '300';

SET PROPERTY FOR 'bi_user'
'max_user_connections' = '150';

SET PROPERTY FOR 'etl_user'
'max_user_connections' = '100';

这样做的好处是,即使某个业务突然产生大量连接,也不会无限制地占用 FE 的全部连接资源。

特别是生产环境中,不建议所有应用都使用同一个 Doris 用户。

例如下面这种方式风险较高:

所有Java服务
       ↓
     root
       ↓
Doris

更合理的方式是:

订单服务 ──→ order_user
报表服务 ──→ report_user
ETL服务 ──→ etl_user
数据分析 ──→ analyst_user

然后针对不同用户设置独立连接上限。

五、连接数配置与连接池需要同时优化

实际生产环境中,Doris连接数问题经常发生在应用连接池,而不是数据库本身。

例如一个Java服务配置:

maximumPoolSize = 100
minimumIdle = 20

如果部署了 10 台应用服务器,理论上最大连接数量可能达到:

100 × 10 = 1000

如果还有另外两个服务:

报表服务:200
ETL服务:100

那么整体连接需求可能达到:

1000 + 200 + 100 = 1300

此时即使单个应用没有异常,FE 的默认 qe_max_connection=1024 也可能成为限制因素。

所以连接数规划应该从应用端开始计算。

可以使用:

总连接需求
≈
应用实例数量 × 单实例最大连接池大小
+
其他业务连接

然后再结合 Doris FE 节点数量和业务峰值进行容量规划。

六、不要把连接池最大连接数直接设置得过大

很多开发人员遇到:

Could not get connection
Connection timeout
Too many connections

第一反应是把连接池从 100 调到 500,甚至 1000。

这种处理方式并不一定正确。

假设:

应用实例:20台
单实例最大连接:500

理论连接上限就是:

20 × 500 = 10000

如果 Doris FE 只有少量节点,这样的连接规模可能明显高于实际业务查询需求。

更合理的方式是根据实际并发查询数配置连接池,而不是根据“希望系统支持多少用户”直接配置连接数。

一个Web系统有10000个在线用户,并不意味着需要10000个数据库连接。

例如:

在线用户:10000
实际同时发起查询:100
数据库连接池:150

这在很多业务系统中完全可以成立。

七、区分“连接数”和“查询并发数”

连接数与查询并发数不是同一个概念。

一个数据库连接建立以后,可以保持空闲状态。此时:

连接存在
≠
正在执行查询

因此,如果监控发现连接数很高,并不意味着同时运行的SQL数量同样很高。

例如:

当前连接:800
执行查询:50
空闲连接:750

此时真正应该解决的可能是连接池长期保留连接过多,而不是继续扩大 Doris 的连接上限。

排查时建议同时关注:

连接总数
活跃连接数
空闲连接数
查询执行数
查询平均耗时
连接建立速率
连接关闭速率

只有把这些指标结合起来,才能判断究竟是数据库连接容量不足,还是应用连接管理存在问题。

八、连接数过高时重点排查连接泄漏

如果应用不断创建连接,却没有及时关闭,就会出现连接数持续增长的问题。

Java代码中应确保连接、Statement和ResultSet得到正确释放,例如:

try (Connection conn = dataSource.getConnection();
     PreparedStatement ps = conn.prepareStatement(sql);
     ResultSet rs = ps.executeQuery()) {

    while (rs.next()) {
        // 处理结果
    }
}

使用连接池时,close() 通常意味着将连接归还连接池,而不是直接关闭底层数据库连接。

如果连接没有正确归还,连接池中的可用连接会越来越少,最终表现为:

获取连接超时

而数据库侧可能表现为:

连接数持续增长

所以出现连接数异常时,应该同时查看应用日志和 Doris FE 日志。

九、多FE环境下要注意连接分布

生产环境通常不会只部署一个 FE。

假设集群有:

FE1
FE2
FE3

如果应用直接连接固定的 FE1,那么即使 FE2、FE3 还有大量空闲资源,FE1 仍可能先达到 qe_max_connection。

因此,多 FE 环境应该考虑连接分发。

常见方式包括:

应用
 ↓
负载均衡
 ↓
FE1
FE2
FE3

或者通过应用侧的连接配置实现多个 FE 地址的合理分配。

这样可以避免:

FE1:1000连接
FE2:100连接
FE3:80连接

这种明显不均衡的情况。

Doris 的 MySQL 协议服务由 FE 提供,默认端口为 9030,因此应用侧的连接入口配置与 FE 节点分布需要一起考虑。

十、mysql_service相关参数优化

除了 qe_max_connection,FE 还提供多个与 MySQL 服务相关的参数。

mysql_service_io_threads_num

该参数用于 MySQL 服务的 I/O 线程配置,官方文档当前默认值为 4。

如果系统存在大量并发连接,可以结合实际负载观察 I/O 处理情况。

但不要在没有监控数据的情况下盲目提高线程数。

max_mysql_service_task_threads_num

该参数用于限制 MySQL 服务处理任务的最大线程数量,当前官方配置文档默认值为 4096。

对于普通业务场景,通常没有必要为了增加连接数而同步修改该参数。

mysql_nio_backlog_num

该参数用于 MySQL NIO Server 的 backlog 配置,官方文档显示默认值为 1024。

如果扩大 mysql_nio_backlog_num,还需要同步关注 Linux:

/proc/sys/net/core/somaxconn

因为 Doris 官方文档明确提示,扩大 backlog 时应同时扩大 Linux somaxconn。

例如:

sysctl net.core.somaxconn

查看当前值。

需要注意,backlog 主要影响等待建立连接的队列,并不等于可以长期保持的数据库连接数量。

十一、Arrow Flight SQL场景需要特别关注连接数

如果使用 Arrow Flight SQL,需要特别注意它与普通 JDBC 查询连接在连接生命周期方面存在差异。

Doris 官方文档指出,Arrow Flight SQL 使用的连接具有长连接特征,连接建立后不会因为单次查询结束就立即断开;如果客户端没有及时发送 close(),连接、Session 等资源可能长期保留。

这意味着某些场景下:

JDBC:
连接 → 查询 → 释放

Arrow Flight SQL:
连接 → 多次使用 → 长时间保持

因此,如果迁移到 Arrow Flight SQL 后突然出现连接数量增加,应检查客户端连接关闭逻辑,而不是直接认为 Doris 的默认连接数配置存在问题。

官方文档还特别说明,在相关版本场景下,Arrow Flight 与 MySQL/JDBC 连接共用 FE 的连接数限制,其中包括 qe_max_connection 和用户级 max_user_connections。

十二、推荐的生产环境配置思路

可以采用以下思路规划 Doris 连接数:

第一步:统计应用实例数量
        ↓
第二步:统计每个实例连接池大小
        ↓
第三步:计算理论最大连接数
        ↓
第四步:统计实际峰值连接数
        ↓
第五步:区分活跃连接与空闲连接
        ↓
第六步:设置各业务用户 max_user_connections
        ↓
第七步:根据FE节点容量设置 qe_max_connection
        ↓
第八步:监控并逐步调整

例如某生产集群:

FE节点:3
应用服务:10台
单应用最大连接:50
BI服务:100
ETL服务:50

理论连接规模约为:

10 × 50 + 100 + 50
= 650

这时可以根据实际峰值、连接分布和增长空间评估 FE 的总连接容量,而不是简单按照服务器数量扩大参数。

十三、连接数优化的几个常见误区

误区一:连接数越大越好

错误。

连接数增加意味着 FE 需要管理更多连接状态,同时应用端也会消耗更多资源。

应该根据实际业务峰值设置,而不是无限提高。

误区二:只修改max_user_connections

如果用户限制已经提高到 5000,但:

qe_max_connection=1024

那么 FE 总连接能力仍然受到整体上限约束。

因此需要同时关注用户级和 FE 级配置。

误区三:只修改Doris,不调整应用连接池

如果连接池本身配置过大,即使 Doris 可以接受更多连接,也可能造成大量空闲连接。

优化应该覆盖:

Doris FE
+
应用连接池
+
负载均衡
+
客户端连接生命周期
+
操作系统网络参数

误区四:把连接数当成查询并发数

大量空闲连接并不代表大量SQL正在执行。

必须结合活跃查询、SQL耗时和资源使用情况分析。

误区五:修改配置后不做验证

修改参数以后,应重新检查:

SHOW PROPERTY FOR 'root' LIKE '%max_user_connections%';

以及:

SHOW FRONTEND CONFIG LIKE 'qe_max_connection';

同时观察连接数和查询负载是否发生预期变化。

十四、Doris连接数问题排查清单

遇到“Doris连接数达到上限”或者应用连接超时,可以按照下面顺序排查:

第一步:确认报错来源

判断是:

Doris拒绝连接

还是:

应用连接池获取连接超时

两者处理方向不同。

第二步:检查用户连接限制

SHOW PROPERTY FOR 'app_user'
LIKE '%max_user_connections%';

第三步:检查FE总连接限制

SHOW FRONTEND CONFIG LIKE 'qe_max_connection';

第四步:统计各应用实例连接池

重点检查:

maximumPoolSize
minimumIdle
connectionTimeout
idleTimeout
maxLifetime

具体参数名称根据连接池实现不同而有所区别。

第五步:检查连接是否释放

重点排查:

代码异常导致连接未归还
事务长时间未提交
ResultSet未关闭
连接池配置不合理
客户端长连接未主动关闭

第六步:检查FE节点是否负载均衡

确认是否存在某个 FE 连接明显高于其他 FE 的情况。

第七步:再决定是否提高限制

只有确认业务确实需要更多并发连接后,才应该调整:

max_user_connections
qe_max_connection

十五、推荐的Doris连接数优化原则

Doris连接数优化并不是简单修改一个参数,而是一个完整的容量管理问题。

比较合理的策略可以概括为:

控制用户
    ↓
max_user_connections

控制FE
    ↓
qe_max_connection

控制应用
    ↓
连接池大小

控制生命周期
    ↓
及时释放连接

控制分布
    ↓
多个FE合理负载

持续监控
    ↓