Redis 集群 lua 实现
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,二话不说,直接上货.多多交流哈,谢谢各路大神..重点就是下面这段:Object object = redisTemplate.execute(redisUpdateOrderScript,//这里有k
千家信息网最后更新 2025年02月01日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.0354
java 代码
加盘口
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安全错误
数据库的锁怎样保障安全
分析数据库的工作原理
数据库闭源
geo数据库自带的分析
上海网络技术应用研究所待遇
河南瑞日网络技术有限公司
智能矿山网络安全加密
政府完善网络安全
c 向线程传数据库
网络安全大会上海
南宁软件开发外包怎么做好
曹剑楠网络安全
网络安全手抄报简单漂亮字少
档案管理软件开发方案
蚌埠市钰淼网络技术有限公司
英文期刊数据库
蓝阔打印服务器管理
闵行区工商软件开发厂家价格
钢铁雄心4服务器
软件开发平台龙头
可靠的数据库水印溯源
吃鸡游戏服务器密码是多少
导出非本地数据库
我的世界云服务器怎么玩手机版
爱丽丝服务器
服务器上管理员权限
鸿蒙应用用什么软件开发
个人网络安全培训心得
svn跨服务器备份
简述数据库结构设计
新华互联网科技专场