欢迎光临
我们一直在努力

php方案 读写分离延迟处理

读写分离延迟处理

class MasterSlaveDB {
private $master; // 主库
private $slave; // 从库

function __construct() {
$this->master = new PDO('mysql:host=master;dbname=test', 'root', '');
$this->slave = new PDO('mysql:host=slave;dbname=test', 'root', '');
}

// 写操作(主库)
function updateUser($id, $name) {
$stmt = $this->master->prepare("UPDATE users SET name = ? WHERE id = ?");
$stmt->execute([$name, $id]);

// 返回版本号用于后续校验
return time();
}

// 读操作 – 方案1: 强制主库读(写后立即读)
function getUserFromMaster($id) {
$stmt = $this->master->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}

// 读操作 – 方案2: 从库读(可能有延迟)
function getUser($id) {
$stmt = $this->slave->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
return $stmt->fetch();
}

// 读操作 – 方案3: 版本号校验重试
function getUserWithRetry($id, $min_version = 0) {
for ($i = 0; $i < 3; $i++) {
$row = $this->getUser($id);

// 检查版本是否足够新
if ($row && $row['updated_at'] >= $min_version) {
return $row;
}

usleep(100000); // 延迟100ms重试
}

// 重试失败,强制主库读
return $this->getUserFromMaster($id);
}
}

$db = new MasterSlaveDB();

// 场景: 更新后立即查询
$version = $db->updateUser(1, 'newname');

// 错误: 从库读可能读到旧数据
$user = $db->getUser(1); // name可能还是旧值

// 正确: 强制主库读
$user = $db->getUserFromMaster(1); // name=newname

// 优化: 版本校验+重试
$user = $db->getUserWithRetry(1, $version); // 确保读到最新数据

大白话: 主从复制有延迟(1500ms),写后立即读要么读主库,要么校验版本号重试。

输出:
主从延迟: 平均50ms, 最高500ms

场景1(错误): 写主库 -> 读从库 -> 读到旧数据
场景2(安全): 写主库 -> 读主库 -> 读到新数据
场景3(优化): 写主库 -> 校验版本 -> 重试或读主库

方案选择: 强一致读主库, 最终一致读从库

赞(0)
未经允许不得转载:171主机测评 » php方案 读写分离延迟处理
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址