Split the memory and Redis cache implementations into separate files and provide backend-native atomic set-if-absent support.