[13.x] Fix Redis tagged cache flush blocking Redis when flushing many tags

Merged
MO
8d ago
+118-17

Currently, "RedisTaggedCache::flush()" passes all tag IDs to the Lua script for every batch of keys. With many tags, Redis ends up running "ZREM" against tags that don't contain those keys. This can block Redis long enough to trigger "BUSY" errors, as reported in #62212.

This changes the flush to process each tag separately, passing only that tag's keys and ID to the existing Lua script.

With 1,000 keys and 2,001 tags, the flush time dropped from 1,958 ms to 58 ms in my local benchmark.

I also added tests covering the script arguments and shared keys being rewritten during a flush. All cache tests pass with both phpredis and Predis.