Redis 集群 lua 实现
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,二话不说,直接上货.多多交流哈,谢谢各路大神..重点就是下面这段:Object object = redisTemplate.execute(redisUpdateOrderScript,//这里有k
千家信息网最后更新 2026年11月04日Redis 集群 lua 实现
二话不说,直接上货.多多交流哈,谢谢各路大神.
.
重点就是下面这段:
Object object = redisTemplate.execute(redisUpdateOrderScript,//这里有key 要像官网说的那样加个"{}",不然就报错了,这里3个key都要前缀一致Arrays.asList(hkey, amountKey, key),//值无要求amount.longValueExact(),price.doubleValue(),price.doubleValue());我自己的理解是,执行脚本和执行hget 是一样的,只是lua脚本内容由Redis执行,但发送命令的要求是一样的.所以上面3个key 都得加一样的前缀.
.
.
.
业务逻辑是这样子的:
把20档盘口放到Redis里面
1.用有序集合(sorted set)进行自动价格排序
ZADD key 0.0354 "0.0354"2.然后再根据价格到hash里去取值,取的val 就是这个价格的下单量
HGET key 0.0354java 代码
加盘口
public void addOrderForLua(BeforeMatchDTO model) { //缓存失效 redisService.remove(RedisService.getPositionKey(model.getContract())); BigDecimal price = model.getPrice(); BigDecimal amount = model.getAmount().multiply(PRECISION_DOUBLE); String key = RedisKeyGen.getContractPositionZsetKey(model.getContract(), model.getDirection()); log.info("getContractPositionZsetKey:{}",key); String hkey = RedisKeyGen.getContractPositionHashKey(model.getContract(), model.getDirection()); log.info("getContractPositionHashKey:{}",hkey); String amountKey = RedisKeyGen.getContractPositionAmountKey(model.getContract(),price.stripTrailingZeros().toPlainString()); log.info("getContractPositionAmountKey:{}",amountKey); log.info("addOrderForLua contract:{}, value:{}", model.getContract(), amount.longValueExact()); Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amount.longValueExact(),price.doubleValue(),price.doubleValue()); log.info("addOrderForLua" + object); }减盘口
public void subOrderForLua(String contract,BigDecimal price,BigDecimal amount,int direction) { //缓存失效 redisService.remove(RedisService.getPositionKey(contract)); String key = RedisKeyGen.getContractPositionZsetKey(contract, direction); log.info("getContractPositionZsetKey:{}",key); String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction); log.info("getContractPositionHashKey:{}",hkey); String amountKey = RedisKeyGen.getContractPositionAmountKey(contract,price.stripTrailingZeros().toPlainString()); log.info("getContractPositionAmountKey:{}",amountKey); log.info("subOrderForLua contract:{}, value:{}", contract, amount.doubleValue()); BigDecimal amountTag = amount.multiply(PRECISION_DOUBLE).negate(); //转成负数 Object nowAmount = redisService.hmGet(hkey, price.toPlainString()); log.info("subOrderForLua nowAmount:{},direction:{}", nowAmount, direction); Object object = redisTemplate.execute(redisUpdateOrderScript, Arrays.asList(hkey, amountKey, key), amountTag.longValueExact(),price.doubleValue(),price.doubleValue()); log.info("subOrderForLua" + object); }查询(重点看取值的地方,转换请忽略)
public List query(String contract,int direction) { List result = new ArrayList<>(); String key = RedisKeyGen.getContractPositionZsetKey(contract, direction); log.info("getContractPositionZsetKey:{}",key); String hkey = RedisKeyGen.getContractPositionHashKey(contract, direction); log.info("getContractPositionHashKey:{}",hkey); Set key 生成
public static final String getContractPositionZsetKey(String contract,int direction){ return "{POSITION:"+contract+"}.POSITION-ORDER-" + contract + "-" + direction; } public static final String getContractPositionHashKey(String contract,int direction){ return "{POSITION:"+contract+"}.POSITION-ORDER-VAL-" + contract + "-" + direction; } public static final String getContractPositionAmountKey(String contract,String amount){ return "{POSITION:"+contract+"}." + amount; }lua 脚本
local val1 = '"'local valAmount = redis.call('hget',KEYS[1],KEYS[2])if not valAmount then redis.pcall('hset',KEYS[1],KEYS[2],ARGV[1]) if tonumber(ARGV[1]) > 0 then local val2 = val1 .. ARGV[3] .. val1 return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2) else return 1 endelse local tagAmount = tonumber(valAmount) + ARGV[1] redis.pcall('hset',KEYS[1],KEYS[2],tagAmount) local val2 = val1 .. ARGV[3] .. val1 local zset = redis.pcall('ZRANK', KEYS[3], val2) if tagAmount <= 0 then if not zset then return 1 else return redis.pcall('ZREMRANGEBYSCORE', KEYS[3], tonumber(ARGV[2]), tonumber(ARGV[2])) end else if not zset then local val2 = val1 .. ARGV[3] .. val1 return redis.pcall('ZADD', KEYS[3], tonumber(ARGV[2]), val2) else return 1 end endend
价格
盘口
脚本
前缀
就是
缓存
重点
有序
一致
二话不说
业务
二话
代码
内容
只是
命令
地方
大神
样子
负数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技的发展
致骋互联网科技
世界互联网领先科技成果
安徽鑫晟辉互联网科技
互联网科技咨询
国外互联网科技网站
农村开互联网科技讲堂
互联网金融中的现代科技
花神(南京)互联网科技有限公司
爱医互联网络科技
元气玛特互联网科技公司是外包吗
郑州欣桑互联网科技有限公司
易企秀互联网科技是做什么的
新氧科技和美国互联网有关系吗
信承诺互联网科技有限公司
中国科技和美国互联网
张家口科技产业互联网平台
互联网科技博主张洲
前海云享互联网科技
武汉亿视互联网科技有限公司
深圳互联网科技公司
银优互联网科技有限公司
互联网金融科技平台
互联网科技上市公司
互联网教育科技公司vipkid
重庆威客帮互联网科技
消费医药和互联网科技
无锡工业互联网科技有限公司
互联网科技融合创新
济南小医互联网科技有限公司招聘