|
| 1 | +# Redis Cluster Pipeline Library |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This is a custom wrapper library around the popular ioredis client that adds a new method called `clusterPipeline` to handle Redis Cluster pipelines more efficiently. This library was developed by the PhysicsWallah Private Limited tech team to solve issues with executing multiple Redis commands across Redis Cluster nodes. |
| 6 | + |
| 7 | +## Problem Statement |
| 8 | + |
| 9 | +While using Redis Cluster with the ioredis client, handling multiple commands in a way that correctly distributes them across nodes while maintaining the order of execution was challenging. To address this, we developed this library that adds the `clusterPipeline` method, making it easy to manage Redis commands in a Redis Cluster environment. |
| 10 | + |
| 11 | +This library is simply a wrapper around ioredis, extending it with an additional method that enables Redis Cluster commands to be executed in parallel, with the results returned in the correct order. |
| 12 | + |
| 13 | +## Features |
| 14 | + |
| 15 | +- **Efficient Redis Cluster Pipeline**: Adds support for executing commands across multiple Redis Cluster nodes using `clusterPipeline`. |
| 16 | +- **Seamless Integration**: Works with the existing ioredis client without requiring any changes to your existing Redis configuration. |
| 17 | +- **Cluster-Aware**: Automatically handles Redis commands based on slots, distributing them across the appropriate Redis Cluster node. |
| 18 | +- **Backward Compatible**: All existing ioredis functionality is preserved; the `clusterPipeline` method is simply added to the Cluster class. |
| 19 | + |
| 20 | +## Installation |
| 21 | + |
| 22 | +To install the library, use npm or yarn to add it to your project. |
| 23 | + |
| 24 | +```bash |
| 25 | +npm install @pw-tech/ioredis |
| 26 | +``` |
| 27 | + |
| 28 | +Or with yarn: |
| 29 | + |
| 30 | +```bash |
| 31 | +yarn add @pw-tech/ioredis |
| 32 | +``` |
| 33 | + |
| 34 | +## Usage |
| 35 | + |
| 36 | +After installing, you can use the Cluster class just as you would with ioredis, but with the added functionality of the `clusterPipeline` method for Redis Cluster commands. |
| 37 | + |
| 38 | +### Example |
| 39 | + |
| 40 | +1. Basic Redis Usage (Without Clusters) |
| 41 | + |
| 42 | +```javascript |
| 43 | +import { Redis } from '@pw-tech/ioredis'; |
| 44 | + |
| 45 | +const redis = new Redis({ |
| 46 | + host: 'localhost', |
| 47 | + port: 6379, |
| 48 | +}); |
| 49 | + |
| 50 | +redis.set('key1', 'value1').then(() => redis.get('key1')).then(console.log); |
| 51 | +``` |
| 52 | + |
| 53 | +2. Redis Cluster Usage (With `clusterPipeline`) |
| 54 | + |
| 55 | +In case you are using a Redis Cluster, you can now use the `clusterPipeline` method to handle pipelines across multiple nodes. |
| 56 | + |
| 57 | +```javascript |
| 58 | +import { Cluster } from '@pw-tech/ioredis'; |
| 59 | + |
| 60 | +const clusterRedis = new Cluster({ |
| 61 | + redisOptions: [{ host: 'localhost', port: 6379 }], |
| 62 | +}); |
| 63 | + |
| 64 | +const commands = [ |
| 65 | + ['set', 'key1', 'value1'], |
| 66 | + ['get', 'key1'], |
| 67 | +]; |
| 68 | + |
| 69 | +clusterRedis.clusterPipeline(commands).then(results => { |
| 70 | + console.log(results); // Output: [ ['OK'], ['value1'] ] |
| 71 | +}); |
| 72 | +``` |
| 73 | + |
| 74 | +## Explanation of `clusterPipeline` |
| 75 | + |
| 76 | +`clusterPipeline` takes an array of Redis commands (e.g., [['set', 'key', 'value'], ['get', 'key']]). |
| 77 | +It automatically divides the commands across the Redis Cluster nodes based on the slot of the key. |
| 78 | +It executes the commands in parallel and ensures the results are returned in the same order as the original commands. |
| 79 | + |
| 80 | +## How it Works |
| 81 | + |
| 82 | +- **Slot Calculation**: Redis Cluster splits keys across multiple nodes using slots. This library automatically calculates which node each key belongs to and groups the commands accordingly. |
| 83 | +- **Pipeline Execution**: Once the commands are grouped by node, they are executed in parallel on each node, ensuring better performance when dealing with large pipelines. |
| 84 | +- **Result Handling**: Results from each node are merged and returned in the same order as the original commands. |
| 85 | + |
| 86 | +## API Documentation |
| 87 | + |
| 88 | +`clusterPipeline(commands: [string, ...any][]): Promise<any[]>` |
| 89 | + |
| 90 | +### Parameters: |
| 91 | + |
| 92 | +- `commands`: An array of Redis commands, where each command is an array starting with the command name and followed by its arguments. |
| 93 | + - Example: [['set', 'key1', 'value1'], ['get', 'key1']]. |
| 94 | + |
| 95 | +### Returns: |
| 96 | + |
| 97 | +- A Promise that resolves to an array of command results in the same order as they were provided. |
| 98 | + - Example: [ ['OK'], ['value1'] ]. |
| 99 | + |
| 100 | +## Redis and Cluster |
| 101 | + |
| 102 | +All the normal ioredis Redis and Cluster functionality remains available. This library only adds the `clusterPipeline` method to Cluster. |
| 103 | + |
| 104 | +## Why This Library? |
| 105 | + |
| 106 | +### Problem at PhysicsWallah Private Limited |
| 107 | + |
| 108 | +At PhysicsWallah Private Limited, we needed an efficient way to handle Redis Cluster commands when multiple Redis nodes were involved. The standard Redis pipeline approach didn’t take slot distribution into account, leading to inefficiencies and complexity. We developed this library to: |
| 109 | + |
| 110 | +- Simplify the execution of multiple Redis commands across a Redis Cluster. |
| 111 | +- Maintain the order of results while executing commands in parallel. |
| 112 | +- Make our Redis Cluster usage more efficient and less error-prone. |
| 113 | + |
| 114 | +### How We Solve It |
| 115 | + |
| 116 | +By adding the `clusterPipeline` method, we ensure commands are distributed to the appropriate Redis node, executed in parallel, and results are returned in the correct order. This approach eliminates the need to manually manage slot calculations and node selection. |
| 117 | + |
| 118 | +## License |
| 119 | + |
| 120 | +This library is open-source and licensed under the MIT License. |
| 121 | + |
| 122 | +## Contributing |
| 123 | + |
| 124 | +If you have any improvements or bug fixes, feel free to submit a pull request or open an issue. |
0 commit comments