Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
@keyv/redis
Advanced tools
@keyv/redis is an npm package that provides a Redis storage adapter for Keyv, a simple key-value storage library. It allows you to use Redis as a backend for storing key-value pairs, making it easy to integrate Redis into your Node.js applications.
Basic Key-Value Storage
This feature allows you to store and retrieve basic key-value pairs using Redis as the backend. The code sample demonstrates how to set and get a value from the Redis store.
const Keyv = require('keyv');
const keyv = new Keyv('redis://user:pass@localhost:6379');
(async () => {
await keyv.set('foo', 'bar');
const value = await keyv.get('foo');
console.log(value); // 'bar'
})();
Expiration of Keys
This feature allows you to set an expiration time for keys. The code sample demonstrates how to set a key with an expiration time and shows that the key is no longer available after the specified time.
const Keyv = require('keyv');
const keyv = new Keyv('redis://user:pass@localhost:6379');
(async () => {
await keyv.set('foo', 'bar', 1000); // Expires in 1 second
setTimeout(async () => {
const value = await keyv.get('foo');
console.log(value); // undefined
}, 1500);
})();
Namespace Support
This feature allows you to use namespaces to avoid key collisions. The code sample demonstrates how to set and get a value within a specific namespace.
const Keyv = require('keyv');
const keyv = new Keyv({ uri: 'redis://user:pass@localhost:6379', namespace: 'myapp' });
(async () => {
await keyv.set('foo', 'bar');
const value = await keyv.get('foo');
console.log(value); // 'bar'
})();
ioredis is a robust, full-featured Redis client for Node.js. It supports advanced Redis features like clustering, sentinel, and pipelining. Compared to @keyv/redis, ioredis offers more direct control over Redis commands and is suitable for more complex use cases.
redis is the official Node.js client for Redis. It provides a straightforward API for interacting with Redis and supports all Redis commands. While @keyv/redis focuses on key-value storage with a simple API, redis offers more granular control and flexibility.
node-cache is an in-memory caching module for Node.js. It provides a simple API for storing key-value pairs with optional expiration times. Unlike @keyv/redis, node-cache does not use Redis as a backend and is suitable for use cases where in-memory storage is sufficient.
Redis storage adapter for Keyv
Redis storage adapter for Keyv.
createKeyv
function for easy creation of Keyv instances.Here is a standard use case where we implement Keyv
and @keyv/redis
:
import Keyv from 'keyv';
import KeyvRedis from '@keyv/redis';
const keyv = new Keyv(new KeyvRedis('redis://user:pass@localhost:6379'));
keyv.on('error', handleConnectionError);
Here is the same example but with the Keyv
instance created with the createKeyv
function:
import { createKeyv } from '@keyv/redis';
const keyv = createKeyv('redis://user:pass@localhost:6379', { namespace: 'my-namespace' });
You only have to import the @keyv/redis
library if you are using the createKeyv
function. 🎉 Otherwise, you can import Keyv
and @keyv/redis
independently.
Here you can pass in the Redis options directly:
import Keyv from 'keyv';
import KeyvRedis from '@keyv/redis';
const redisOptions = {
url: 'redis://localhost:6379', // The Redis server URL (use 'rediss' for TLS)
password: 'your_password', // Optional password if Redis has authentication enabled
socket: {
host: 'localhost', // Hostname of the Redis server
port: 6379, // Port number
reconnectStrategy: (retries) => Math.min(retries * 50, 2000), // Custom reconnect logic
tls: false, // Enable TLS if you need to connect over SSL
keepAlive: 30000, // Keep-alive timeout (in milliseconds)
}
};
const keyv = new Keyv(new KeyvRedis(redisOptions));
Or you can create a new Redis instance and pass it in with KeyvOptions
:
import Keyv from 'keyv';
import KeyvRedis, { createClient } from '@keyv/redis';
const redis = createClient('redis://user:pass@localhost:6379', { namespace: 'my-namespace'});
const keyvRedis = new KeyvRedis(redis);
const keyv = new Keyv({ store: keyvRedis });
You can set a namespace for your keys. This is useful if you want to manage your keys in a more organized way. Here is an example of how to set a namespace:
import Keyv from 'keyv';
import KeyvRedis from '@keyv/redis';
const keyv = new Keyv(new KeyvRedis('redis://user:pass@localhost:6379', { namespace: 'my-namespace' }));
This will prefix all keys with my-namespace:
. You can also set the namespace after the fact:
keyv.namespace = 'my-namespace';
NOTE: If you plan to do many clears or deletes, it is recommended to read the Performance Considerations section.
When initializing KeyvRedis
, you can specify the type of the values you are storing and you can also specify types when calling methods:
import Keyv from 'keyv';
import KeyvRedis, { createClient } from '@keyv/redis';
interface User {
id: number
name: string
}
const redis = createClient('redis://user:pass@localhost:6379');
const keyvRedis = new KeyvRedis<User>(redis);
const keyv = new Keyv({ store: keyvRedis });
await keyv.set("user:1", { id: 1, name: "Alice" })
const user = await keyv.get("user:1")
console.log(user.name) // 'Alice'
// specify types when calling methods
const user = await keyv.get<User>("user:1")
console.log(user.name) // 'Alice'
With namespaces being prefix based it is critical to understand some of the performance considerations we have made:
clear()
- We use the SCAN
command to iterate over keys. This is a non-blocking command that is more efficient than KEYS
. In addition we are using UNLINK
by default instead of DEL
. Even with that if you are iterating over a large dataset it can still be slow. It is highly recommended to use the namespace
option to limit the keys that are being cleared and if possible to not use the clear()
method in high performance environments. If you don't set namespaces, you can enable noNamespaceAffectsAll
to clear all keys using the FLUSHDB
command which is faster and can be used in production environments.
delete()
- By default we are now using UNLINK
instead of DEL
for deleting keys. This is a non-blocking command that is more efficient than DEL
. If you are deleting a large number of keys it is recommended to use the deleteMany()
method instead of delete()
.
clearBatchSize
- The clearBatchSize
option is set to 1000
by default. This is because Redis has a limit of 1000 keys that can be deleted in a single batch. If no namespace is defined and noNamespaceAffectsAll is set to true
this option will be ignored and the FLUSHDB
command will be used instead.
useUnlink
- This option is set to true
by default. This is because UNLINK
is a non-blocking command that is more efficient than DEL
. If you are not using UNLINK
and are doing a lot of deletes it is recommended to set this option to true
.
setMany
, getMany
, deleteMany
- These methods are more efficient than their singular counterparts. These will be used by default in the Keyv
library such as when using keyv.delete(string[])
it will use deleteMany()
.
If you want to see even better performance please see the Using Cacheable with Redis section as it has non-blocking and in-memory primary caching that goes along well with this library and Keyv.
This is because we are using UNLINK
by default instead of DEL
. This is a non-blocking command that is more efficient than DEL
but will slowly remove the memory allocation.
If you are deleting or clearing a large number of keys you can disable this by setting the useUnlink
option to false
. This will use DEL
instead of UNLINK
and should reduce the memory usage.
const keyv = new Keyv(new KeyvRedis('redis://user:pass@localhost:6379', { useUnlink: false }));
// Or
keyv.useUnlink = false;
If you are wanting to see even better performance with Redis, you can use Cacheable which is a multi-layered cache library that has in-memory primary caching and non-blocking secondary caching. Here is an example of how to use it with Redis:
import KeyvRedis from '@keyv/redis';
import Cacheable from 'cacheable';
const secondary = new KeyvRedis('redis://user:pass@localhost:6379');
const cache = new Cacheable( { secondary } );
For even higher performance you can set the nonBlocking
option to true
:
const cache = new Cacheable( { secondary, nonBlocking: true } );
This will make it so that the secondary does not block the primary cache and will be very fast. 🚀
If you are using a Redis Cluster or need to use TLS, you can pass in the redisOptions
directly. Here is an example of how to do that:
import Keyv from 'keyv';
import KeyvRedis, { createCluster } from '@keyv/redis';
const cluster = createCluster({
rootNodes: [
{
url: 'redis://127.0.0.1:7000',
},
{
url: 'redis://127.0.0.1:7001',
},
{
url: 'redis://127.0.0.1:7002',
},
],
});
const keyv = new Keyv({ store: new KeyvRedis(cluster) });
You can learn more about the createCluster
function in the documentation at https://github.com/redis/node-redis/tree/master/docs.
Here is an example of how to use TLS:
import Keyv from 'keyv';
import KeyvRedis from '@keyv/redis';
const tlsOptions = {
socket: {
host: 'localhost',
port: 6379,
tls: true, // Enable TLS connection
rejectUnauthorized: false, // Ignore self-signed certificate errors (for testing)
// Alternatively, provide CA, key, and cert for mutual authentication
ca: fs.readFileSync('/path/to/ca-cert.pem'),
cert: fs.readFileSync('/path/to/client-cert.pem'), // Optional for client auth
key: fs.readFileSync('/path/to/client-key.pem'), // Optional for client auth
}
};
const keyv = new Keyv({ store: new KeyvRedis(tlsOptions) });
UNLINK
command for deleting keys isntead of DEL
.false
).noNamespaceAffectsAll
is set to true
.noNamespaceAffectsAll
is set to true
.Overall the API is the same as v3 with additional options and performance improvements. Here are the main changes:
ioredis
library has been removed in favor of the redis
aka node-redis
library. If you want to use ioredis you can use @keyv/keyval
useUnlink
option has been added to use UNLINK
instead of DEL
and set to true by default.clearBatchSize
option has been added to set the number of keys to delete in a single batch.clear()
and delete()
methods now use UNLINK
instead of DEL
. If you want to use DEL
you can set the useUnlink
option to false
.keyv
with @keyv/redis
as the storage adapter you can do the following:import Keyv from 'keyv';
import KeyvRedis from '@keyv/redis';
const redis = new KeyvRedis('redis://user:pass@localhost:6379');
const keyv = new Keyv({ store: redis, namespace: 'my-namespace', useKeyPrefix: false });
This will make it so the storage adapter @keyv/redis
will handle the namespace and not the keyv
instance. If you leave it on it will just look duplicated like my-namespace:my-namespace:key
.
We no longer support redis sets. This is due to the fact that it caused significant performance issues and was not a good fit for the library.
FAQs
Redis storage adapter for Keyv
The npm package @keyv/redis receives a total of 256,749 weekly downloads. As such, @keyv/redis popularity was classified as popular.
We found that @keyv/redis demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.