Skip to content

[Cache] invalidating tags breaks after updating to symfony/cache 5.3.3 with Redis versions below 5.x #42126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jordikroon opened this issue Jul 15, 2021 · 3 comments · Fixed by #43158

Comments

@jordikroon
Copy link

jordikroon commented Jul 15, 2021

symfony/cache: 5.3.3

Description
We are using a Redis version prior to Redis 5.x, Redis 3.2 to be precise. After upgrading the symfony/cache package to 5.3.3 we are experiencing a problem with flushing tags.

RedisException
ERR Error running script (call to f_cea3ea3b59f1b3411febbbeb5f94de8a695cec73): @user_script:19: @user_script: 19: Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode.

How to reproduce

  • Upgrade symfony/cache to 5.3.3
  • Execute:
$redis = new \Redis();
$redis->connect($_ENV['REDIS_SERVER'], $_ENV['REDIS_PORT']);
$redis->select((int) $_ENV['REDIS_DATABASE']);

$cachePool = new RedisTagAwareAdapter($redis, 'cacheable');
$cachePool->invalidateTags($tags);

This will trigger an error.

Cannot use object of type RedisException as array

To reveal the real exception, add to symfony/cache/Adapter/RedisTagAwareAdapter.php:244 (after EOLUA;):

foreach ($results as $id => $values) {
  if ($values instanceof \RedisException) {
      throw $values;
  }
}

Possible Solution

In order to enable script effects replication, you need to issue the following Lua command before any write operated by the script:
redis.replicate_commands()
The function returns true if the script effects replication was enabled, otherwise if the function was called after the script already called some write command, it returns false, and normal whole script replication is used

Another possible solution is to update ext-redis requirements to 5.x. Though this will be a BC break

Additional context
https://redis.io/commands/eval#replicating-commands-instead-of-scripts

@jordikroon jordikroon added the Bug label Jul 15, 2021
@jordikroon jordikroon changed the title [Cache] [Cache] invalidating tags breaks after updating to symfony/cache 5.3.3 with Redis versions below 5.x Jul 15, 2021
@stof
Copy link
Member

stof commented Jul 15, 2021

* Upgrade symfony/cache to 5.3.3

Upgrading from which version that was not affected ?

@jordikroon
Copy link
Author

@stof We upgraded from 5.3.0 to 5.3.3. Also considering the release notes, I am pretty confident that #41804 is causing this error. Because the change adds a flush using LUA.

bug #41804 fix eventual consistency when using RedisTagAwareAdapter with a cluster (nicolas-grekas)

@nicolas-grekas
Copy link
Member

Would you mind sending a fix @jordikroon?

@wouterj wouterj linked a pull request Sep 24, 2021 that will close this issue
@fabpot fabpot closed this as completed Sep 26, 2021
fabpot added a commit that referenced this issue Sep 26, 2021
This PR was merged into the 4.4 branch.

Discussion
----------

[Cache] Fix invalidating tags on Redis <5

| Q             | A
| ------------- | ---
| Branch?       | 5.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #42126
| License       | MIT
| Doc PR        | -

https://redis.io/commands/eval#replicating-commands-instead-of-scripts

> Note: starting with Redis 5, the replication method described in this section (scripts effects replication) is the default and does not need to be explicitly enabled.
>
> Starting with Redis 3.2, it is possible to select an alternative replication method. Instead of replicating whole scripts, we can just replicate single write commands generated by the script. We call this script effects replication.
>
> To enable script effects replication you need to issue the following Lua command before the script performs a write:
>
> ```
> redis.replicate_commands()
> ```

Commits
-------

fda7e7e Fix Redis replication on Redis <5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants