Skip to content

Not reproducible compression results with LZ4 #1939

@TheLevti

Description

@TheLevti

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

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions