Java-高性能缓存Redis Lua 脚本

Redis LuacnaRedis Lua 脚本

日期+ 自增Id(位数不足前面补零)

例:

日期:20210309 + 自增(5位)

2021030900001

复制代码
local key = tostring(KEYS[1]);
local count = tonumber(KEYS[2]);
local dateStr = tostring(KEYS[3]);

local newKey = key .. "_" .. dateStr;
local numRedis = redis.call("incr", newKey);
print(numRedis);

if (numRedis == 1) then
	redis.call("expire",newKey,60);
end

-- 计算数字的位数
local function DightNum(num)
	if math.floor(num) ~= num or num < 0 then
		return -1;
	elseif 0 == num then
		return 1;
	else
		local tmp_dight = 0;
		while num > 0 do
			num = math.floor(num/10);
			tmp_dight = tmp_dight + 1;
		end
		return tmp_dight;
	end
end

-- 在整数数字前面加0
-- dest_dight 标识最终生成位数,例如 AddZeroFrontNum(5, 1) 计算后是00001
local function AddZeroFrontNum(dest_dight, num)
	local num_dight = DightNum(num);
	if -1 == num_dight then
		return -1;
	elseif dest_dight <= num_dight then
		return tostring(num);
	else
		local str_e = ""
		for var =1, dest_dight - num_dight do
			str_e = str_e .. "0";
		end
		return str_e .. tostring(num);
	end
end

local idStr = AddZeroFrontNum(count, numRedis);
return dateStr .. idStr;

注:windows 下面redis-cli 执行lua脚本,必须git bash 下面执行,cmd下面没有cat命令,所以不能执行

复制代码
./redis-cli -a root@123 script load "$(cat getGenerateId.lua)"

sha :8b760e96cba49659ae2e2e33eeeefa9347dcccbd

参数说明: evalsha sha numkeys key1 key2 key3

参数总数量 key1 key2 key3

复制代码
./redis-cli -a root@123 evalsha 8b760e96cba49659ae2e2e33eeeefa9347dcccbd 3 orderid 5 20210310

Java Springboot

复制代码
@Service
public class RedisGenerateIdServiceImpl {
    private static final DateFormat df = new SimpleDateFormat("yyyyMMdd");

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private DefaultRedisScript<String> redisScript;

    @PostConstruct
    public void init(){
        redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(String.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("luascript/getGenerateId.lua")));
    }

    public String executeScript(DefaultRedisScript<String> script, final List<String> keys) {
        return redisTemplate.execute(script, keys);
    }

    /**
     * 每秒从 1 开始生成唯一标识,包括时间戳:yyyyMMdd
     * 最终格式为:yyyyMMdd + 四位有序数字
     * @param sha     redis中生成lua脚本的序列号
     * @param key     redis中存放id的key前缀
     * @param length  后面生成有序数字的位数
     * @return
     */
    public Long fetchUUID(DefaultRedisScript<String> script, String key, String length){
        if(Objects.isNull(script)){
            script = redisScript;
        }
        List<String> keys = new ArrayList<>();
        keys.add(key);
        keys.add(length);
        Calendar now = new GregorianCalendar();
        String datetime = df.format(now.getTime());
        keys.add(datetime);
        String result = executeScript(script, keys);
        return Long.parseLong(result);
    }
}
相关推荐
wdfk_prog5 小时前
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计
java·linux·开发语言·面试·职场和发展·架构·c
卓怡学长5 小时前
w255基于springboot仓库管理系统
java·数据库·spring boot·spring·intellij-idea
这个DBA有点耶8 小时前
SQL调优进阶:从“优化一条SQL”到“优化一个系统”的思维升级
java·大数据·数据库·sql·程序人生·dba·改行学it
csdn2015_8 小时前
springboot读取配置的方法
java·spring boot·spring
AOwhisky9 小时前
下一代容器来了?Docker 宣布原生支持 WebAssembly
java·运维·docker·容器·rust·wasm
云云只是个程序马喽11 小时前
海外短剧平台搭建方案:私有化源码系统选型|云微短剧系统技术架构拆解
java·php
C137的本贾尼12 小时前
第七篇:消息队列(MQ)——就是个带存储的异步通信管道
java·开发语言·中间件
Flittly12 小时前
【AgentScope Java新手村系列】(19)多模态-图像音频视频
java·spring boot·spring
Javatutouhouduan12 小时前
国内大厂Java面试高频题库(2026突击版)
java·架构师·java面试·java面试题·后端开发·java程序员·java八股文
Tim_1012 小时前
【C++】017、new/delete与malloc/free的区别
java·数据结构·算法