Skip to content
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

[Cache] Improve RedisTagAwareAdapter invalidation logic & requirements #33461

Merged

Conversation

andrerom
Copy link
Contributor

@andrerom andrerom commented Sep 4, 2019

Q A
Branch? 4.4
Bug fix? yes, and improvment
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
License MIT
Doc PR

Changes logic of invalidation in RedisTagAwareAdapter in order to:

  • Delete the tag key on invalidation => avoiding possible left behind empty tag keys that Redis is not allowed to evict, gradually consuming slightly more memory

Positive side effects of no longer using sPOP:

  • Lowered requirements to Redis 2.8, and no specific version constraint for phpredis
  • Lift limitation of 2 billion keys per tag (Now only limited by Redis Set datatype: 4 billion)

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cool!
A hypothetical future step could be to schedule the cleanups using Messenger :)

@andrerom
Copy link
Contributor Author

andrerom commented Sep 5, 2019

Some setbacks here, clients are not so complete:

  • RedisArray does not support SSCAN, you'll get:
    Parameter 2 to Redis::sscan() expected to be a reference, value given
  • Predis alos have limited SSCAN and gives the following if key does not exists:
    Predis\Response\ServerException: ERR no such key

These can potentially be fixed by instead using SMEMBERS + skipping SSCAN/SMEMBERS on tagId if RENAME returned 0 (not found in this case).

More of a Server issue:

  • Cluster on Predis and RedisCluster does not support RENAME:
    RedisCluster::rename(): Keys don't hash to the same slot

This one I'm unsure of, should we try to make sure we RENAME within same node?

Suggestions @nicolas-grekas / @berezuev?

@nicolas-grekas
Copy link
Member

Can't we rename to a key that will be guaranteed on the same node, using the special syntax they support for this?

@andrerom
Copy link
Contributor Author

andrerom commented Sep 5, 2019

using the special syntax they support for this?

Do you happen to remember where that is described? Thought about that too, but didn't know where to look.

@nicolas-grekas nicolas-grekas added this to the next milestone Sep 6, 2019
@nicolas-grekas
Copy link
Member

Sure, see https://redis.io/topics/cluster-spec, the section about "hash tags"

@stof
Copy link
Member

stof commented Sep 6, 2019

is it possible to have { and } in our normal tagId Redis keys ? If yes, we won't be able to use hash tags to achieve our goal.
Otherwise, this can indeed by used, making the temporary tag id being '{'.$tagId.'}'.$randomSuffix instead of $tagId.':'.$randomSuffix.

@andrerom

This comment has been minimized.

@nicolas-grekas
Copy link
Member

The alternative could be to talk directly to the corresponding node in the cluster. That's possible AFAIK.

@andrerom

This comment has been minimized.

@nicolas-grekas
Copy link
Member

I think there is a function for that :)
Happy 🌴 !

@andrerom andrerom force-pushed the improved_tagaware_redis_adapter branch 3 times, most recently from e264119 to e2c430b Compare September 22, 2019 18:46
@andrerom
Copy link
Contributor Author

andrerom commented Sep 22, 2019

RedisCluster failure was fixed in be04079. I did not find a simple way to deal with RENAME on Predis across RedisCluster & PredisCluster so left that as-is, could instead use SPOP there if prefered.

AppVeyor failure seems unrelated (HttpClient\Tests\NativeHttpClientTest::testNotATimeout), so rebased and moving this to review.

@andrerom andrerom marked this pull request as ready for review September 22, 2019 19:29
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rebase, you've been caught by fabbot :)

@andrerom andrerom force-pushed the improved_tagaware_redis_adapter branch from cbc72b7 to f9e47ba Compare September 25, 2019 16:08
@andrerom
Copy link
Contributor Author

let's throw for now in this situation and open an issue on Predis?

last commit 2017...

@nicolas-grekas
Copy link
Member

Another reason to throw and encourage using phpredis...
Let's still create the issue for the record...

@fabpot
Copy link
Member

fabpot commented Sep 27, 2019

Mergeable?

@andrerom
Copy link
Contributor Author

IMHO Yes, we can do the improvements as a follow up, it will anyway need some investigation and testing. But it's entirely up to you two.

@nicolas-grekas
Copy link
Member

I'd prefer doing it in this PR, depending on your availability to do it :)

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Oct 7, 2019

Hello, I just push-forced this here:
https://github.com/symfony/symfony/compare/db80b9db0519ec73165b9bc2d57674993c7a3d5e..28948eeb8b

Should fix the last comment.

@nicolas-grekas nicolas-grekas force-pushed the improved_tagaware_redis_adapter branch 3 times, most recently from e28a53e to 28948ee Compare October 7, 2019 16:58
Copy link
Contributor Author

@andrerom andrerom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 Looks good to me 👍

Further improvements here depends on future improvements in Predis if anyone is up for the tasks:

  1. Exception on rename on missing key (should align with phpredis: false response when missing)
  2. Lack of api to find slot of key when using RedisCluster class (should also be added to ClusterInterface, based on implementation in PredisCluster class)

@nicolas-grekas
Copy link
Member

Exception on rename on missing key

Actually, I just discovered this is already possible! PR updated to use pipelining.

Lack of api to find slot of key when using RedisCluster

that's a bit more involving, as that'd require implementing the logic to react to MOVE responses. Should be handled at the Predis level instead, as phpredis does.

@nicolas-grekas nicolas-grekas force-pushed the improved_tagaware_redis_adapter branch 2 times, most recently from 67d569d to 5ece961 Compare October 8, 2019 09:53
@nicolas-grekas
Copy link
Member

Thank you @andrerom.

nicolas-grekas added a commit that referenced this pull request Oct 8, 2019
…c & requirements (andrerom)

This PR was merged into the 4.4 branch.

Discussion
----------

[Cache] Improve RedisTagAwareAdapter invalidation logic & requirements

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes, _and improvment_
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| License       | MIT
| Doc PR        |

Changes logic of invalidation in RedisTagAwareAdapter in order to:
- Delete the  tag key on invalidation => _avoiding possible left behind empty tag keys that Redis is not allowed to evict, gradually consuming more and more memory_

Positive side effects of no longer using sPOP:
- Lowered requirements to Redis 2.8, and no specific version constraint for phpredis
- Lift limitation of 2 billion keys per tag _(Now only limited by Redis Set datatype: 4 billion)_

Commits
-------

3d38c58 [Cache] Improve RedisTagAwareAdapter invalidation logic & requirements
@nicolas-grekas nicolas-grekas merged commit 3d38c58 into symfony:4.4 Oct 8, 2019
@andrerom andrerom deleted the improved_tagaware_redis_adapter branch October 8, 2019 10:46
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.4 Oct 27, 2019
This was referenced Nov 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants