首页 > 数据库 >Redis生成无规律不重复的纯数字券码

Redis生成无规律不重复的纯数字券码

时间:2024-02-17 20:13:53浏览次数:32  
标签:arr 无规律 队列 券码 Redis codeData valid array

需求描述
在开发优惠券系统或票务系统的时候,经常要生成纯数字码,券码要求:12位纯数字,无规律,不重复。

下面我提供一种思路,利用redis的List数据类型,Lpop+Rpush 维护一个1万个码的队列

队列数据结构
保持1万个券码数量,可以根据项目实际情况自行调整

Array
(
[0] => 478439938353
[1] => 992919492490
[2] => 476600175512
[3] => 512596230643
[4] => 627621923933
[5] => 763100176075
…………
…………
…………
[9998] => 763100176032
[9999] => 797543322210
)

用户端
用Lpop取出指定数量券码,因为Lpop具有原子性,在高并发的场景下,即使同一时间多个用户获取券码,也要按先后顺序一个个执行,这样就保证了每个用户获取出来的券码肯定不会重复的

点击查看代码
/**
 * @从队列中取出指定数量的券码
 * @param $num   券码数量
 * @return array 返回券码数组
 */
function getCode($num){
	$codeArr=[];
	for($i=0;$i<$num;$i++){
		$tmpCode=$redis->LPOP($key);
		if(strlen($tmpCode)==10){
			$codeArr[]=$tmpCode;
		}
	}
	//如果队列中剩余券码数量不足,不足的部分要随机生成
	if(count($codeArr)<$num){
		$diff=$num-count($codeArr);
		for($i=0;$i<$diff;$i++){
			$code=rand(100000000000,999999999999);
			$codeArr[]=$code;
		}
	}
	return $codeArr;
 
}

定时脚本

  • 定时脚本每分钟执行一次,检查队列券码数量,消耗多个券码,就补充多少个券码进去。
  • 随机新生成的券码,要去数据库查下看是否已存在,如果已存在,需重新随机生成一个,再去数据库检查,直至查出有效券号为止
  • Rpush批量插入队列,提高操作效率
    代码示例
点击查看代码
$codeData=$redis->lRange($key,0,-1); //取出券码队列所有数据
$codeData=!is_array($codeData)?[]:$codeData;
$len=count($codeData);
$diff=10000-$len;//差多少个
 
$valid_arr=[];//有效核销码
if($diff>0){
    getValidCode($diff);
    $arr=array_merge([$key],$valid_arr);
    call_user_func_array(array($redis,"rpush"),$arr);//批量插入尾部,提高操作效率
}
 
//递归获取有效券号
function getValidCode($need_num){
    $filter_arr=[];
    for($i=0;$i<10;$i++){
        $code=rand(1000000000,9999999999);
        if(in_array($code,$codeData)){
            continue;
        }
        $filter_arr[]="'".$code."'";
        $valid_arr[]=$code;
    }
    if(count($filter_arr)==0){
        getValidCode($need_num);
        return;
    }
    //查找券码是否已使用
    $used_arr=[];
    $filter_str=implode(",",$filter_arr);
    $sql="select distinct `code` from `user_code` where `code` in ({$filter_str})";
    $tmpData=DB::query($sql);
    foreach($tmpData as $k=>$v){
        $used_arr[]=$v['code'];
    }
    unset($tmpData);
    $valid_arr=array_diff($valid_arr,$used_arr);//减掉数据库中已用的
    if(count($valid_arr)<$need_num){
        getValidCode($need_num);
    }
}

项目盘点
笔者所在企业的票务系统,使用这套券码解决方案,在年数据几千万条的情况下,已经稳定运行多年

标签:arr,无规律,队列,券码,Redis,codeData,valid,array
From: https://www.cnblogs.com/bcjs/p/18018296

相关文章

  • Redis使用Lua脚本
    Redis使用Lua脚本Redis使用lua脚本的优点减少网络开销:将原来多次请求的逻辑封装为脚本在服务器上执行,只需1次请求就能完成,减少了网络往返时延;原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入;复用性:客户端发送的脚本会永久保存在Redis中,其他客户端可以复用......
  • 【Redis】【高性能】Redis 批量查询技巧
    1  前言Redis,我们做开发的想必都用过,他是一种缓存,主要用于快速响应结果嘛。比如我们要获取商品的详情,有日销量、月销量、库存数量、评价数量,这些数据都在Redis缓存中,那么我们是要拿四趟?还是一趟呢?当然是一趟最好呀。接下来我们来看看为什么我们要一趟这么做,以及怎么做。2  ......
  • 细扣Redis Cluster原理
    细扣RedisCluster原理RedisCluster是Redis提供的一种分布式数据存储解决方案,它能够将大量数据分布到多个节点上,实现高可用性和水平扩展。以下是RedisCluster的工作原理及其如何保证数据安全、一致性以及避免脏数据问题的详细解释:工作原理数据分片(Slot分配):RedisClu......
  • Redis
    ubuntu安装redis:sudoapt-getupdatesudoapt-getinstallredis-serverredis-server即可启动从打印的信息可以看到端口信息netstat-tulnp也可查看程序的端口号redis-cli连上redissetname"alexli"setage22getnamegetagekeys*查看所有的keysets......
  • dotnet aspnet redis 缓存 分布式缓存
    分布式缓存\appsettings.Development.json{"Logging":{"LogLevel":{"Default":"Information","Microsoft.AspNetCore":"Warning"}}}分布式缓存\appsettings.json{"Logg......
  • springboot整合redis报错:链接失败;org.springframework.data.redis.RedisConnectionFai
    错误原因:开启了保护模式解决方案:关闭保护模式和防火墙具体步骤:1、打开你的redis配置文件,做出如下修改2.开启进程守护yes代表开启守护进程模式。在该模式下,redis会在后台运行,并将进程pid号写入至redis.conf选项pidfile设置的文件中,此时redis将一直运行,除非手动kill该进程。3.......
  • Mac电脑安装RedisCluster集群(非Docker模式)
    第1步,新建redis.confredis.conf内容如下:port7021cluster-enabledyes              //启用集群模式cluster-config-filenodes.conf     //集群的配置文件cluster-node-timeout5000appendonlyyesdaemonizeyesbind0.0.0.0   ......
  • SpringBoot 报错无法连接到Redis (Unable to connect to Redis)
    UnabletoconnecttoRedisSpringBoot3.1.2报错:UnabletoconnecttoRedis背景在搭建项目开发环境的时候,进行Redis相关的单元测试时发现无法连接到远程的Redis服务器。并且报错UnabletoconnecttoRedisRedis所在服务器UbuntuService64位20.04.06问题排查:检查基......
  • redis基础知识梳理
    性能测试工具redis-benchmark-hhost-pport-cconnections-nrequests-hhost:指定Redis服务器的主机名或IP地址。-pport:指定Redis服务器的端口号。-cconnections:指定并发连接数,即同时向服务器发起的连接数量。-nrequests:指定总的请求数量,即测试期间每个连接向服务......
  • Redis基础命令集
    一、基础命令1、ping(心跳命令)若看到PONG响应,则说明客户端与Redis的连接时正常的。2、select(切换数据库)redis默认有16个数据库,默认使用的是0号DB。3、dbsize(查看key数量)查看当前数据库中key的数量。4、flushdb(删除当前库中所有数据)清楚当前DB中的所有数据,不影响其他DB......