当前位置:首页 > PHP

php redis实现秒杀

2026-03-13 09:19:53PHP

Redis实现秒杀的PHP方案

秒杀场景的核心问题是高并发下的超卖和性能瓶颈。Redis凭借单线程原子性和高性能特性,是解决这一问题的理想选择。以下是基于PHP和Redis的完整实现方案:

使用Redis原子操作防止超卖

通过Redis的原子性操作(如DECR、INCRBY)确保库存扣减的准确性:

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

$productId = 'product_123';
$userId = uniqid();

// Lua脚本保证原子性
$lua = <<<LUA
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock > 0 then
    redis.call('DECR', KEYS[1])
    return redis.call('SADD', KEYS[2], ARGV[1])
end
return 0
LUA;

$result = $redis->eval($lua, [$productId, 'seckill_success_users', $userId], 2);
if ($result) {
    echo "秒杀成功";
} else {
    echo "秒杀失败";
}

库存预热与限流措施

提前将商品库存加载到Redis,避免活动开始时的数据库压力:

// 活动开始前执行
$totalStock = 1000;
$redis->set('product_123', $totalStock);
$redis->expire('product_123', 3600); // 设置过期时间

结合令牌桶算法实现限流:

function acquireToken($redis, $key, $limit, $expire) {
    $now = microtime(true);
    $redis->watch($key);
    $lastTime = $redis->get($key);

    if ($lastTime && $now - $lastTime < 1/$limit) {
        $redis->unwatch();
        return false;
    }

    $redis->multi();
    $redis->set($key, $now);
    $redis->expire($key, $expire);
    return $redis->exec();
}

异步订单处理方案

秒杀成功后采用消息队列异步处理订单:

// 秒杀成功后
if ($result) {
    $orderData = [
        'user_id' => $userId,
        'product_id' => $productId,
        'create_time' => time()
    ];
    $redis->lPush('seckill_order_queue', json_encode($orderData));
}

后台消费进程处理:

while (true) {
    $orderJson = $redis->rPop('seckill_order_queue');
    if ($orderJson) {
        $order = json_decode($orderJson, true);
        // 实际订单入库操作
        saveToDatabase($order);
    }
    usleep(100000); // 100ms间隔
}

数据一致性保障

采用双重检查避免数据库与Redis数据不一致:

// 下单前再次检查
if ($redis->sIsMember('seckill_success_users', $userId)) {
    $dbStock = getDbStock($productId);
    if ($dbStock > 0) {
        createOrder($userId, $productId);
    } else {
        $redis->sRem('seckill_success_users', $userId);
        $redis->incr('product_123'); // 回滚库存
    }
}

性能优化关键点

  1. 使用Redis管道减少网络往返:

    $redis->pipeline();
    $redis->get('stock');
    $redis->sAdd('users', $userId);
    $results = $redis->exec();
  2. 连接池管理避免频繁创建连接

  3. 热点数据分片存储减轻单节点压力

  4. 采用CLUSTER模式实现横向扩展

    php  redis实现秒杀

该方案通过Redis原子操作保证数据一致性,异步处理提升系统吞吐量,多重校验确保最终准确性,可支持万级QPS的秒杀场景。实际部署时需要根据具体业务调整参数并进行压力测试。

标签: 秒杀php
分享给朋友:

相关文章

php实现推送

php实现推送

PHP 实现推送功能的方法 PHP 实现推送功能可以通过多种方式完成,包括 WebSocket、Server-Sent Events (SSE)、长轮询或第三方推送服务。以下是几种常见的方法: 使用…

php实现秒杀

php实现秒杀

PHP实现秒杀功能的关键技术 秒杀系统需要解决高并发、数据一致性、系统稳定性等问题。以下是PHP实现秒杀功能的核心技术方案: 数据库优化 使用InnoDB引擎的行级锁和事务特性,确保数据一致性。商品…

php 实现多态

php 实现多态

PHP 实现多态的方法 多态是面向对象编程的三大特性之一,允许不同类的对象对同一消息做出响应。PHP 主要通过以下方式实现多态: 通过接口实现多态 定义接口并让不同类实现该接口,通过接口类型调用方法…

php实现分享功能实现

php实现分享功能实现

实现PHP分享功能的方法 在PHP中实现分享功能可以通过多种方式完成,以下是一些常见的实现方法: 使用社交媒体分享按钮 社交媒体平台如Facebook、Twitter、LinkedIn等提供了现成…

php实现多进程

php实现多进程

PHP 实现多进程的方法 PHP 本身是单线程的脚本语言,但可以通过扩展或系统调用来实现多进程操作。以下是几种常见的实现方式: 使用 pcntl 扩展 pcntl(Process Control)是…

php实现记住密码

php实现记住密码

实现记住密码功能的方法 使用PHP实现记住密码功能通常需要结合Cookie和Session技术。以下是几种常见的实现方式: 使用Cookie存储登录信息 在用户登录时创建一个长期有效的Cookie来…