Skip to content

Conversation

@yhayase
Copy link
Owner

@yhayase yhayase commented Nov 6, 2025

This is a test PR to verify the cache-redis-cluster.yml workflow. Will be closed after verification.

hayase_yasuhiro and others added 7 commits November 3, 2025 22:24
The flexible() method was generating keys that could hash to different
slots in Redis Cluster, causing CROSSSLOT errors. This fix adds Redis
hash tags to ensure all related keys (value, created timestamp, and lock)
are stored in the same slot.

Changes:
- Add a 4-character MD5 hash prefix as a hash tag for slot allocation
- Wrap hash in {} to ensure consistent slot placement in Redis Cluster
- Maintain original key structure for non-cluster Redis instances
- Works with both phpredis and predis drivers

This resolves issues with AWS ElastiCache Serverless (Valkey) and other
Redis Cluster environments while remaining backward compatible with
standalone Redis instances.
This adds a new configuration option 'flexible_cluster_mode' that enables
sequential operations in Cache::flexible() for Redis Cluster compatibility.

Implementation:
- When 'flexible_cluster_mode' is enabled, flexible() uses sequential get/put
  operations instead of bulk many()/putMany() operations
- This avoids CROSSSLOT errors in Redis Cluster environments where keys hash
  to different slots
- Default is false to maintain existing behavior

Configuration (config/cache.php):
```php
'stores' => [
    'redis' => [
        'driver' => 'redis',
        'flexible_cluster_mode' => env('CACHE_FLEXIBLE_CLUSTER_MODE', false),
    ],
],
```

Trade-offs:
- Sequential mode: 2 network round-trips instead of 1
- Performance impact is minimal since flexible() callback execution dominates
- This approach already exists for putMany() in cluster connections

All tests pass (75 tests, 302 assertions).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Repository::flexible() references the flexible_cluster_mode config,
but CacheManager::repository() was using Arr::only($config, ['store']),
which prevented flexible_cluster_mode from being passed to Repository.

Changes:
- Modified Arr::only($config, ['store', 'flexible_cluster_mode'])
- This ensures flexible_cluster_mode config is properly passed to Repository

Test results:
- Local: 75 tests, 302 assertions all passed
- Valkey Serverless: 3/3 patterns all succeeded
  - phpredis + default: SUCCESS
  - predis + default: SUCCESS
  - predis + clusters: SUCCESS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Use INFO cluster command to detect if Redis server has cluster mode
enabled, instead of relying on configuration or connection type.

This approach works for AWS ElastiCache Serverless (Valkey) where
the server has cluster_enabled:1 but provides only a single endpoint,
requiring single-node connection mode.

Changes:
- Add detectClusterEnabled() method to check server cluster status
- Check PhpRedisClusterConnection/PredisClusterConnection first
- For single-node connections, query INFO cluster command
- Cache result per Repository instance in $clusterEnabled property
- Use sequential operations (get/put) instead of bulk (many/putMany)
  when cluster mode is detected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants