Allow the cache option to take in of an instance of a redis client that can be shared
# Edit
Please ignore what I said below. I realized with Keyv there is a way to share the redis client as specified in the `@keyv/redis` module. 

```js
const KeyvRedis = require('@keyv/redis');
const Redis = require('ioredis');
const Keyv = require('keyv');

const redis = new Redis('redis://user:pass@localhost:6379');
const keyvRedis = new KeyvRedis(redis);
const keyv = new Keyv({ store: keyvRedis });
```


# This is not an issue anymore, Keyv allows us to share the redis client

The current recommended implementation for caching using redis looks simething like this
```ts
const keyV = new Keyv(process.env.REDIS_URL as string);

const server = new ApolloServer({
  schema,
  cache: new KeyvAdapter(keyV),
  plugins:[responseCachePlugin()],
});
```

However, there is a major problem, if I the developer want to use redis myself, which I currently am with the `graphql-rate-limit-directive` and that takes in Redis as well. The nice thing is, I can just create a redis client myself using `ioredis` and provide it to the configuration. The problem is, having a rate limiter and implementing caching are 2 crucial features for a production-grade and scalable application, and since I am using serverless, I can't just store it in memory because the memory will probably all get losts when the function isn't warm anymore. Therefore I need an external database for caching as do monolithic databases implement as well.

A very obvious problem arises: **To imlement rate limiting and caching, we have 2 instances of the redis client conecting to the exact same server, running at the same time**
This is a wildly inefficient system to have. A solution I propose is to support caching by providing an instance of the redis client directly.

As a developer, I have several difficult choices to make in which I shouldn't be making in my opinion
## Use the in-memory storage for either rate-limiting or caching
This isn't scalable, and in a serverless environment that memory will be lost when the function isn't warm anymore, so it will have to start over again. The data won't persist and the window of usefulness is so niche, I might as well not implement it. Even in a monolithic server, this consumes server resources, which could impact performance unless if the VM is good enough
## Give up implementing either rate limiting or caching
This isn't a viable choice. Not implementing rate limiting exposes my server to the risk of mass requests spam. But at the same time if I give up caching I'm giving up a major feature that can improve user experience 


## Solution
Like the `grahql-rate-limit-directive`, take in a redis client directly in the cache property.

Example:
```js
const server = new ApolloServer({
  schema,
  cache: redisClient,
  plugins:[responseCachePlugin()],
});
```

It appears the most ideal solution is to introduce a plugin that will support the redis client just like how the `keyv` package gets implemented.

