# Clustering ## Basic Example Connecting to a cluster is a bit different. Create the client by specifying some (or all) of the nodes in your cluster and then use it like a regular client instance: ```javascript import { createCluster } from 'redis'; const cluster = await createCluster({ rootNodes: [{ url: 'redis://10.0.0.1:30001' }, { url: 'redis://10.0.0.2:30002' }] }) .on('error', err => console.log('Redis Cluster Error', err)) .connect(); await cluster.set('key', 'value'); const value = await cluster.get('key'); await cluster.close(); ``` ## `createCluster` configuration > See the [client configuration](./client-configuration.md) page for the `rootNodes` and `defaults` configuration schemas. | Property | Default | Description | |------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | rootNodes | | An array of root nodes that are part of the cluster, which will be used to get the cluster topology. Each element in the array is a client configuration object. There is no need to specify every node in the cluster: 3 should be enough to reliably connect and obtain the cluster configuration from the server | | defaults | | The default configuration values for every client in the cluster. Use this for example when specifying an ACL user to connect with | | useReplicas | `false` | When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes | | minimizeConnections | `false` | When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes. Useful for short-term or Pub/Sub-only connections. | | maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors | | nodeAddressMap | | Defines the [node address mapping](#node-address-map) | | modules | | Included [Redis Modules](../README.md#packages) | | scripts | | Script definitions (see [Lua Scripts](./programmability.md#lua-scripts)) | | functions | | Function definitions (see [Functions](./programmability.md#functions)) | ## Auth with password and username Specifying the password in the URL or a root node will only affect the connection to that specific node. In case you want to set the password for all the connections being created from a cluster instance, use the `defaults` option. ```javascript createCluster({ rootNodes: [{ url: 'redis://10.0.0.1:30001' }, { url: 'redis://10.0.0.2:30002' }], defaults: { username: 'username', password: 'password' } }); ``` ## Node Address Map A mapping between the addresses in the cluster (see `CLUSTER SHARDS`) and the addresses the client should connect to. Useful when the cluster is running on a different network to the client. ```javascript const rootNodes = [{ url: 'external-host-1.io:30001' }, { url: 'external-host-2.io:30002' }]; // Use either a static mapping: createCluster({ rootNodes, nodeAddressMap: { '10.0.0.1:30001': { host: 'external-host.io', port: 30001 }, '10.0.0.2:30002': { host: 'external-host.io', port: 30002 } } }); // or create the mapping dynamically, as a function: createCluster({ rootNodes, nodeAddressMap(address) { const indexOfDash = address.lastIndexOf('-'), indexOfDot = address.indexOf('.', indexOfDash), indexOfColons = address.indexOf(':', indexOfDot); return { host: `external-host-${address.substring(indexOfDash + 1, indexOfDot)}.io`, port: Number(address.substring(indexOfColons + 1)) }; } }); ``` > This is a common problem when using ElastiCache. See [Accessing ElastiCache from outside AWS](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/accessing-elasticache.html) for more information on that. ## Command Routing ### Commands that operate on Redis Keys Commands such as `GET`, `SET`, etc. are routed by the first key specified. For example `MGET 1 2 3` will be routed by the key `1`. ### [Server Commands](https://redis.io/commands#server) Admin commands such as `MEMORY STATS`, `FLUSHALL`, etc. are not attached to the cluster, and must be executed on a specific node via `.getSlotMaster()`. ### "Forwarded Commands" Certain commands (e.g. `PUBLISH`) are forwarded to other cluster nodes by the Redis server. The client sends these commands to a random node in order to spread the load across the cluster.