CodeIgniter4数据库读写分离与Session粘滞

风萱大大_8780

风萱大大_8780

2026-08-09

180人浏览

原创

ci4 不支持原生读写分离,其 database.default 配置仅允许单组连接参数;需手动定义 read/write 连接组并在 .env 中配置,再通过自封装工厂函数调用 configdatabase::connect('group') 显式获取连接。

codeigniter4数据库读写分离与session粘滞

CI4 的 database.default 配置不支持读写分离

CodeIgniter 4 官方数据库配置(database.default.*)只允许定义一套连接参数,没有内置的 read / write 分组字段。试图在 .env 里加 database.read.hostname 或修改 app/Config/Database.php 中的 $default 数组,都不会被框架识别——CI4 的 ConfigDatabase::connect() 只读取 database.default.* 这一组。

常见错误现象:配置了多套 host,但所有查询(包括 INSERTUPDATE)全打到同一个库上;或手动改 Database.php 后报错 Call to undefined method CodeIgniter\Database\MySQLi\Connection::read()

  • CI4 不像 Laravel 那样有 connections.read + connections.write 的原生支持
  • app/Config/Database.php 是只读模板,框架启动时完全忽略它;真正生效的只有 .env
  • 若强行在 Database.php 中 return 多个连接实例,后续调用 $this->db 仍只会拿到 default 实例

手动实现读写分离需绕过默认连接机制

要让 CI4 实际走不同库,必须跳过 $this->db 自动注入,改用 ConfigDatabase::connect('group_name') 显式获取连接,并配合查询类型做路由判断。

例如,在控制器中:

// 写操作走主库
$writeDB = ConfigDatabase::connect('write');
$writeDB->table('users')->insert(['name' => 'alice']);
<p>// 读操作走从库
$readDB = ConfigDatabase::connect('read');
$users = $readDB->table('users')->get()->getResult();
</p>

关键点在于:你得自己定义 'write''read' 这两个连接组,并让它们在 .env 中可被识别。

Session Memory
Session Memory

持久记忆工具包,专为AI智能体设计。保存上下文,基于相关性评分进行召回,整合洞察,跨会话追踪决策。功能...

下载
  • 先在 .env 中添加两组配置:database.write.hostnamedatabase.write.username 等,以及 database.read.hostname
  • 然后在 app/Config/Database.php 中重写 init() 方法(或覆盖 getConnection()),根据传入的 group 名动态加载对应 .env 配置
  • 注意:CI4 的 Database 类没有 connect('xxx') 的原生支持,必须自己封装一个工厂函数,否则会报 InvalidArgumentException: Group "read" does not exist

Session 粘滞不是 CI4 自带功能,必须靠应用层控制

所谓“Session 粘滞”,是指同一用户的所有请求(尤其含写操作)始终落在同一台从库上,避免主从延迟导致读不到刚写入的数据。CI4 的 Session 类(CodeIgniterSessionSession)本身不感知数据库拓扑,也不提供 sticky_to_slave 开关。

真实场景下,粘滞逻辑只能由你自己编码实现:

  • 在登录成功后,把当前用户分配的从库编号存入 Session:session()->set('slave_id', 1)
  • 后续读请求,先读 session()->get('slave_id'),再调用对应编号的 ConfigDatabase::connect("read_{$id}")
  • 写请求一律走 write 组,且写完后可主动触发一次短时缓存失效(如 cache()->delete("user_{$uid}")),降低对粘滞的依赖
  • 不要依赖 IP 做粘滞——负载均衡器可能轮换源 IP,且移动端 IP 易变

最容易被忽略的兼容性陷阱

CI4 的 Query Builder 在底层复用同一个 Connection 实例,一旦你手动切换连接,$builder->from()$builder->where() 等链式调用不会自动绑定到新连接。这意味着:

  • 不能混用:$this->db->table('x')->get()ConfigDatabase::connect('read')->table('x')->get() 共存于同一请求中,容易因事务上下文错乱导致数据不一致
  • Query Builder 的 join() 跨库时无效——MySQL 不允许 SELECT * FROM master.users JOIN slave.logs 这种语法,除非用 FEDERATED 引擎(不推荐)
  • Migration 和 Seeder 默认只跑在 default 连接上,部署时若没切到 write 组,可能建表失败却无提示

真正在生产环境跑读写分离,得接受一个事实:CI4 不是为这个场景设计的。每加一层手动路由,就多一分维护成本和出错概率。不如先确认主从延迟是否真到了影响业务的程度,再决定要不要上。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

2023.10.17

580

4

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

2023.10.18

856

5

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

2025.08.19

1726

14

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

2185

3

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2023.08.14

3581

10

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2023.08.31

2311

3

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.05

807

5

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

2127

5

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2023.10.16

2147

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程