Laravel 8 数据库读写分离需在config/database.php中将read/write嵌套于同一mysql连接内,read为数组、write为单元素关联数组,共用配置置外层,且必须启用sticky=>true;事务及Eloquent默认操作均强制走主库。

Laravel 8 不支持“数据库缓存读写分离”这个概念——缓存和数据库读写分离是两套完全独立的机制,不能混为一谈。你无法也不应该让 Laravel 的 Cache 组件去走数据库的 read/write 路由逻辑。所谓“数据库缓存读写分离”,通常是误解了术语:要么想配 数据库主从读写分离,要么想做 缓存冷热数据分离。下面分清楚讲。
数据库主从读写分离(重点,Laravel 8 原生支持)
这是最常被问及、也最容易配错的部分。Laravel 8 通过 config/database.php 中单个 mysql 连接的嵌套结构实现自动路由,不是靠新增两个连接。
- 必须把
read和write写在同一个'mysql'连接配置内,read是数组(哪怕只有一个从库也要写成[['host' => '...']]),write是单元素关联数组(如['host' => '...']) - 共用字段(
database、username、password、charset、driver)必须放在外层,不能塞进read或write里面,否则会被忽略 -
sticky => true必须开启:否则用户刚提交表单就查不到新数据,不是 bug,是主从延迟导致的预期行为 - 事务中所有查询(包括
select)强制走主库,无法绕过;Eloquent 的find()、get()默认也走主库,除非你用了on('xxx')或设了$connection
缓存冷热数据分离(可选,需手动配置)
如果你真想对缓存本身做“读写分流”,比如热数据放 Redis 0 库、冷数据放 Redis 1 库或 File 驱动,那就属于缓存策略优化,和数据库无关。
- 在
config/cache.php的'stores'中定义多个缓存 store,例如'redis-hot'和'redis-cold',分别指定不同database或driver - 业务中显式调用:
Cache::store('redis-hot')->put(...)存热数据,Cache::store('redis-cold')->put(...)存冷数据 - 不推荐用 Tag 实现冷热分区,因为 Laravel 8 的 File 和 Array 驱动不支持 tags,且 Redis tags 在集群模式下有兼容风险
常见错误组合(务必避开)
这些看似合理、实则失效的配置方式,在 Laravel 8 中非常典型:
- 新增
mysql_read和mysql_write两个独立连接,然后模型里写protected $connection = 'mysql_read'—— 这不算读写分离,只是硬编码切换,事务、连接复用、故障转移全要自己处理 - 保留原
mysql配置,只额外加一个mysql_slave连接,再在控制器里写User::on('mysql_slave')->get()—— 这样从库确实能查到,但框架的自动路由、sticky 机制、事务一致性全部失效 - 把
database、username写在read数组里,导致从库连不上,报Database [xxx] not configured - 忘了运行
php artisan config:clear,改完配置却还在用缓存旧值


















