찾다
백엔드 개발PHP 튜토리얼Redis Flash Sale 이용시 제품 슈퍼 현상을 해결하는 방법은 무엇입니까?

최근 플래시세일 이벤트를 진행했는데, 성능과 응답속도를 위해 redis를 사용했습니다. 글을 쓸 때 초자연적인 현상을 방지하는 데 특별한 주의를 기울였습니다. Redis 이론을 기반으로 하는 cas(check and set) 낙관적 잠금을 사용하면 이 문제를 해결할 수 있을 것이라고 생각했지만 여전히 매우 혼란스럽습니다. 구체적인 코드는 대략 다음과 같습니다.

<code><?php header("content-type:text/html;charset=utf-8");  
$redis = new redis();  
$result = $redis->connect('10.10.10.119', 6379);  
$mywatchkey = $redis->get("mywatchkey");  
$rob_total = 100;   //抢购数量  
if($mywatchkeywatch("mywatchkey");  
    $redis->multi();  
      
    //设置延迟,方便测试效果。  
    sleep(5);  
    //插入抢购数据  
    $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());  
    $redis->set("mywatchkey",$mywatchkey+1);  
    $rob_result = $redis->exec();  
    if($rob_result){  
        $mywatchlist = $redis->hGetAll("mywatchlist");  
        echo "抢购成功!<br>";  
        echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>";  
        echo "用户列表:<pre class="brush:php;toolbar:false">";  
        var_dump($mywatchlist);  
    }else{  
        echo "手气不好,再抢购!";exit;  
    }  
}  
?>  

답글 내용:

최근 플래시세일 이벤트를 진행했는데, 성능과 응답속도를 위해 redis를 사용했습니다. 글을 쓸 때 초자연적인 현상을 방지하는 데 특별한 주의를 기울였습니다. Redis 이론을 기반으로 하는 cas(check and set) 낙관적 잠금을 사용하면 이 문제를 해결할 수 있을 것이라고 생각했지만 여전히 매우 혼란스럽습니다. 구체적인 코드는 대략 다음과 같습니다.

<code><?php header("content-type:text/html;charset=utf-8");  
$redis = new redis();  
$result = $redis->connect('10.10.10.119', 6379);  
$mywatchkey = $redis->get("mywatchkey");  
$rob_total = 100;   //抢购数量  
if($mywatchkeywatch("mywatchkey");  
    $redis->multi();  
      
    //设置延迟,方便测试效果。  
    sleep(5);  
    //插入抢购数据  
    $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());  
    $redis->set("mywatchkey",$mywatchkey+1);  
    $rob_result = $redis->exec();  
    if($rob_result){  
        $mywatchlist = $redis->hGetAll("mywatchlist");  
        echo "抢购成功!<br>";  
        echo "剩余数量:".($rob_total-$mywatchkey-1)."<br>";  
        echo "用户列表:<pre class="brush:php;toolbar:false">";  
        var_dump($mywatchlist);  
    }else{  
        echo "手气不好,再抢购!";exit;  
    }  
}  
?>  

이 코드는 높은 동시성 조건에서는 여전히 과매도될 것이라고 생각합니다. 상금이 1개만 남았을 때 세 사람이 동시에 $redis->watch("mywatchkey")을 실행하여 얻은 데이터가 99라면 과매도 현상이 발생한다고 가정해 보겠습니다.

redis은 단일 스레드 읽기이므로 가장 간단한 대기열 구현을 사용해 보겠습니다.

  1. 추첨 전 redisqueueaward:100에 경품 개수를 적습니다. // 길이가 100인 목록, 값은 경품 당첨 여부에만 사용됩니다

  2. 동시추첨

<code>$award = $redis->lpop('award:100'); // 由于队列只有100个值,可以确保只有100个人中奖
if(!$award){
    echo "手气不好,再抢购!";exit;  
}

// 剩下就是中奖操作的事情了</code>

sleep(5);
귀사에서는 아직도 인력을 수용하나요?

이런 상황을 생각해 보세요.
mywatchkey=99
사용자 A가 mywatchkey를 요청하고 99를 받았습니다.
사용자 B가 mywatchkey를 요청하고 99를 받았습니다.
A와 B의 요청이 완료되면 mywatchkey는 무엇이어야 합니까? . 101인가요, 100인가요?

이것은 전형적인 확인 후 실행 오류입니다

먼저 이 코드의 "과매도" 결과가 $mywatchkey > 100인지(불가능하다고 생각합니다)
아니면 $mywatchkey =100일 때 동시에 두 페이지가 나오는지 여쭤보겠습니다. "구매 성공!"
이 코드는 테스트해보지 않았으며 다음과 같을지 추측만 했습니다.

1.세션 A: mywatchkey 확인을 수행합니다. 이때 mywatchkey = 99

2.Session B: mywatchkey를 처리한 후 현재 mywatchkey=100이지만 Session A의 후속 작업에는 영향을 미치지 않습니다

두 개의 연결을 더 추가하고 살펴보겠습니다. 뭔가 얻을 수 있습니다

redis의 트랜잭션 및 감시 명령문
redis-watch-multi-exec-by-one-client

이 문제를 근본적으로 해결하고 싶다면 먼저 공부해보세요.

1. 잠금.

2. 기존 데이터베이스 트랜잭션.

그런 다음 Redis와 기존 데이터베이스의 차이점을 알아보세요.

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
es和redis区别es和redis区别Jul 06, 2019 pm 01:45 PM

Redis是现在最热门的key-value数据库,Redis的最大特点是key-value存储所带来的简单和高性能;相较于MongoDB和Redis,晚一年发布的ES可能知名度要低一些,ES的特点是搜索,ES是围绕搜索设计的。

一起来聊聊Redis有什么优势和特点一起来聊聊Redis有什么优势和特点May 16, 2022 pm 06:04 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于redis的一些优势和特点,Redis 是一个开源的使用ANSI C语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式存储数据库,下面一起来看一下,希望对大家有帮助。

实例详解Redis Cluster集群收缩主从节点实例详解Redis Cluster集群收缩主从节点Apr 21, 2022 pm 06:23 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis Cluster集群收缩主从节点的相关问题,包括了Cluster集群收缩概念、将6390主节点从集群中收缩、验证数据迁移过程是否导致数据异常等,希望对大家有帮助。

Redis实现排行榜及相同积分按时间排序功能的实现Redis实现排行榜及相同积分按时间排序功能的实现Aug 22, 2022 pm 05:51 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,希望对大家有帮助。

详细解析Redis中命令的原子性详细解析Redis中命令的原子性Jun 01, 2022 am 11:58 AM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于原子操作中命令原子性的相关问题,包括了处理并发的方案、编程模型、多IO线程以及单命令的相关内容,下面一起看一下,希望对大家有帮助。

一文搞懂redis的bitmap一文搞懂redis的bitmapApr 27, 2022 pm 07:48 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了bitmap问题,Redis 为我们提供了位图这一数据结构,位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已,希望对大家有帮助。

实例详解Redis实现排行榜及相同积分按时间排序功能的实现实例详解Redis实现排行榜及相同积分按时间排序功能的实现Aug 26, 2022 pm 02:09 PM

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,下面一起来看一下,希望对大家有帮助。

redis error什么意思redis error什么意思Jun 17, 2019 am 11:07 AM

redis error就是redis数据库和其组合使用的部件出现错误,这个出现的错误有很多种,例如Redis被配置为保存数据库快照,但它不能持久化到硬盘,用来修改集合数据的命令不能用。

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음