Redis 集群 lua 实现
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,二话不说,直接上货.多多交流哈,谢谢各路大神..重点就是下面这段:Object object = redisTemplate.execute(redisUpdateOrderScript,//这里有k
千家信息网最后更新 2025年12月03日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安全错误
数据库的锁怎样保障安全
vb程序中怎么读出数据库中
部队国家网络安全周
linux服务器权限设置
宁海计算机软件开发公司
网络安全法关于网络安全的规定
天安杯 信息通信网络安全
山西网络安全文件
5G基带嵌入式软件开发
网络安全认证都有啥
协作机器人的自重软件开发
java怎么删除数据库的内容
尝试连接服务器时出错
nova9升级连接不到服务器
国内镜像服务器
网络安全的系统层安全
上海软件开发贵阳
组装服务器需要购买什么
网络安全法自何时实施
软件开发干不下来
浪潮数据库服务器
轻松筹 互联网大会科技
知网的英文数据库有哪些
青浦区项目软件开发服务保障
加强涉密网络安全保护
大专软件开发这个专业好吗
魔兽怀旧服如何看服务器
接收服务器内型
网络营销软件开发定制好处
商务通服务器版
网络安全专科班