You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying fetch data from redis cluster via openresty nginx + LuaJIT + this module.
I've tried different enviroment (alpine-fat \ stretch \ with and without LuaRocks \ openresty 1.13 - 1.15) and got same error.
Probably trouble with resty.utils, but same config work perfectly at one of physical servers...
Error message:
lua entry thread aborted: runtime error: /usr/local/openresty/lualib/rediscluster.lua:296: attempt to index a nil value
stack traceback:
/usr/local/openresty/lualib/rediscluster.lua:416: in function 'smembers'
/lua/read.lua:34: in function 'r_members'
/lua/read.lua:70: in function 'gatherNightNodes'
/lua/read.lua:208: in function 'dispatcher'
if not res then
ngx.log("Error redis smembers key: " .. key .. "Error: " .. err)
end
return res
--[[
local co = coroutine.create(function (redis, key)
coroutine.yield(redis:smembers(key))
end)
return coroutine.resume(co, redis, key)
]]--
end
local hGetAll = function (redis, key, currentTime)
res, ok = redis:hgetall(key)
-- res, ok = redis:eval("local r = {} local t = {} for i, d in pairs(redis.call('HGETALL', KEYS[1])) do if(math.fmod(i,2) > 0) then t = {i = d, d = nil} else if tonumber(string.sub(d, 1,10)) > tonumber(ARGV[1]) then r[#r+1] = t.i r[#r+1] = d end t = {i = nil, d = nil} end end return r", 1, key, currentTime)
if not res then
return {}
end
return res;
-- return redis:array_to_hash(res)
end
local buildNodes = function (parentNodeKey, members)
local new = {}
for i,v in pairs(members) do new[i] = parentNodeKey .. "-" .. v end
return new
end;
local getNextLevelSmembers = function (redis, nodeType, nodeKey, criteria)
local members = r_members(redis, nodeType .. nodeKey);
if nodeType == "RootNode_" then
if criteria.nights[1] == nil then
return buildNodes(nodeKey, members)
else
return buildNodes(nodeKey, utils.filter(members, function(el) return utils.list_has(criteria.nights, tonumber(el)) end))
end
elseif nodeType == "NightNode_" then
if criteria.resorts[1] == nil then
return buildNodes(nodeKey, members)
else
return buildNodes(nodeKey, utils.filter(members, function(el) return utils.list_has(criteria.resorts, tonumber(el)) end))
end
elseif nodeType == "ResortNode_" then
return members
end
end
local gatherNightNodes = function (redis, rootNode, criteria)
return getNextLevelSmembers(redis, "RootNode_", rootNode, criteria)
end
local gatherResortNodes = function (redis, nightNode, criteria)
return getNextLevelSmembers(redis, "NightNode_", nightNode, criteria)
end
local gatherPriceNodes = function (redis, resortNode, priceNodesCollection, criteria)
local priceBucketFrom = tonumber(criteria.priceRangeFrom) ~= nil and tonumber(criteria.priceRangeFrom) > 0 and math.floor(criteria.priceRangeFrom / 3000) or nil
local priceBucketTo = tonumber(criteria.priceRangeTo) ~= nil and tonumber(criteria.priceRangeTo) > 0 and math.floor(criteria.priceRangeTo / 3000) or nil
local priceNodes = getNextLevelSmembers(redis, "ResortNode_", resortNode, criteria)
for i,v in pairs(priceNodes) do
if (priceBucketFrom == nil or priceBucketFrom <= tonumber(v)) and (priceBucketTo == nil or priceBucketTo >= tonumber(v)) then
if priceNodesCollection[v] == nil then
priceNodesCollection[v] = {}
end
priceNodesCollection[v][#priceNodesCollection[v]+1] = resortNode .. "-" .. v
end
end
return priceNodesCollection
end
local gatherTours = function(redis, priceNodeCollection, criteria, currentTime)
local tours = {}
local count = 0
local nodeTours;
local needExit;
local cycle = 0;
local filteredTour = false
local totalFiltered = 0
local totalPriceNodesRead = 0
local tour = {
identity = nil,
data = {}
}
redis:init_pipeline()
for pool, priceNodePool in priceNodeCollection do
for i, v in ipairs(priceNodePool) do
totalPriceNodesRead = totalPriceNodesRead + 1
redis:hgetall("PriceNode_" .. v)
-- ngx.say("PriceNode_" .. v)
end
end
local nodeBuckets = redis:commit_pipeline()
for i, nodeTours in pairs(nodeBuckets) do
for key, val in pairs(nodeTours) do
local match = {}
if(math.fmod(key,2) > 0) then
tour = {
identity = val,
data = {}
}
else
for s in val:gmatch("([^;]*);?") do
table.insert(tour.data, s)
end
if tonumber(tour.data[1]) < currentTime then
filteredTour = true
-- totalFiltered = totalFiltered + 1
elseif tonumber(criteria.priceRangeFrom) ~= nill and tonumber(criteria.priceRangeTo) ~= nill and tonumber(criteria.priceRangeFrom) > 0 and tonumber(criteria.priceRangeTo) > tonumber(criteria.priceRangeFrom)
and (tonumber(criteria.priceRangeFrom) > tonumber(tour.data[4]) or tonumber(criteria.priceRangeTo) < tonumber(tour.data[4])) then
filteredTour = true
elseif criteria.operators[1] ~= nil and not utils.list_has(criteria.operators, tonumber(tour.data[6])) then
filteredTour = true
elseif criteria.hotels[1] ~= nil and not utils.list_has(criteria.hotels, tonumber(tour.data[3])) then
filteredTour = true
elseif criteria.hotelCategories[1] ~= nil and not utils.list_has(criteria.hotelCategories, tonumber(tour.data[18])) then
filteredTour = true
elseif criteria.meals[1] ~= nil and not utils.list_has(criteria.meals, tonumber(tour.data[17])) then
filteredTour = true
end
if not filteredTour then
tours[#tours+1] = tour
count = count + 1
else
totalFiltered = totalFiltered + 1
end
tour = {
identity = nil,
data = {}
}
filteredTour = false
end
end
end
local dispatcher = function(utils, redis, criteria, currentTime)
local allNightNodes = {}
local allResortNodes = {}
local allPriceNodes = {}
local priceNodesCollection = {}
-- local sortedPriceNodes = {}
for i,v in pairs(criteria.rootNodes) do
allNightNodes = utils.list_extend(allNightNodes, gatherNightNodes(redis, v, criteria) or {})
end
for i,v in pairs(allNightNodes) do
allResortNodes = utils.list_extend(allResortNodes, gatherResortNodes(redis, v, criteria) or {})
end
--for i,v in pairs(allResortNodes) do
--ngx.say(v)
--end
for i,v in pairs(allResortNodes) do
priceNodesCollection = gatherPriceNodes(redis, v, priceNodesCollection, criteria)
end
local toursPerHotels = {}
local tours = gatherTours(redis, utils.sorted(priceNodesCollection, function(a,b) return tonumber(a) < tonumber(b) end), criteria, currentTime)
local sortedTours = {}
for i,v in utils.sorted(tours, function(a,b)
return
tonumber(tours[a].data[4] or 0)
+ tonumber((tours[a].data[7] and tours[a].data[7] ~= '') and tours[a].data[7] or 0)
< tonumber(tours[b].data[4] or 0)
+ tonumber((tours[b].data[7] and tours[b].data[7] ~= '') and tours[b].data[7] or 0)
end) do
if toursPerHotels[v.data[3]] == nil then
toursPerHotels[v.data[3]] = 0
end
if toursPerHotels[v.data[3]] < criteria.toursPerHotelLimit then
sortedTours[#sortedTours+1] = v
toursPerHotels[v.data[3]] = toursPerHotels[v.data[3]] + 1
end
if(#sortedTours >= criteria.limit) then
break
end
end
return sortedTours
--local ok, members = r_members(red_c, "ResortNode_20190308-92-2-2-0-0-11-2162")
--local ok, members = r_members(red_c, "RootNode_" .. request.criteria.rootNodes[1]);
--local members = getNextLevelSmembers(red_c, "RootNode_", request.criteria.rootNodes[1])
--ngx.say(tonumber(request.criteria.priceRangeFrom))
local tours = dispatcher(utils, red_c, request.criteria, currentTime)
--res = red_c:eval("local r = {} local t = {} for i, d in pairs(redis.call('HGETALL', KEYS[1])) do if(math.fmod(i,2) > 0) then t = {i = d, d = nil} else if tonumber(string.sub(d, 1,10)) > tonumber(ARGV[1]) then r[#r+1] = t.i r[#r+1] = d end t = {i = nil, d = nil} end end return r", 1, "PriceNode_20190310-92-2-2-0-0-12-2185-25", currentTime)
--ngx.say(res[2])
--[[
--red_c:init_pipeline()
--red_c:hgetall("PriceNode_20190407-92-2-2-0-0-7-2161-8")
red_c:hgetall("PriceNode_20190407-92-2-2-0-0-8-2162-13")
red_c:hgetall("PriceNode_20190407-92-2-2-0-0-7-2184-13")
local res, err = red_c:commit_pipeline()
if not res then
ngx.log(ngx.ERR, "err: ", err)
else
ngx.say(json.encode(res))
end
--]]
--for i, v in pairs(members) do ngx.print(v .. "\n") end
4) redis_slot.so
gcc redis_slot.c -fPIC -shared -o redis_slot.so
cp redis_slot.so /usr/local/openresty/lualib/
cp rediscluster.lua /usr/local/openresty/lualib/
The text was updated successfully, but these errors were encountered:
I'm trying fetch data from redis cluster via openresty nginx + LuaJIT + this module.
I've tried different enviroment (alpine-fat \ stretch \ with and without LuaRocks \ openresty 1.13 - 1.15) and got same error.
Probably trouble with resty.utils, but same config work perfectly at one of physical servers...
Error message:
lua entry thread aborted: runtime error: /usr/local/openresty/lualib/rediscluster.lua:296: attempt to index a nil value
stack traceback:
/usr/local/openresty/lualib/rediscluster.lua:416: in function 'smembers'
/lua/read.lua:34: in function 'r_members'
/lua/read.lua:70: in function 'gatherNightNodes'
/lua/read.lua:208: in function 'dispatcher'
My last setup:
xiedacon/lua-pretty-json 0.1
fffonion/lua-resty-shdict-server 0.02
xiangnanscu/lua-resty-utils 1.21
openresty/lua-resty-redis 0.25
xiangnanscu/lua-resty-repr 1.0
openresty/lua-resty-lock 0.07
openresty -V
nginx version: openresty/1.15.8.2
built by gcc 8.3.0 (Alpine 8.3.0)
built with OpenSSL 1.1.1c 28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt='-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include' --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.15 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.09 --add-module=../ngx_stream_lua-0.0.7 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib' --with-pcre --with-compat --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-ipv6 --with-mail --with-mail_ssl_module --with-md5-asm --with-pcre-jit --with-sha1-asm --with-stream --with-stream_ssl_module --with-threads --with-stream --with-stream_ssl_preread_module
2) nginx.conf
worker_processes 20;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
lua_shared_dict redis_cluster_slot_locks 100k;
log_format travelata '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $request_time';
server {
listen 80;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.0;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
proxy_set_header Accept-Encoding 'gzip';
access_log /dev/stdout;
error_log /dev/stdout;
location /searchOneThread {
default_type text/html;
content_by_lua_file "/lua/read.lua";
}
location /writeOneThread {
default_type text/html;
content_by_lua_file "/lua/write.lua";
}
location /nginx_status {
stub_status on;
access_log off;
}
}
}
3) content_by_lua_file "/lua/read.lua
local json = require('cjson')
local redis_cluster = require "rediscluster"
local utils = require "resty.utils"
ngx.req.read_body()
local data = ngx.req.get_body_data();
local request = json.decode(data);
local config = {
name = "testCluster", --rediscluster name
serv_list = { --redis cluster node list(host and port),
{ ip = "10.10.6.4", port = 6380 },
{ ip = "10.10.6.4", port = 6381 },
},
--enableSlaveRead = true,
keepalive_timeout = 60000, --redis connection pool idle timeout
keepalive_cons = 1000, --redis connection pool size
connection_timout = 1000, --timeout while connecting
max_redirection = 5, --maximum retry attempts for redirection
}
local red_c = redis_cluster:new(config)
local currentTime = os.time()
--[[
{"criteria":{"operators":[],"hotels":[],"resorts":[],"hotelCategories":[4,7,8,9],"nights":[7,8,9,10,11,12],"priceRangeFrom":6000,"priceRangeTo":1000000,"rootNodes":["20190308-92-2-2-0-0","20190309-92-2-2-0-0","20190310-92-2-2-0-0"],"meals":[],"limit":6000,"toursPerHotelLimit":8}}
]]--
local r_members = function (redis, key)
local res, err = redis:smembers(key)
if not res then
ngx.log("Error redis smembers key: " .. key .. "Error: " .. err)
end
return res
--[[
local co = coroutine.create(function (redis, key)
coroutine.yield(redis:smembers(key))
end)
return coroutine.resume(co, redis, key)
]]--
end
local hGetAll = function (redis, key, currentTime)
res, ok = redis:hgetall(key)
-- res, ok = redis:eval("local r = {} local t = {} for i, d in pairs(redis.call('HGETALL', KEYS[1])) do if(math.fmod(i,2) > 0) then t = {i = d, d = nil} else if tonumber(string.sub(d, 1,10)) > tonumber(ARGV[1]) then r[#r+1] = t.i r[#r+1] = d end t = {i = nil, d = nil} end end return r", 1, key, currentTime)
if not res then
return {}
end
return res;
-- return redis:array_to_hash(res)
end
local buildNodes = function (parentNodeKey, members)
local new = {}
for i,v in pairs(members) do new[i] = parentNodeKey .. "-" .. v end
return new
end;
local getNextLevelSmembers = function (redis, nodeType, nodeKey, criteria)
local members = r_members(redis, nodeType .. nodeKey);
end
local gatherNightNodes = function (redis, rootNode, criteria)
return getNextLevelSmembers(redis, "RootNode_", rootNode, criteria)
end
local gatherResortNodes = function (redis, nightNode, criteria)
return getNextLevelSmembers(redis, "NightNode_", nightNode, criteria)
end
local gatherPriceNodes = function (redis, resortNode, priceNodesCollection, criteria)
local priceBucketFrom = tonumber(criteria.priceRangeFrom) ~= nil and tonumber(criteria.priceRangeFrom) > 0 and math.floor(criteria.priceRangeFrom / 3000) or nil
local priceBucketTo = tonumber(criteria.priceRangeTo) ~= nil and tonumber(criteria.priceRangeTo) > 0 and math.floor(criteria.priceRangeTo / 3000) or nil
local priceNodes = getNextLevelSmembers(redis, "ResortNode_", resortNode, criteria)
for i,v in pairs(priceNodes) do
if (priceBucketFrom == nil or priceBucketFrom <= tonumber(v)) and (priceBucketTo == nil or priceBucketTo >= tonumber(v)) then
if priceNodesCollection[v] == nil then
priceNodesCollection[v] = {}
end
priceNodesCollection[v][#priceNodesCollection[v]+1] = resortNode .. "-" .. v
end
end
return priceNodesCollection
end
local gatherTours = function(redis, priceNodeCollection, criteria, currentTime)
-- ngx.say("PriceNode_" .. v)
end
end
-- totalFiltered = totalFiltered + 1
elseif tonumber(criteria.priceRangeFrom) ~= nill and tonumber(criteria.priceRangeTo) ~= nill and tonumber(criteria.priceRangeFrom) > 0 and tonumber(criteria.priceRangeTo) > tonumber(criteria.priceRangeFrom)
and (tonumber(criteria.priceRangeFrom) > tonumber(tour.data[4]) or tonumber(criteria.priceRangeTo) < tonumber(tour.data[4])) then
filteredTour = true
elseif criteria.operators[1] ~= nil and not utils.list_has(criteria.operators, tonumber(tour.data[6])) then
filteredTour = true
elseif criteria.hotels[1] ~= nil and not utils.list_has(criteria.hotels, tonumber(tour.data[3])) then
filteredTour = true
elseif criteria.hotelCategories[1] ~= nil and not utils.list_has(criteria.hotelCategories, tonumber(tour.data[18])) then
filteredTour = true
elseif criteria.meals[1] ~= nil and not utils.list_has(criteria.meals, tonumber(tour.data[17])) then
filteredTour = true
end
-- ngx.say("Total filtered: " .. totalFiltered)
-- ngx.say("Total price nodes read: " .. totalPriceNodesRead)
return tours
end
local dispatcher = function(utils, redis, criteria, currentTime)
-- local sortedPriceNodes = {}
--for i,v in pairs(allResortNodes) do
--ngx.say(v)
--end
end
--local data, error = red_c:smembers("ResortNode_20190308-92-2-2-0-0-11-2162")
--local ok, members = r_members(red_c, "ResortNode_20190308-92-2-2-0-0-11-2162")
--local ok, members = r_members(red_c, "RootNode_" .. request.criteria.rootNodes[1]);
--local members = getNextLevelSmembers(red_c, "RootNode_", request.criteria.rootNodes[1])
--ngx.say(tonumber(request.criteria.priceRangeFrom))
local tours = dispatcher(utils, red_c, request.criteria, currentTime)
--res = red_c:eval("local r = {} local t = {} for i, d in pairs(redis.call('HGETALL', KEYS[1])) do if(math.fmod(i,2) > 0) then t = {i = d, d = nil} else if tonumber(string.sub(d, 1,10)) > tonumber(ARGV[1]) then r[#r+1] = t.i r[#r+1] = d end t = {i = nil, d = nil} end end return r", 1, "PriceNode_20190310-92-2-2-0-0-12-2185-25", currentTime)
--ngx.say(res[2])
red_c:close()
ngx.say(json.encode(tours))
--ngx.say("Total tours: " .. #tours)
--[[
--red_c:init_pipeline()
--red_c:hgetall("PriceNode_20190407-92-2-2-0-0-7-2161-8")
red_c:hgetall("PriceNode_20190407-92-2-2-0-0-8-2162-13")
red_c:hgetall("PriceNode_20190407-92-2-2-0-0-7-2184-13")
local res, err = red_c:commit_pipeline()
if not res then
ngx.log(ngx.ERR, "err: ", err)
else
ngx.say(json.encode(res))
end
--]]
--for i, v in pairs(members) do ngx.print(v .. "\n") end
4) redis_slot.so
gcc redis_slot.c -fPIC -shared -o redis_slot.so
cp redis_slot.so /usr/local/openresty/lualib/
cp rediscluster.lua /usr/local/openresty/lualib/
The text was updated successfully, but these errors were encountered: