or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cluster.mdcommands.mdconfiguration.mdindex.mdpipelining.mdpubsub.mdredis-client.mdstreaming.md
tile.json

cluster.mddocs/

0

# Cluster Operations

1

2

Redis Cluster client provides automatic slot management, node discovery, failover handling, and load distribution across multiple Redis nodes. It maintains compatibility with the Redis client API while adding cluster-specific functionality.

3

4

## Capabilities

5

6

### Cluster Class

7

8

Main client class for Redis Cluster deployments with automatic slot mapping and node management.

9

10

```typescript { .api }

11

class Cluster extends EventEmitter {

12

constructor(startupNodes: ClusterNode[], options?: ClusterOptions);

13

14

// Connection management

15

connect(): Promise<void>;

16

disconnect(reconnect?: boolean): void;

17

quit(callback?: Callback<"OK">): Promise<"OK">;

18

duplicate(overrideStartupNodes?: ClusterNode[], overrideOptions?: ClusterOptions): Cluster;

19

20

// Properties

21

readonly options: ClusterOptions;

22

readonly status: ClusterStatus;

23

readonly autoPipelineQueueSize: number;

24

25

// Cluster management

26

nodes(role?: NodeRole): Redis[];

27

refreshSlotsCache(callback?: Callback<void>): void;

28

29

// All Redis commands are available with automatic slot routing

30

}

31

32

type ClusterNode = string | number | {

33

host?: string;

34

port?: number;

35

};

36

37

type ClusterStatus = "wait" | "reconnecting" | "connecting" | "connect" | "ready" | "close" | "end";

38

type NodeRole = "master" | "slave" | "all";

39

```

40

41

**Usage Examples:**

42

43

```typescript

44

import { Cluster } from "ioredis";

45

46

// Basic cluster connection

47

const cluster = new Cluster([

48

{ host: "127.0.0.1", port: 7000 },

49

{ host: "127.0.0.1", port: 7001 },

50

{ host: "127.0.0.1", port: 7002 }

51

]);

52

53

// Connection with options

54

const cluster2 = new Cluster([

55

"127.0.0.1:7000",

56

"127.0.0.1:7001",

57

"127.0.0.1:7002"

58

], {

59

scaleReads: "slave",

60

maxRedirections: 16,

61

retryStrategy: (times) => Math.min(times * 50, 2000)

62

});

63

64

// Automatic Redis command routing

65

await cluster.set("key", "value");

66

const value = await cluster.get("key");

67

```

68

69

### Node Management

70

71

Access and manage individual Redis nodes within the cluster.

72

73

```typescript { .api }

74

// Get nodes by role

75

nodes(role?: NodeRole): Redis[];

76

77

// Refresh slot mapping from cluster

78

refreshSlotsCache(callback?: Callback<void>): void;

79

```

80

81

**Usage Examples:**

82

83

```typescript

84

// Get all master nodes

85

const masters = cluster.nodes("master");

86

console.log(`${masters.length} master nodes`);

87

88

// Get all slave nodes

89

const slaves = cluster.nodes("slave");

90

91

// Get all nodes

92

const allNodes = cluster.nodes("all");

93

94

// Manual slot cache refresh

95

cluster.refreshSlotsCache((err) => {

96

if (err) console.error("Failed to refresh slots:", err);

97

else console.log("Slots cache refreshed");

98

});

99

```

100

101

### Cluster Configuration

102

103

Comprehensive configuration options extending Redis options with cluster-specific settings.

104

105

```typescript { .api }

106

interface ClusterOptions extends Partial<RedisOptions> {

107

// Cluster behavior

108

clusterRetryStrategy?: (times: number, reason?: Error) => number | void | null;

109

enableOfflineQueue?: boolean;

110

redisOptions?: RedisOptions;

111

scaleReads?: NodeRole | ((node: any, command: any) => Redis);

112

113

// Slot management

114

maxRedirections?: number;

115

retryDelayOnClusterDown?: number;

116

retryDelayOnMove?: number;

117

retryDelayOnFailover?: number;

118

119

// Node discovery

120

enableReadyCheck?: boolean;

121

lazyConnect?: boolean;

122

dnsLookup?: DNSLookupFunction;

123

124

// Performance

125

enableAutoPipelining?: boolean;

126

autoPipeliningIgnoredCommands?: string[];

127

128

// NAT support

129

natMap?: NatMap;

130

131

// Custom slot calculation

132

keyHashTag?: string;

133

134

// Cluster commands

135

customCommandHandlers?: Record<string, (command: string, args: any[]) => void>;

136

}

137

138

interface NatMap {

139

[key: string]: { host: string; port: number };

140

}

141

```

142

143

**Usage Examples:**

144

145

```typescript

146

const cluster = new Cluster([

147

{ host: "127.0.0.1", port: 7000 }

148

], {

149

// Read from slave nodes when possible

150

scaleReads: "slave",

151

152

// Cluster retry strategy

153

clusterRetryStrategy: (times, reason) => {

154

console.log(`Cluster retry ${times}: ${reason?.message}`);

155

return times < 10 ? Math.min(times * 100, 5000) : null;

156

},

157

158

// Max redirections before giving up

159

maxRedirections: 16,

160

161

// Enable autopipelining for performance

162

enableAutoPipelining: true,

163

164

// Custom Redis options for each node

165

redisOptions: {

166

password: "cluster-password",

167

connectTimeout: 5000,

168

commandTimeout: 2000

169

},

170

171

// NAT mapping for Docker/cloud environments

172

natMap: {

173

"172.17.0.2:7000": { host: "redis-node-1.example.com", port: 7000 },

174

"172.17.0.3:7001": { host: "redis-node-2.example.com", port: 7001 }

175

}

176

});

177

```

178

179

### Cluster Events

180

181

The Cluster client emits events for connection lifecycle and cluster state changes.

182

183

```typescript { .api }

184

// Connection events (inherited from EventEmitter)

185

on(event: 'connect', listener: (address?: string) => void): this;

186

on(event: 'ready', listener: () => void): this;

187

on(event: 'error', listener: (err: Error) => void): this;

188

on(event: 'close', listener: () => void): this;

189

on(event: 'reconnecting', listener: (ms: number) => void): this;

190

on(event: 'end', listener: () => void): this;

191

192

// Cluster-specific events

193

on(event: 'node error', listener: (err: Error, address: string) => void): this;

194

on(event: '+node', listener: (address: string) => void): this;

195

on(event: '-node', listener: (address: string) => void): this;

196

```

197

198

**Usage Examples:**

199

200

```typescript

201

const cluster = new Cluster([{ host: "127.0.0.1", port: 7000 }]);

202

203

cluster.on('ready', () => {

204

console.log('Cluster is ready');

205

});

206

207

cluster.on('error', (err) => {

208

console.error('Cluster error:', err);

209

});

210

211

cluster.on('node error', (err, address) => {

212

console.error(`Node ${address} error:`, err);

213

});

214

215

cluster.on('+node', (address) => {

216

console.log(`Node added: ${address}`);

217

});

218

219

cluster.on('-node', (address) => {

220

console.log(`Node removed: ${address}`);

221

});

222

```

223

224

## Advanced Features

225

226

### Custom Scale Reads Function

227

228

Implement custom logic for directing read commands to specific nodes.

229

230

```typescript { .api }

231

type ScaleReadsFunction = (node: {

232

role: string;

233

key: string;

234

options: any;

235

}, command: {

236

name: string;

237

args: any[];

238

}) => Redis | null;

239

```

240

241

```typescript

242

const cluster = new Cluster(nodes, {

243

scaleReads: (node, command) => {

244

// Direct specific commands to masters only

245

if (['eval', 'evalsha'].includes(command.name.toLowerCase())) {

246

return node.role === 'master' ? node : null;

247

}

248

// Use slaves for read operations

249

return node.role === 'slave' ? node : null;

250

}

251

});

252

```

253

254

### Cluster Connection Duplication

255

256

Create new cluster instances with independent connections but shared configuration.

257

258

```typescript { .api }

259

duplicate(

260

overrideStartupNodes?: ClusterNode[],

261

overrideOptions?: ClusterOptions

262

): Cluster;

263

```

264

265

```typescript

266

const originalCluster = new Cluster([...nodes], options);

267

268

// Duplicate with same configuration

269

const dup1 = originalCluster.duplicate();

270

271

// Duplicate with different nodes

272

const dup2 = originalCluster.duplicate([

273

{ host: "new-cluster-1.example.com", port: 7000 }

274

]);

275

276

// Duplicate with different options

277

const dup3 = originalCluster.duplicate(undefined, {

278

scaleReads: "master",

279

maxRedirections: 8

280

});

281

```

282

283

## Types

284

285

```typescript { .api }

286

type Callback<T> = (err?: Error | null, result?: T) => void;

287

288

interface DNSLookupFunction {

289

(hostname: string, options: any, callback: Function): void;

290

}

291

```