Symfony PSR-16 Redis缓存跨类型查询可行性咨询
Great question! Let’s break down how to approach this—Symfony’s Cache component does have some limitations here, but you don’t necessarily need to build a full separate Redis service to make it work.
First, The Limitation of Symfony’s PSR-16 Cache
Symfony’s Cache implementation follows the PSR-16 standard, which is built for simple key-value operations (get, set, delete, etc.). It doesn’t include native support for scanning or iterating over keys in the cache pool. That’s intentional: PSR-16 is designed to be storage-agnostic (it could work with Redis, filesystem, or other backends), so key-scanning isn’t part of its core interface.
But You Can Use the Underlying Redis Client
Luckily, when you’re using the Redis adapter for Symfony Cache, the pool wraps a real Redis client (either phpredis or Predis). You can grab that client directly to run Redis-native commands like SCAN (way safer than KEYS for production) to find all your hash.[哈希值] keys.
Here’s a practical example of how to pull this off:
// Inject your CacheItemPoolInterface via Symfony's dependency injection public function processCacheRecords(CacheItemPoolInterface $cachePool) { // Get the raw Redis client from the Symfony Cache adapter $redisClient = $cachePool->getAdapter()->getClient(); // Use SCAN to safely iterate over keys matching "hash.*" $iterator = null; do { // Scan for keys matching our pattern $scanResult = $redisClient->scan($iterator, 'hash.*'); if ($scanResult === false) { break; } foreach ($scanResult as $hashKey) { // Fetch the primary key from the first cache type $primaryKey = $cachePool->get($hashKey); if ($primaryKey === null) { continue; // Skip if the key expired or was deleted } // Build the second type of key (adjust table name logic to fit your setup!) // Note: You’ll need to map hash keys to their table names—this example assumes a fixed table $tableKey = "your_target_table.$primaryKey"; // Fetch the corresponding record from the second cache type $recordData = $cachePool->get($tableKey); // Process the record data as needed here } } while ($iterator > 0); }
Key Notes to Keep In Mind:
- Always use
SCANinstead ofKEYS:KEYSblocks your Redis server while it scans the entire keyspace, which is a production killer.SCANworks incrementally and avoids downtime. - Table Name Mapping: Your first cache type only stores the primary key—you’ll need a way to know which table that key belongs to. If your hash keys include the table name (e.g.,
hash.users.[哈希值]), parse it from the key. Otherwise, store an additional mapping (like a separate Redis hash) to link hash values to table names.
When to Build a Direct Redis Service
If you find yourself needing more complex Redis operations (like pipelining, transactions, or advanced data structure manipulations) that don’t fit neatly with Symfony’s Cache abstraction, then building a dedicated Redis service makes sense. This gives you full control over Redis commands without relying on the Cache component’s wrapper.
But for your specific use case, leveraging the underlying client from Symfony’s Cache pool is totally viable—it keeps you aligned with Symfony’s existing caching setup while letting you do the key-scanning you need.
内容的提问来源于stack exchange,提问作者super.t

