redis+lua

redis调用lua

E:\redis\Redis-x64-3.2.100\redis-cli.exe --eval redis_test.lua test_set 1

方便测试

上面命令中的1表示有几个key这里只有一个key 所以lua代码中只能用KEY[1]获取
KEY[1]=ip:1213

逗号,表示分割KEY和ARGV

##linux 系统时间可能同步的位置
systemctl status systemd-timesyncd
关闭它

E:\lua>E:\redis\Redis-x64-3.2.100\redis-cli.exe --eval buyer.lua sjs_sell_800001 sjs_buy_800001 2 , 800001 buy000001 30 10 1121214343 1 sjs

成交的lua函数

local function split(str,delimiter)
    local dLen = string.len(delimiter)
    local newDeli = ''
    for i=1,dLen,1 do
        newDeli = newDeli .. "["..string.sub(delimiter,i,i).."]"
    end

    local locaStart,locaEnd = string.find(str,newDeli)
    local arr = {}
    local n = 1
    while locaStart ~= nil
    do
        if locaStart>0 then
            arr[n] = string.sub(str,1,locaStart-1)
            n = n + 1
        end

        str = string.sub(str,locaEnd+1,string.len(str))
        locaStart,locaEnd = string.find(str,newDeli)
    end
    if str ~= nil then
        arr[n] = str
    end
    return arr
end


-- 买单lua 为挂买单准备----arg 
-- cs.setInt(1, investorsCode);
-- cs.setInt(2, recordOrderId);
-- cs.setInt(3, buyerOrderPrice);
-- cs.setInt(4, buyerOrderNum);
-- cs.setString(5, buyerOrderDate);

-- key1 为卖单key  key2为买单key
-- sortedset price sjs_buyer_orderId_buyernum



local TRANSACTION_price=0;
local order_price_found = 0;
local order_num_found=0;
local order_id_found=0;
local tmp_num = 0;
local buy_only_part = 0;
local done = 0;

--返回的结果
local p_result='';

--index控制
local key_index=0;
local sell_num=0;
-- 默认为5档撮合
local step=4;
local whileFlag= 0

--参数
local sell_key=KEYS[1]
local buy_key=KEYS[2]
local investorsCode = ARGV[1]
local recordOrderId=ARGV[2]
local buyerOrderPrice=ARGV[3]+0
local buyerOrderNum = ARGV[4]+0
local buyerOrderDate = ARGV[5]
local check = ARGV[6]+0
local app=ARGV[7]


-- sjs_sell_800001  sjs_800001_121313time_sell000001_20   zadd 30 sjs_800001_time121313_sell000001_20
local buyer_order_key_pre = app.."_"..investorsCode.."_"..buyerOrderDate.."_"..recordOrderId


-- check为0 强制检查是否和数据库未同步
local sell_count=redis.call("zcard",KEYS[1])
if (sell_count==0 and check==0)
then
	p_result="-1"
-- 如果check=1 则表示不强制检查数据库
else
	while(whileFlag==0)
		do

			local beginIndex = key_index;
			local endIndex=key_index+step
			--从大到小
			local list=redis.call("zrange",KEYS[1],beginIndex,endIndex);
			local list_sell_count=#list
			if (list_sell_count==0)
			then
				--退出
				whileFlag=1 
			end
			for k,v in pairs(list) do
				--价格必须满足条件
				local sell_price=redis.call("zscore",KEYS[1],v)+0
				if (sell_price>buyerOrderPrice)
				then
					--没有可成交的单了
					whileFlag=1
					break
				else
					local params=split(v,"_")
					-- get the last index of the table
					local s_num=params[#params]
					local s_id=params[#params-1]

					sell_num=sell_num+tonumber(s_num)
					--满足了买单,卖单部分成交
					if (sell_num>buyerOrderNum)
					then
						--分拆卖单--移除最后一个元素
						local v_part=params
						table.remove(v_part)
						--计算分拆结果
						local remain_sell=sell_num-buyerOrderNum
						table.insert(v_part,remain_sell)
						local last_part=table.concat(v_part,"_")
						--删除以前的单
						redis.call("zrem",sell_key,v)
						redis.call("zadd",sell_key,sell_price,last_part)
						local get_sell=s_num-remain_sell
						p_result=p_result..","..s_id..","..get_sell..","..sell_price
						whileFlag=1
						break
					elseif(sell_num==buyerOrderNum)
					then
						--刚好完成订单--删除以前的单
						redis.call("zrem",sell_key,v)
						p_result=p_result..","..s_id..","..s_num..","..sell_price
						whileFlag=1
						break
					else
						--买单大于卖单
						redis.call("zrem",sell_key,v)
						p_result=p_result..","..s_id..","..s_num..","..sell_price
					end
				end
			end
			-- 是否还有数据,如果没有退出
			if (list_sell_count<5)
			then
				--没有足够的卖单
				whileFlag=1
				break
			end
			key_index=endIndex+1
	end
	-- 查看是否需要把买单放入缓存
	if (buyerOrderNum>sell_num)
	then
		buy_only_part=1
		local remain_buy=buyerOrderNum-sell_num
		local buyer_order_key=buyer_order_key_pre.."_"..remain_buy
		redis.call("zadd",buy_key,buyerOrderPrice,buyer_order_key)
	end

end
--结束标记
p_result=p_result.."#"..buy_only_part
--返回结果
return p_result

猜你喜欢

转载自blog.csdn.net/qq_30845665/article/details/88197020