基于源码分析 HikariCP 常见参数的具体含义

HikariCP 是目前风头最劲的 JDBC 连接池,号称性能最佳,SpringBoot 2.0 也将 HikariCP 作为默认的数据库连接池。

要想用好 HikariCP,理解常见参数的具体含义至关重要。但是对于某些参数,尽管官方文档给出了详细解释,很多开发、DBA 读完后还是会感到困惑。

因此,本文将从源码角度对 HikariCP 中的一些常见参数进行分析,希望能帮助大家更加清晰地理解这些参数的具体含义。

本文将分析的参数包括:

  • maximumPoolSize
  • minimumIdle
  • connectionTimeout
  • idleTimeout 及空闲连接的清理逻辑。
  • maxLifetime
  • keepaliveTime
  • connectionTestQuery 及连接有效性检测的实现逻辑。
  • leakDetectionThreshold
  • 什么时候会检测连接的有效性?

maximumPoolSize

连接池可以创建的最大连接数,包括空闲和活动连接。默认值为 10。

if (maxPoolSize < 1) {maxPoolSize = DEFAULT_POOL_SIZE;
}

如果未显式设置 maxPoolSize,则默认为 -1,此时连接池会使用默认的最大连接数 DEFAULT_POOL_SIZE(10)。

当连接池达到该限制且没有可用的空闲连接时,对新连接的请求(通过 getConnection())将会阻塞,最多等待 connectionTimeout 毫秒,然后超时失败。

public Connection getConnection() throws SQLException
{return getConnection(connectionTimeout);
}public Connection getConnection(final long hardTimeout) throws SQLException{suspendResumeLock.acquire();final var startTime = currentTime();try {var timeout = hardTimeout;do {var poolEntry = connectionBag.borrow(timeout, MILLISECONDS);...}

minimumIdle

最小空闲连接数。

if (minIdle < 0 || minIdle > maxPoolSize) {minIdle = maxPoolSize;
}

如果未显式设置 minimumIdle,则默认为 -1,此时会取 maximumPoolSize 的值。官方建议不要设置这个参数,让 HikariCP 作为一个固定大小的连接池进行管理。

如果连接池中的空闲连接数低于 minimumIdle,且连接池中的总连接数小于 maximumPoolSize(最大连接数),HikariCP 会调用fillPool方法补充连接。

private synchronized void fillPool(final boolean isAfterAdd)
{  // 获取当前空闲连接数final var idle = getIdleConnections();// 检查是否需要创建新连接,创建新连接的条件是总连接数小于 maximumPoolSize 且空闲连接数小于 minimumIdle。final var shouldAdd = getTotalConnections() < config.getMaximumPoolSize() && idle < config.getMinimumIdle();if (shouldAdd) {// 计算需要创建的连接数final var countToAdd = config.getMinimumIdle() - idle;for (int i = 0; i < countToAdd; i++)addConnectionExecutor.submit(isAfterAdd ? postFillPoolEntryCreator : poolEntryCreator);}else if (isAfterAdd) {logger.debug("{} - Fill pool skipped, pool has sufficient level or currently being filled.", poolName);}
}

fillPool会在三种场景下调用:

  1. 销毁连接时。
  2. HouseKeeper 的周期性任务中。
  3. 恢复暂停的连接池时(这种场景不常见,可忽略)。

connectionTimeout

获取连接时的最大等待时间,单位为毫秒,默认值为 30000(30秒),最小允许值是 250。

如果 connectionTimeout 设置为 0,则它会取 Java int 类型的最大值,即 2147483647,约 24.85 天。

public void setConnectionTimeout(long connectionTimeoutMs)
{if (connectionTimeoutMs == 0) {this.connectionTimeout = Integer.MAX_VALUE;}else if (connectionTimeoutMs < SOFT_TIMEOUT_FLOOR) {throw new IllegalArgumentException("connectionTimeout cannot be less than " + SOFT_TIMEOUT_FLOOR + "ms");}else {this.connectionTimeout = connectionTimeoutMs;}
}

idleTimeout

空闲连接的超时时长,单位为毫秒。超过指定时长的连接将被销毁掉。默认值为 600000(10分钟),最小允许值是 10000(10秒)。

注意,如果 idleTimeout 的设置不合理,连接池会基于其它参数的值来设置 idleTimeout,具体逻辑如下:

// 如果 idleTimeout 与 maxLifetime 的值过于接近,且 maxLifetime 大于 0,连接池将禁用 idleTimeout,避免设置的超时时间影响连接生命周期。
if (idleTimeout + SECONDS.toMillis(1) > maxLifetime && maxLifetime > 0 && minIdle < maxPoolSize) {LOGGER.warn("{} - idleTimeout is close to or more than maxLifetime, disabling it.", poolName);idleTimeout = 0;
} // 如果 idleTimeout 小于 10 秒,且 minIdle 小于最大连接数 maxPoolSize,连接池会将 idleTimeout 设置为默认值 IDLE_TIMEOUT(10分钟),避免空闲连接存活时间过短影响池的正常使用。
else if (idleTimeout != 0 && idleTimeout < SECONDS.toMillis(10) && minIdle < maxPoolSize) {LOGGER.warn("{} - idleTimeout is less than 10000ms, setting to default {}ms.", poolName, IDLE_TIMEOUT);idleTimeout = IDLE_TIMEOUT;
} // 如果连接池已配置为固定大小(即 minIdle == maxPoolSize),并且 idleTimeout 被显式设置,连接池会发出警告,说明该设置无效。
else  if (idleTimeout != IDLE_TIMEOUT && idleTimeout != 0 && minIdle == maxPoolSize) {LOGGER.warn("{} - idleTimeout has been set but has no effect because the pool is operating as a fixed size pool.", poolName);
}

连接池中的空闲连接是指当前没有被使用、处于空闲状态的连接。空闲连接可以随时被借用(即从连接池中获取)来进行数据库操作。

注意,空闲连接在 MySQL 中的状态是Sleep,但不是所有Sleep状态的连接都是空闲连接。

空闲连接的清理逻辑

空闲连接由 HouseKeeper 定期清理。

HouseKeeper 是 HikariCP 中的一个定时任务,负责清理空闲连接、调整连接池大小等。

HouseKeeper 会在启动后 100 毫秒执行第一次任务,然后每隔 housekeepingPeriodMs 毫秒执行一次。

housekeepingPeriodMs 的值由com.zaxxer.hikari.housekeeping.periodMs决定,默认是 30000 毫秒(30秒)。

private final long housekeepingPeriodMs = Long.getLong("com.zaxxer.hikari.housekeeping.periodMs", SECONDS.toMillis(30));this.houseKeeperTask = houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(), 100L, housekeepingPeriodMs, MILLISECONDS);

下面我们看看 HouseKeeper 任务具体的实现逻辑。

private final class HouseKeeper implements Runnable{...public void run(){try {...if (idleTimeout > 0L && config.getMinimumIdle() < config.getMaximumPoolSize()) {logPoolState("Before cleanup ");// 获取连接池所有未使用的连接(STATE_NOT_IN_USE)final var notInUse = connectionBag.values(STATE_NOT_IN_USE);// 计算需要清理的连接数 maxToRemove,即当前未使用连接数减去最小空闲连接数。var maxToRemove = notInUse.size() - config.getMinimumIdle();for (PoolEntry entry : notInUse) {// 如果连接的空闲时间超过 idleTimeout,则关闭该连接。if (maxToRemove > 0 && elapsedMillis(entry.lastAccessed, now) > idleTimeout && connectionBag.reserve(entry)) {closeConnection(entry, "(connection has passed idleTimeout)");maxToRemove--;}}logPoolState("After cleanup  ");}elselogPoolState("Pool ");// 调用 fillPool(true) 以确保连接池维持最小空闲连接数。fillPool(true); // Try to maintain minimum connections}catch (Exception e) {logger.error("Unexpected exception in housekeeping task", e);}}}

可以看到,空闲连接能回收的前提是 idleTimeout 大于 0,且 minIdle 小于 maxPoolSize。

如果按照官方建议不显式设置 minIdle 的话,则 minIdle 会取 maxPoolSize 的值,此时空闲连接将不会被回收。

无论是否回收空闲连接,最后都会调用 fillPool 来填充连接池,以确保池中有足够的连接。

空闲连接的持续时长是通过elapsedMillis(entry.lastAccessed, now)计算的,其中 entry.lastAccessed 记录了连接最后一次被访问的时间。该时间戳会在以下两种场景下设置:

  1. 创建物理连接时:当一个新的连接被创建并加入连接池时,lastAccessed 会被设置为当前时间,表示连接的创建时间。
  2. 连接归还给连接池时:当连接被归还给连接池时,lastAccessed 会更新为归还时的时间。

因此,空闲连接的持续时长实际上等于当前系统时间减去连接最后一次归还给连接池的时间。

maxLifetime

连接池中连接的最大生命周期,单位为毫秒。默认值为 1800000(30分钟),最小允许值是 30000(30秒)。

if (maxLifetime != 0 && maxLifetime < SECONDS.toMillis(30)) {LOGGER.warn("{} - maxLifetime is less than 30000ms, setting to default {}ms.", poolName, MAX_LIFETIME);maxLifetime = MAX_LIFETIME;
}

如果 maxLifetime 设置为 0,则表示不限制连接的最大生命周期。

如果 maxLifetime 不等于 0 且小于 30 秒,则会输出警告日志,提示 maxLifetime 设置过短,并将 maxLifetime 设置为默认的最大生命周期 MAX_LIFETIME(即 30 分钟)。

在创建一个新的物理连接时,会为其设置一个到期执行的任务MaxLifetimeTask,该任务将在连接的生命周期到期时执行。连接的生命周期时间等于 maxLifetime 减去一个随机偏移量。

private PoolEntry createPoolEntry(){try {final var poolEntry = newPoolEntry(getTotalConnections() == 0);final var maxLifetime = config.getMaxLifetime();if (maxLifetime > 0) {// 如果 maxLifetime 大于 10000 毫秒,则生成一个最大为 maxLifetime 的 25% 的随机偏移量final var variance = maxLifetime > 10_000L ? ThreadLocalRandom.current().nextLong( maxLifetime / lifeTimeVarianceFactor ) : 0L;final var lifetime = maxLifetime - variance;poolEntry.setFutureEol(houseKeepingExecutorService.schedule(new MaxLifetimeTask(poolEntry), lifetime, MILLISECONDS));}...return poolEntry;}...return null;}

当连接的生命周期(lifetime)到期时,MaxLifetimeTask 会被触发,它会调用 softEvictConnection() 方法尝试驱逐该连接。如果驱逐成功,则会调用 addBagItem() 方法判断是否向连接池中添加新的连接。

private final class MaxLifetimeTask implements Runnable
{...public void run(){if (softEvictConnection(poolEntry, "(connection has passed maxLifetime)", false /* not owner */)) {addBagItem(connectionBag.getWaitingThreadCount());}}
}

下面我们看看softEvictConnection()的实现逻辑。

private boolean softEvictConnection(final PoolEntry poolEntry, final String reason, final boolean owner)
{// 将连接标记为驱逐状态poolEntry.markEvicted();if (owner || connectionBag.reserve(poolEntry)) {closeConnection(poolEntry, reason);return true;}return false;
}void markEvicted()
{this.evict = true;
}public boolean reserve(final T bagEntry)
{return bagEntry.compareAndSet(STATE_NOT_IN_USE, STATE_RESERVED);
}

连接首先会被标记为驱逐状态。

如果调用者是连接的拥有者,或者连接的状态可以从 STATE_NOT_IN_USE(未使用)转变为 STATE_RESERVED(已预留),则会调用 closeConnection 销毁该连接。

需要注意的是,对于正在使用的连接,仅会将其标记为驱逐状态,而不会销毁,即使其生命周期已经到期。只有当连接被归还到连接池时,才会真正执行销毁操作。

下面是连接归还到连接池时的实现细节。

void recycle(final PoolEntry poolEntry)
{metricsTracker.recordConnectionUsage(poolEntry);// 如果连接被标记为驱逐状态,则销毁连接if (poolEntry.isMarkedEvicted()) { closeConnection(poolEntry, EVICTED_CONNECTION_MESSAGE);} else {if (isRequestBoundariesEnabled) {try {poolEntry.connection.endRequest();} catch (SQLException e) {logger.warn("endRequest Failed for: {},({})", poolEntry.connection, e.getMessage());}}// 如果连接未被标记为驱逐,将执行正常的连接归还操作connectionBag.requite(poolEntry);}
}

如果连接被标记为驱逐状态,则会销毁该连接。如果连接未被标记为驱逐,则会执行正常的连接归还操作。

keepaliveTime

对空闲连接进行定期心跳检测的时间间隔,单位为毫秒。默认值为 120000(2分钟),最小允许值是 30000(30秒)。

if (keepaliveTime != 0 && keepaliveTime < SECONDS.toMillis(30)) {LOGGER.warn("{} - keepaliveTime is less than 30000ms, disabling it.", poolName);keepaliveTime = 0L;
}

如果 keepaliveTime 不等于 0 且小于 30 秒,则输出警告日志,提示 keepaliveTime 设置过短,并禁用心跳检测(将 keepaliveTime 设置为 0)。

定期检测的目的主要有两个:

  1. 检测连接是否失效。

  2. 防止连接因长时间空闲而被数据库或其他中间层关闭。

在创建新的物理连接时,会为其设置一个定期执行的任务KeepaliveTask,该任务会在 heartbeatTime 后首次执行,并随后以相同的时间间隔(heartbeatTime)重复执行。heartbeatTime 等于 keepaliveTime 减去一个随机偏移量(variance)。

variance 是最大为 keepaliveTime 的 10% 的随机偏移量。引入该随机偏移量的目的是为了避免所有连接在同一时刻发送心跳,从而减轻系统资源竞争和负载。

private PoolEntry createPoolEntry(){try {final var poolEntry = newPoolEntry(getTotalConnections() == 0);...final long keepaliveTime = config.getKeepaliveTime();if (keepaliveTime > 0) {// variance up to 10% of the heartbeat timefinal var variance = ThreadLocalRandom.current().nextLong(keepaliveTime / 10);final var heartbeatTime = keepaliveTime - variance;poolEntry.setKeepalive(houseKeepingExecutorService.scheduleWithFixedDelay(new KeepaliveTask(poolEntry), heartbeatTime, heartbeatTime, MILLISECONDS));}return poolEntry;}...return null;}

以下是 KeepaliveTask 的具体实现。

private final class KeepaliveTask implements Runnable{...public void run(){// 尝试将连接的状态从 STATE_NOT_IN_USE(未使用)改为 STATE_RESERVED(已保留),防止它被其他线程借用if (connectionBag.reserve(poolEntry)) {// 检查连接是否失效if (isConnectionDead(poolEntry.connection)) {// 将连接从连接池中移除并关闭softEvictConnection(poolEntry, DEAD_CONNECTION_MESSAGE, true);// 检查当前等待连接的线程数,判断是否向连接池中添加新的连接addBagItem(connectionBag.getWaitingThreadCount());}else {connectionBag.unreserve(poolEntry);logger.debug("{} - keepalive: connection {} is alive", poolName, poolEntry.connection);}}}}

connectionTestQuery

用于设置连接检测语句,默认为 none。

对于支持 JDBC4 的驱动程序,建议不要设置该参数,因为 JDBC4 提供了Connection.isValid()方法来进行连接有效性检查。

JDBC4 是 Java Database Connectivity (JDBC) 的第 4 版,首次在 Java 6(即 Java 1.6)中引入。因此,只要程序使用的是 Java 1.6 及更高版本,就可以使用isValid()方法。

连接有效性检测的实现逻辑

如果 connectionTestQuery 为 none,则会将 isUseJdbc4Validation 设置为 true。

// 如果 connectionTestQuery 为 none,则将其设置为 null
connectionTestQuery = getNullIfEmpty(connectionTestQuery);// 如果 connectionTestQuery 为 null,则 isUseJdbc4Validation 设置为 true。
this.isUseJdbc4Validation = config.getConnectionTestQuery() == null;

isUseJdbc4Validation 会用在两个地方:

  1. 判断驱动是否支持connection.isValid方法。

  2. 检测连接是否失效。

检测连接是否失效是在isConnectionDead中实现的。

boolean isConnectionDead(final Connection connection){try {setNetworkTimeout(connection, validationTimeout);try {final var validationSeconds = (int) Math.max(1000L, validationTimeout) / 1000;if (isUseJdbc4Validation) {return !connection.isValid(validationSeconds);}try (var statement = connection.createStatement()) {if (isNetworkTimeoutSupported != TRUE) {setQueryTimeout(statement, validationSeconds);}statement.execute(config.getConnectionTestQuery());}}...}}

可以看到,如果 isUseJdbc4Validation 为 true,则会调用connection.isValid方法来检测连接的有效性。否则,系统将使用配置的 connectionTestQuery 来执行 SQL 查询,以检查连接是否有效。

leakDetectionThreshold

连接从池中取出后,如果未归还超过一定时间,则会记录日志,提示可能的连接泄漏。默认值为 0,表示禁用泄漏检测。

if (leakDetectionThreshold > 0 && !unitTest) {if (leakDetectionThreshold < SECONDS.toMillis(2) || (leakDetectionThreshold > maxLifetime && maxLifetime > 0)) {LOGGER.warn("{} - leakDetectionThreshold is less than 2000ms or more than maxLifetime, disabling it.", poolName);leakDetectionThreshold = 0;}
}

如果 leakDetectionThreshold 小于 2 秒,或者 leakDetectionThreshold 大于连接池的 maxLifetime,则会发出警告,并将其重置为 0,禁用泄漏检测。

实现细节可参考:如何定位 Druid & HikariCP 连接池的连接泄漏问题?

什么时候会检测连接的有效性?

除了通过 KeepaliveTask 定期检查连接的有效性外,HikariCP 还会在借用连接时进行有效性检测。

这个检测逻辑在 getConnection 方法中实现。具体来说,在从连接池借用连接后,会检查连接的最后归还时间(poolEntry.lastAccessed)与当前时间的差值是否超过 aliveBypassWindowMs(默认 500 毫秒)。如果超过该时间阈值,则会调用 isConnectionDead(poolEntry.connection) 来检查连接是否失效。

public Connection getConnection(final long hardTimeout) throws SQLException{suspendResumeLock.acquire();final var startTime = currentTime();try {var timeout = hardTimeout;do {// 从连接池中借用一个连接var poolEntry = connectionBag.borrow(timeout, MILLISECONDS);if (poolEntry == null) {break; // We timed out... break and throw exception}final var now = currentTime();if (poolEntry.isMarkedEvicted() || (elapsedMillis(poolEntry.lastAccessed, now) > aliveBypassWindowMs && isConnectionDead(poolEntry.connection))) {closeConnection(poolEntry, poolEntry.isMarkedEvicted() ? EVICTED_CONNECTION_MESSAGE : DEAD_CONNECTION_MESSAGE);timeout = hardTimeout - elapsedMillis(startTime);}else {...return poolEntry.createProxyConnection(leakTaskFactory.schedule(poolEntry));}} while (timeout > 0L);...}

aliveBypassWindowMs 由配置项com.zaxxer.hikari.aliveBypassWindowMs控制,默认值为 500 毫秒。

这一逻辑与其他连接池中的 testOnBorrow 参数类似,只不过 testOnBorrow 是每次都检查,而 HikariCP 只有在连接空闲超过 500 毫秒时才会检查。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker部署scylladb

创建存储数据的目录和配置目录 mkdir -p /root/docker/scylla/data/data /root/docker/scylla/data/commitlog /root/docker/scylla/data/hints /root/docker/scylla/data/view_hints /root/docker/scylla/conf快速启动拷贝配置文件 docker run -d \--name scylla \scylladb/…

golang 在windows 系统的交叉编译

基本交叉编译命令 GOOS目标操作系统 GOARCH目标架构 go build -o 输出文件名 包路径 编译 Linux 64位程序 set GOOSlinux set GOARCHamd64 go build -o myapp-linux main.go 编译 MacOS (Darwin) 64位程序 set GOOSdarwin set GOARCHamd64 go build -o myapp-macos main.go …

本地mock服务编写

确认有需要mock的接口文档后&#xff0c;本地可以mock服务编写&#xff1b; 用于测试UI事务、模拟对接组件等&#xff1b; 使用python FLASK可以轻松建立本地mock服务端&#xff0c;注册预期的接口响应&#xff01;flask会在接收端持续打印收到的请求&#xff01; 注意&#…

京东云智能体平台joybuilder v3.0.0测试

平台介绍&#xff1a; JoyBuilder 是京东云推出的 AI 原生应用开发平台&#xff0c;以下是对它的具体介绍&#xff1a; 开发方式便捷高效&#xff1a;将 AI 能力融入低代码平台&#xff0c;用户通过对话式交互方式&#xff0c;输入如 “创建客户反馈管理系统” 等需求&#x…

前端实现对接现成文件下载接口(xlsx)

针对于Ant Design 框架 1.在你的api文件下编写接口路径 import request from /utils/request import storage from storeimport {AUTHORIZATION} from /store/mutation-types const api {downloadVocabularyTemplate:/vocabulary/downloadVocabularyTemplate, }export funct…

TCPIP详解 卷1协议 六 DHCP和自动配置

6.1——DHCP和自动配置 为了使用 TCP/IP 协议族&#xff0c;每台主机和路由器需要一定的配置信息。基本上采用3种方法&#xff1a;手工获得信息&#xff1b;通过一个系统获得使用的网络服务&#xff1b;使用某种算法自动确定。 拥有一个IP 地址和子网掩码&#xff0c;以及 DN…

联想电脑开机出现Defalut Boot Device Missing or Boot Failed怎么办

目录 一、恢复bios默认设置 二、关机重启 三、“物理”方法 在图书馆敲代码时&#xff0c;去吃了午饭回来发现刚开机就出现了下图的问题&#xff08;崩溃&#xff09;&#xff0c;想起之前也发生过一次 这样的问题&#xff0c;现在把我用到的方法写在下面&#xff0c;可能对…

用户登陆UI

本节任务 完成用户登陆UI&#xff0c;点击登陆按钮跳转到应用主页 界面原型&#xff1a; 登陆页面&#xff1a; 登陆成功页面&#xff1a; 涉及知识点&#xff1a; 线性布局Image组件输入框复选框分割线按钮路由跳转背景色、内容对齐 1 新建项目 录入项目信息&#xff1a;…

linux多线(进)程编程——(1)前置知识

liunx多线程编程&#xff08;前置知识&#xff09;前置知识 前言 学习编程就像是修仙&#xff0c;分为宗门的正统修士&#xff08;计算机专业的学生&#xff09;&#xff0c;以及野修&#xff08;半路转码&#xff09;。正统修士有各大宗门的功法&#xff0c;保证一路修行畅通…

Npfs!NpFsdCreate函数分析之从NpCreateClientEnd函数分析到Npfs!NpSetConnectedPipeState

第一部分&#xff1a; 1: kd> g Breakpoint 5 hit Npfs!NpFsdCreate: baaecba6 55 push ebp 1: kd> kc # 00 Npfs!NpFsdCreate 01 nt!IofCallDriver 02 nt!IopParseDevice 03 nt!ObpLookupObjectName 04 nt!ObOpenObjectByName 05 nt!IopCreateFile 06…

【软件测试】bug 篇

本章思维导图&#xff1a; 1. 软件测试的生命周期 软件测试贯穿于整个软件的生命周期 流程阶段需求分析测试计划测试设计/开发测试执行测试评估上线运行维护具体工作内容1. 阅读需求文档 2. 标记可测试需求 3. 确定测试类型1. 制定测试范围 2. 选择测试工具 3. 分配资源1. 编写…

「Unity3D」图片导入选项取消Read/Write,就无法正确显示导入大小,以及Addressable打包无法正确显示的问题

如果在Edit -> Project Settings -> Editor中的“Load texture data on demand”勾选&#xff0c;就会让图片导入设置中&#xff0c;不勾选Read/Write&#xff0c;就无法正确显示纹理的大小数字。 更进一步的问题是&#xff0c;使用Addressable打包的时候&#xff0c; 如…

《MySQL从入门到精通》

文章目录 《MySQL从入门到精通》1. 基础-SQL通用语法及分类2. 基础-SQL-DDL-数据库操作3. 基础-SQL-DDL-表操作-创建&查询4. 基础-SQL-DDL-数据类型及案例4.1 数值类型4.2 字符串类型4.3 时间和日期类型 5. 基础-SQL-DDL-表操作-修改&删除5.1 DDL-表操作-修改5.2 DDL-表…

Vccaux_IO在DDR3接口中的作用

一、Vccaux_IO在DDR3接口中的作用 1.vccaux_io通常为FPGA的IO bank的辅助电源&#xff0c;用于支持特定电压的IO标准 2.在DDR3接口中&#xff0c;FPGA的IO bank需要DDR3芯片的电压(1.5v/1.35v)匹配 3.Vccaux_IO用于为FPGA的DDR3接口I/O Bank供电&#xff0c;其电压值、噪声和稳…

深入理解Apache Kafka

引言 在现代分布式系统架构中&#xff0c;中间件扮演着至关重要的角色&#xff0c;它作为系统各组件之间的桥梁&#xff0c;负责处理数据传递、消息通信、负载均衡等关键任务。在众多中间件解决方案中&#xff0c;Apache Kafka凭借其高吞吐量、低延迟和可扩展性&#xff0c;已…

【NLP】 21. Transformer整体流程概述 Encoder 与 Decoder架构对比

1. Transformer 整体流程概述 Transformer 模型的整个处理流程可以概括为从自注意力&#xff08;Self-Attention&#xff09;到多头注意力&#xff0c;再加上残差连接、层归一化、堆叠多层的结构。其核心思想是利用注意力机制对输入进行并行计算&#xff0c;从而避免传统 RNN …

路由器端口映射的意思、使用场景、及内网ip让公网访问常见问题和解决方法

一、端口映射是什么意思 端口映射是将内网主机的IP地址端口映射到公网中&#xff0c;内部机器提供相应的互联网服务。当异地用户访问该这个端口时&#xff0c;会自动将请求映射到对应局域网内部的机器上。 二、端口映射常见使用场景 1&#xff0c;远程访问需求。当有…

GEO全域优化白皮书:盈达科技如何打造AI生态中的认知护城河

副标题&#xff1a;让内容被AI优先引用&#xff0c;占领生成式引擎的“主屏入口” 一、GEO&#xff1a;生成式引擎时代的内容占位权之战 随着ChatGPT、Kimi、DeepSeek等生成式AI快速成为信息获取的主流方式&#xff0c;搜索逻辑正在根本性改变&#xff1a;从“网页排名”转向“…

如何用DeepSeek大模型提升MySQL DBA工作效率?实战案例解析

如何用DeepSeek大模型提升MySQL DBA工作效率&#xff1f;实战案例解析 MySQL DBA&#xff08;数据库管理员&#xff09;的工作涉及数据库监控、SQL优化、故障排查、备份恢复等复杂任务&#xff0c;传统方式依赖手动操作和经验判断&#xff0c;效率较低。而DeepSeek大模型可以结…

系统设计思维的讨论

我们经常说自己熟悉了spring&#xff0c;能够搭建起一个项目基本框架&#xff0c;并且在此之上进行开发&#xff0c;用户or客户提出需求碰到不会的百度找找就可以实现。干个四五年下一份工作就去面试架构师了&#xff0c;运气好一些可能在中小公司真的找到一份架构师、技术负责…