I am trying to implement a read heavy operation in Redis. I have loaded a function in redis server to read all the data. Now when I compare the performance of reading data by calling the function vs using lettuce library, the library gives better performance. Can someone help me understand why.
The first approach using redis function is implemented as follows:
#!lua name=fetch
redis.register_function(
'fetch',
function(keys, args)
local cursor = '0'
local result = {}
local resultIndex = 0
repeat
local keys = redis.call('SCAN', cursor, 'MATCH', args[1], 'COUNT', 7000)
local keysIndex = 0
local values = redis.call('mget', unpack(keys[2]))
for i, value in ipairs(values) do
local data = {keys[2][keysIndex], value}
result[resultIndex] = data
resultIndex = resultIndex + 1
keysIndex = keysIndex + 1
end
cursor = keys[1]
until cursor == '0'
return result
end)
This is the redis function. I am calling this function using lettuce reactive command like
reactiveCommands.fcall("fetch", ScriptOutputType.MULTI, new String[0], "*")
Another approach is by using only lettuce libraries:
List<String> keys = new ArrayList<>();
KeyScanCursor<String> scan = reactiveCommands.scan(ScanCursor.INITIAL, ScanArgs.Builder.limit(100000).match("*")).block();
while(scan != null && scan.getCUrsor().equalIgnoreCase(ScanCursor.INITIAL.getCursor())) {
keys.addAll(scan.getKeys());
scan = reactiveCommands.scan(ScanCursor.of(scan.getCursor()), ScanArgs.Builder.limit(100000).match("*")).block();
}
if(scan != null)
keys.addAll(scan.getKeys())
reactiveCommands.mget(keys.toArray(new String[0])).collectList().block();
With Redis function implementation, it makes only one network call to invoke the function but Java implementation makes multiple network calls. So, I assumed Redis implementation will be faster. But while testing, java implementation gives better performance.