资讯专栏INFORMATION COLUMN

Redis 实现秒杀

MycLambert / 992人阅读

摘要:秒杀接下来是关键的一步,使用的是的命令获取商品,利用的是的原子性。好的方面是秒杀成功的数量是准确的,没有超卖。参考资料实现高并发下的抢购秒杀功能基于云原生的秒杀系统设计思路秒杀架构设计

导语

秒杀想必大家都了解,在短时间内请求访问会激增,同时要保证不会超卖和数据的准确,对于技术方面还是有些考验的。可惜的是,一直没有机会在项目中实现。再看了一些资料后,打算实验下。以下代码仅为测试所用,环境比较简单,请根据实际情况进行修改。

创建秒杀队列

在开始秒杀之前,先将商品放入队列中,如下

/**
     * 创建秒杀列表
     */
    public function createList()
    {
        $count = 30;
        $redisKey = "goods_list";

        for ($i = 1; $i <= $count; $i++) {

            // 测试用,防止数据错误
            if (Redis::llen($redisKey) >= $count) {
                break;
            }

            Redis::rpush($redisKey, $i);
        }
    }

执行完后,在 Redis 中看下

有 30 个商品 ID,数据正常。

秒杀

接下来是关键的一步,使用的是 Redis 的 lpop 命令获取商品 ID,利用的是 Redis 的原子性。

/**
     * 秒杀
     */
    public function buy()
    {
        // 随机用户名,无意义,仅做标记
        $username = Hash::make(now());

        if ($goodsId = Redis::lpop("goods_list")) {
            // 购买成功
            Redis::hset("buy_success", $goodsId, $username);
        } else {
            // 购买失败
            Redis::incr("buy_fail");
        }
    }

如上,简化了代码,购买之后,成功与否只是做记录。实际应用中,当然会更加复杂,但要注意的是,不要同步操作 Mysql。多说一句,Hash:make(now()) 即使值相同,也不会生成相同的数据,参考这里。

测试

最后就是进行测试了,使用 ab 测试,执行 ab -c 300 -n 3000 http://localhost/buy/ ,上述命令的意思是 300 并发,共请求 3000 次

执行完成,速度并不快,并且还有 794 个访问失败。来看下数据是否正确吧。在页面中打印 buy_success

30 个成功者。再来看下秒杀失败的数量

不是一个准确的数字,2165+30 是所有请求成功的数字,再加上失败的 794 ,总数是 2989,依然不足 3000。

结语

上述测试有不足的地方,响应速度慢、请求失败、失败计数不准确。看来有很多要优化的地方,不止是代码层。测试的时候忘记将访问记录入库关掉,应该是有些影响。
好的方面是秒杀成功的数量是准确的,没有超卖。

更新

重新配置了环境, 测试了同样的代码。不同的地方是增加了每次访问判断是否在黑名单(实时查询 MySQl),而访问记录改成了队列写入 MySQL。结果如下

对比来看还是有所提升的。最主要的是数据终于是正确的,访问失败 355,抢购成功 30,抢购失败 2615(忘记截图了),相加总数正好是请求总数。而且 MySQL 中记录的访问记录也是 3000。


参考资料:Redis实现高并发下的抢购、秒杀功能、基于云原生的秒杀系统设计思路、秒杀架构设计

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31233.html

相关文章

  • Redis--秒杀场景应用

    摘要:在大流量程序开发中,必然会遇到高并发的应用的场景。乐观锁实现秒杀功能它的优点如下消息队列对内存消耗较大,个请求,需要操作出队列。需要结合实际的业务场景嵌入本文的核心实现逻辑。 在大流量程序开发中,必然会遇到高并发的应用的场景。解决方案大致分为两个方向,消息队列、锁 redis 实现消息队列核心简单版本 $key = quque; /** ...

    lovXin 评论0 收藏0
  • 秒杀系统优化方案之缓存、队列、锁设计思路

    摘要:一为什么难秒杀系统难做的原因库存只有一份,所有人会在集中的时间读和写这些数据。又例如抢票,亦与秒杀类似,瞬时流量更甚。 一、为什么难     秒杀系统难做的原因:库存只有一份,所有人会在集中的时间读和写这些数据。例如小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。又例如12306抢票,亦与秒杀类似,瞬时流量更甚。 主要需要解决的问题有两个: 高并发对数据库...

    dinfer 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<