Skip to content

Conversation

@zunnu
Copy link

@zunnu zunnu commented Oct 17, 2024

Support for Redis cluster.

I have included a test file but im not sure how to implement it to the Github actions.
To test this I have used a docker-compose file and I will put it as a comment to this PR.

@zunnu
Copy link
Author

zunnu commented Oct 17, 2024

docker-compose.yml

services:
  php:
    build:
      context: .
      args:
        PHP_MODE: production
    restart: unless-stopped
    volumes:
      - ./:/var/www/html
    depends_on:
      - redis-node-0
      - redis-node-1
      - redis-node-2
      - redis-node-3
      - redis-node-4
      - redis-node-5

  redis-node-0:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_CLUSTER_CREATOR: yes
      REDIS_CLUSTER_REPLICAS: 1
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
    depends_on:
      - redis-node-1
      - redis-node-2
      - redis-node-3
      - redis-node-4
      - redis-node-5

  redis-node-1:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5

  redis-node-2:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5

  redis-node-3:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5

  redis-node-4:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5

  redis-node-5:
    image: bitnami/redis-cluster:latest
    restart: unless-stopped
    environment:
      ALLOW_EMPTY_PASSWORD: yes
      REDIS_NODES: redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5

Edit:
The tests are locked to use specific ip's so the yml maybe should have ip's defined like this.

    networks:
      redis-cluster-net:
        ipv4_address: 172.18.0.7

@dereuromark dereuromark added this to the 5.2.0 milestone Oct 17, 2024
@LordSimal
Copy link
Contributor

LordSimal commented Oct 17, 2024

You can run composer cs-fix to automatically fix the codestyle errors which are present.
To check if codestyle is green, you can do composer cs-check

For stan you need to do a composer stan-setup (you need to have phive installed) and then a composer stan to locally debug and fix the PHPStan/Psalm issues.

Certain stan issues can't be fixed easily, so it may be, that you need to regenerate the baselines for phpstan and psalm composer phpstan-baseline and psalm-baseline

zunnu and others added 2 commits October 17, 2024 17:53
@ADmad
Copy link
Member

ADmad commented Oct 24, 2024

I think the changes to RedisEngine seem good, need to add/update the tests now.

@zunnu
Copy link
Author

zunnu commented Oct 24, 2024

Tests have been updated. There is a separated test for RedisCluster. The main problem with the current version of that test is that it uses static ips. Im not sure how to implement RedisCluster testing to Github actions

Copy link
Member

@markstory markstory left a comment

Choose a reason for hiding this comment

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

Looking good. I left a few comments on test coverage.

}

if ($this->_Redis instanceof RedisCluster) {
foreach ($this->_Redis->_masters() as $masterNode) {
Copy link
Member

Choose a reason for hiding this comment

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

We should have tests for clear + RedisCluster.

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Interesting, I wonder why codecov had those lines flagged as uncovered.

$this->_Redis->setOption(Redis::OPT_SCAN, (string)Redis::SCAN_RETRY);
}

if ($this->_Redis instanceof RedisCluster) {
Copy link
Member

Choose a reason for hiding this comment

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

Another place where we should have some test coverage.

Comment on lines 30 to 35
['host' => '172.18.0.7', 'port' => 6379],
['host' => '172.18.0.2', 'port' => 6379],
['host' => '172.18.0.3', 'port' => 6379],
['host' => '172.18.0.5', 'port' => 6379],
['host' => '172.18.0.4', 'port' => 6379],
['host' => '172.18.0.6', 'port' => 6379],
Copy link
Member

Choose a reason for hiding this comment

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

Do we need a 6 node cluster? Couldn't we make due with a 3 node cluster? No need to waste additional resources.

Copy link
Author

Choose a reason for hiding this comment

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

We don't need 6 nodes 3 is fine this was what I used for testing

@markstory markstory modified the milestones: 5.2.0, 5.3.0 Mar 29, 2025
@dereuromark
Copy link
Member

ping @zunnu Anything left to be done? There seems to be a few conflicts.

@zunnu
Copy link
Author

zunnu commented Jun 5, 2025

I merged #18721 changes into 5.next So if you rebase should be on latest changes then.

Should be good now.

@dereuromark
Copy link
Member

Error: Ignored error pattern #^Comparison operation ">" between (int<0, max>|Redis|false) and 0 results in an error.$# in path /home/runner/work/cakephp/cakephp/src/Cache/Engine/RedisEngine.php was not matched in reported errors.
Error: Ignored error pattern #^Comparison operation ">" between (int|Redis|false) and 0 results in an error.$# in path /home/runner/work/cakephp/cakephp/src/Cache/Engine/RedisEngine.php was not matched in reported errors.
Error: Process completed with exit code 1.

@zunnu
Copy link
Author

zunnu commented Jun 6, 2025

Error: Ignored error pattern #^Comparison operation ">" between (int<0, max>|Redis|false) and 0 results in an error.$# in path /home/runner/work/cakephp/cakephp/src/Cache/Engine/RedisEngine.php was not matched in reported errors. Error: Ignored error pattern #^Comparison operation ">" between (int|Redis|false) and 0 results in an error.$# in path /home/runner/work/cakephp/cakephp/src/Cache/Engine/RedisEngine.php was not matched in reported errors. Error: Process completed with exit code 1.

@dereuromark Done

@zunnu
Copy link
Author

zunnu commented Jun 17, 2025

@dereuromark Anything else to be done or can this be merged?

@dereuromark
Copy link
Member

I wonder what those test fails are

@markstory can maybe sign off.

@LordSimal
Copy link
Contributor

LordSimal commented Jun 17, 2025

@dereuromark seems its related to a PHPUnit change since the 2 collection objects are not "equal" anymore.
I'll get that fixed in a separate PR.

The split package stan issues can be ignored.

@dereuromark
Copy link
Member

ping @zunnu

$keys = $this->_Redis->scan($iterator, $masterNode, $pattern, $scanCount);
$nodes = $this->_Redis instanceof RedisCluster
? $this->_Redis->_masters()
: [null];
Copy link
Member

Choose a reason for hiding this comment

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

Why null and not just empty array or array with string?

Copy link
Author

Choose a reason for hiding this comment

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

The reason for [null] instead of [] or ['some-string'] is to make the loop logic work for both cluster and non-cluster without branching.

If you made $nodes = [] in non-cluster mode, the foreach wouldn’t run at all meaning we would never scan anything.
If you made $nodes = [''] or ['some-string'], the wrapper would have to check for a “fake” node value and ignore it, which is clumsier in my opinion.
By using null im saying we have one logical node to scan in single-node mode, but it has no node address pass null into the wrapper so it knows to call the Redis version of scan.

@dereuromark
Copy link
Member

@nicosp If you are happy with it we can move forward now.

@dereuromark dereuromark merged commit c607a2d into cakephp:5.next Aug 11, 2025
13 checks passed
arshidkv12 pushed a commit to arshidkv12/cakephp that referenced this pull request Sep 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement needs squashing The pull request should be squashed before merging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants