-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
I just tested the LZ4 and ZSTD compression options against the REDLOCK algorithm with the laravel cache lock library and it seems like I have the same problem as in #1477. ZSTD worked out of the box with different compression levels.
For LZ4 I am not able to get the same result by calling lz4_compress($string, $compressionLevel) with any compression level. Most of the time the difference is the first byte, which seems to be off.
With compression level 0 (default lz4), I get the following result:
1614439016.383115 [0 10.150.2.1:56450] "SET" "laravel_database_laravel_cache:foo" "\xef\x10\x00\x00\x00\xf0\x011r2fM79GOE1goTTj" "EX" "10" "NX"
1614439016.383433 [0 10.150.2.1:56450] "EVAL" "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n return redis.call(\"del\",KEYS[1])\nelse\n return 0\nend" "1" "laravel_database_laravel_cache:foo" "\x10\x00\x00\x00\xf0\x011r2fM79GOE1goTTj"
1614439016.383451 [0 lua] "get" "laravel_database_laravel_cache:foo"
As you can see the first SET and the EVAL ARGV[1] should be the same, they are but just the first view bytes are different. For the redlock algorithm the user needs to serialize/compress the arguments himself for the EVAL to work, because phpredis is not doing that for the user. For LZF, ZSTD it works fine. As a result the key is never deleted and thus the lock never released until it times out.
Expected behaviour
1614439016.383115 [0 10.150.2.1:56450] "SET" "laravel_database_laravel_cache:foo" "\xef\x10\x00\x00\x00\xf0\x011r2fM79GOE1goTTj" "EX" "10" "NX"
and
1614439016.383433 [0 10.150.2.1:56450] "EVAL" "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n return redis.call(\"del\",KEYS[1])\nelse\n return 0\nend" "1" "laravel_database_laravel_cache:foo" "\x10\x00\x00\x00\xf0\x011r2fM79GOE1goTTj"
should have the same value.
Actual behaviour
phpredis compresses the string differently than the php extension lz4 by calling lz4_compress. (https://github.com/kjdev/php-ext-lz4).
I'm seeing this behaviour on
- OS: Ubuntu 20.04
- Redis: 5.0.9
- PHP: 8.0.2
- phpredis: 5.3.3
Steps to reproduce, backtrace or example script
This is the EVAL script that is running to remove the locked key. See #1477 for examples.
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
``
### I've checked
- [x] There is no similar issue from other users
- [x] Issue isn't fixed in `develop` branch