or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client.mdconnections.mdexceptions.mdindex.mdpipeline.mdpubsub.md

client.mddocs/

0

# Redis Cluster Client

1

2

The RedisCluster class is the primary interface for interacting with Redis clusters. It extends the standard Redis client with cluster-aware implementations of Redis commands, automatic slot management, node discovery, and failover support.

3

4

## Capabilities

5

6

### RedisCluster Class

7

8

Main Redis cluster client that provides all standard Redis operations with cluster-aware implementations and additional cluster management functionality.

9

10

```python { .api }

11

class RedisCluster(Redis):

12

def __init__(self, host=None, port=None, startup_nodes=None,

13

max_connections=None, max_connections_per_node=False,

14

init_slot_cache=True, readonly_mode=False,

15

reinitialize_steps=None, skip_full_coverage_check=False,

16

nodemanager_follow_cluster=False, connection_class=None,

17

read_from_replicas=False, cluster_down_retry_attempts=3,

18

host_port_remap=None, **kwargs):

19

"""

20

Initialize Redis cluster client.

21

22

Parameters:

23

- host (str, optional): Single startup host

24

- port (int, optional): Port for single host

25

- startup_nodes (List[StartupNode], optional): List of initial cluster nodes

26

- max_connections (int, optional): Maximum total connections across cluster

27

- max_connections_per_node (bool|int): Enable per-node connection limits

28

- init_slot_cache (bool): Initialize slot-to-node mapping on startup

29

- readonly_mode (bool): Enable read-only operations

30

- reinitialize_steps (int, optional): Steps before reinitializing cluster layout

31

- skip_full_coverage_check (bool): Skip full cluster coverage validation

32

- nodemanager_follow_cluster (bool): Automatically follow cluster topology changes

33

- connection_class (type, optional): Custom connection class

34

- read_from_replicas (bool): Allow reading from replica nodes

35

- cluster_down_retry_attempts (int): Retry attempts for cluster-down errors

36

- host_port_remap (HostPortRemap, optional): Host/port remapping configuration

37

- **kwargs: Additional Redis connection parameters (decode_responses, etc.)

38

"""

39

```

40

41

### Client Creation

42

43

Create cluster clients from URLs or startup node lists.

44

45

```python { .api }

46

@classmethod

47

def from_url(cls, url, **kwargs):

48

"""

49

Create RedisCluster client from connection URL.

50

51

Parameters:

52

- url (str): Redis cluster URL (redis://host:port)

53

- **kwargs: Additional connection parameters

54

55

Returns:

56

RedisCluster: Configured cluster client instance

57

"""

58

```

59

60

### Core Client Methods

61

62

Essential client functionality for command execution and cluster interface creation.

63

64

```python { .api }

65

def execute_command(self, *args, **kwargs):

66

"""

67

Execute Redis command with cluster routing.

68

69

Parameters:

70

- *args: Command and arguments

71

- **kwargs: Additional execution options

72

73

Returns:

74

Any: Command result

75

"""

76

77

def pubsub(self, **kwargs):

78

"""

79

Get cluster-aware pub/sub interface.

80

81

Parameters:

82

- **kwargs: PubSub configuration options

83

84

Returns:

85

ClusterPubSub: Cluster pub/sub instance

86

"""

87

88

def pipeline(self, transaction=None, shard_hint=None, read_from_replicas=False):

89

"""

90

Create cluster pipeline for batching commands.

91

92

Parameters:

93

- transaction (bool, optional): Transaction mode (not supported in cluster)

94

- shard_hint (str, optional): Hint for pipeline routing

95

- read_from_replicas (bool): Enable reading from replicas

96

97

Returns:

98

ClusterPipeline: Pipeline instance for command batching

99

"""

100

```

101

102

### Key Scanning

103

104

Cluster-wide key iteration with pattern matching and type filtering.

105

106

```python { .api }

107

def scan_iter(self, match=None, count=None, _type=None):

108

"""

109

Scan keys across entire cluster.

110

111

Parameters:

112

- match (str, optional): Key pattern to match

113

- count (int, optional): Hint for number of keys per iteration

114

- _type (str, optional): Filter by key type

115

116

Yields:

117

str: Matching keys from all cluster nodes

118

"""

119

```

120

121

### Cluster Management Commands

122

123

Commands for managing cluster topology, slots, and node configuration.

124

125

```python { .api }

126

def cluster_info(self):

127

"""

128

Get cluster state information.

129

130

Returns:

131

dict: Cluster state details including size, slots, and status

132

"""

133

134

def cluster_nodes(self):

135

"""

136

Get detailed cluster topology information.

137

138

Returns:

139

dict: Node information including IDs, addresses, roles, and slot assignments

140

"""

141

142

def cluster_slots(self):

143

"""

144

Get hash slot to node mappings.

145

146

Returns:

147

SlotsMapping: List of slot ranges with assigned master and replica nodes

148

"""

149

150

def cluster_keyslot(self, name):

151

"""

152

Get hash slot for key.

153

154

Parameters:

155

- name (str): Key name

156

157

Returns:

158

int: Hash slot number (0-16383)

159

"""

160

161

def cluster_countkeysinslot(self, slot_id):

162

"""

163

Count keys in specific slot.

164

165

Parameters:

166

- slot_id (int): Slot number (0-16383)

167

168

Returns:

169

int: Number of keys in slot

170

"""

171

172

def cluster_count_failure_report(self, node_id):

173

"""

174

Get failure report count for specific node.

175

176

Parameters:

177

- node_id (str): Node ID to check failure reports for

178

179

Returns:

180

int: Number of failure reports for the node

181

"""

182

```

183

184

### Slot Management Commands

185

186

Commands for assigning and managing hash slots across cluster nodes.

187

188

```python { .api }

189

def cluster_addslots(self, node_id, *slots):

190

"""

191

Assign hash slots to specific node.

192

193

Parameters:

194

- node_id (str): Target node ID

195

- *slots (int): Slot numbers to assign

196

197

Returns:

198

bool: Success status

199

"""

200

201

def cluster_delslots(self, *slots):

202

"""

203

Remove hash slots from nodes.

204

205

Parameters:

206

- *slots (int): Slot numbers to remove

207

208

Returns:

209

bool: Success status

210

"""

211

```

212

213

### Node Management Commands

214

215

Commands for adding nodes, configuring replication, and managing cluster membership.

216

217

```python { .api }

218

def cluster_meet(self, node_id, host, port):

219

"""

220

Add node to cluster.

221

222

Parameters:

223

- node_id (str): Node ID to add

224

- host (str): Node hostname

225

- port (int): Node port

226

227

Returns:

228

bool: Success status

229

"""

230

231

def cluster_replicate(self, target_node_id):

232

"""

233

Configure current node as replica.

234

235

Parameters:

236

- target_node_id (str): Master node ID to replicate

237

238

Returns:

239

bool: Success status

240

"""

241

242

def cluster_failover(self, node_id, option=None):

243

"""

244

Force failover on specified node.

245

246

Parameters:

247

- node_id (str): Node ID to failover

248

- option (str, optional): Failover option ('FORCE' or 'TAKEOVER')

249

250

Returns:

251

bool: Success status

252

"""

253

254

def cluster_reset(self, node_id, soft=True):

255

"""

256

Reset cluster node.

257

258

Parameters:

259

- node_id (str): Node ID to reset

260

- soft (bool): Perform soft reset (preserve data)

261

262

Returns:

263

bool: Success status

264

"""

265

266

def cluster_reset_all_nodes(self, soft=True):

267

"""

268

Reset all cluster nodes.

269

270

Parameters:

271

- soft (bool): Perform soft reset (preserve data)

272

273

Returns:

274

bool: Success status

275

"""

276

277

def cluster_save_config(self):

278

"""

279

Save cluster configuration to disk.

280

281

Returns:

282

bool: Success status

283

"""

284

285

def cluster_get_keys_in_slot(self, slot, num_keys):

286

"""

287

Get keys in specific slot.

288

289

Parameters:

290

- slot (int): Slot number (0-16383)

291

- num_keys (int): Maximum number of keys to return

292

293

Returns:

294

List[str]: Keys in the slot

295

"""

296

297

def cluster_set_config_epoch(self, node_id, epoch):

298

"""

299

Set cluster configuration epoch for node.

300

301

Parameters:

302

- node_id (str): Node ID

303

- epoch (int): Configuration epoch

304

305

Returns:

306

bool: Success status

307

"""

308

309

def cluster_setslot(self, node_id, slot_id, state, bind_to_node_id=None):

310

"""

311

Set slot state for cluster reconfiguration.

312

313

Parameters:

314

- node_id (str): Node ID

315

- slot_id (int): Slot number (0-16383)

316

- state (str): Slot state ('IMPORTING', 'MIGRATING', 'STABLE', 'NODE')

317

- bind_to_node_id (str, optional): Node to bind slot to (for 'NODE' state)

318

319

Returns:

320

bool: Success status

321

"""

322

323

def cluster_slaves(self, target_node_id):

324

"""

325

Get slave nodes for specific master.

326

327

Parameters:

328

- target_node_id (str): Master node ID

329

330

Returns:

331

List[dict]: Slave node information

332

"""

333

```

334

335

### Cluster-Aware Redis Commands

336

337

Modified Redis commands that work across multiple cluster nodes.

338

339

```python { .api }

340

def mget(self, keys, *args):

341

"""

342

Multi-get across cluster nodes.

343

344

Parameters:

345

- keys (List[str]): List of keys to retrieve

346

- *args: Additional key arguments

347

348

Returns:

349

List[Any]: Values for requested keys (None for missing keys)

350

"""

351

352

def mset(self, *args, **kwargs):

353

"""

354

Multi-set across cluster nodes.

355

356

Parameters:

357

- *args: Key-value pairs as positional arguments

358

- **kwargs: Key-value pairs as keyword arguments

359

360

Returns:

361

bool: Success status

362

"""

363

364

def msetnx(self, *args, **kwargs):

365

"""

366

Multi-set if not exists across cluster nodes.

367

368

Parameters:

369

- *args: Key-value pairs as positional arguments

370

- **kwargs: Key-value pairs as keyword arguments

371

372

Returns:

373

bool: True if all keys were set, False otherwise

374

"""

375

376

def delete(self, *names):

377

"""

378

Delete multiple keys across cluster nodes.

379

380

Parameters:

381

- *names (str): Keys to delete

382

383

Returns:

384

int: Number of keys deleted

385

"""

386

387

def rename(self, src, dst, replace=False):

388

"""

389

Rename key with cross-slot support.

390

391

Parameters:

392

- src (str): Source key name

393

- dst (str): Destination key name

394

- replace (bool): Allow replacing existing destination key

395

396

Returns:

397

bool: Success status

398

"""

399

400

def renamenx(self, src, dst):

401

"""

402

Rename key if destination doesn't exist (cluster implementation is non-atomic).

403

404

Parameters:

405

- src (str): Source key name

406

- dst (str): Destination key name

407

408

Returns:

409

bool: True if rename occurred, False if destination already exists

410

411

Note:

412

In cluster mode, this operation is not atomic - it checks existence

413

then calls rename, which may cause race conditions.

414

"""

415

```

416

417

### Set Operations

418

419

Cluster-aware set operations that work across multiple nodes.

420

421

```python { .api }

422

def sdiff(self, keys, *args):

423

"""Set difference across cluster nodes."""

424

425

def sdiffstore(self, dest, keys, *args):

426

"""Store set difference result across cluster nodes."""

427

428

def sinter(self, keys, *args):

429

"""Set intersection across cluster nodes."""

430

431

def sinterstore(self, dest, keys, *args):

432

"""Store set intersection result across cluster nodes."""

433

434

def smove(self, src, dst, value):

435

"""Move set member between sets across cluster nodes."""

436

437

def sunion(self, keys, *args):

438

"""Set union across cluster nodes."""

439

440

def sunionstore(self, dest, keys, *args):

441

"""Store set union result across cluster nodes."""

442

```

443

444

### List Operations

445

446

Cluster-aware list operations for cross-slot list manipulation.

447

448

```python { .api }

449

def brpoplpush(self, src, dst, timeout=0):

450

"""

451

Blocking right pop left push across cluster nodes.

452

453

Parameters:

454

- src (str): Source list key

455

- dst (str): Destination list key

456

- timeout (int): Blocking timeout in seconds

457

458

Returns:

459

str: Moved element or None if timeout

460

"""

461

462

def rpoplpush(self, src, dst):

463

"""

464

Right pop left push across cluster nodes.

465

466

Parameters:

467

- src (str): Source list key

468

- dst (str): Destination list key

469

470

Returns:

471

str: Moved element or None if source empty

472

"""

473

```

474

475

### HyperLogLog Operations

476

477

Cluster-aware HyperLogLog operations for distributed cardinality estimation.

478

479

```python { .api }

480

def pfcount(self, *sources):

481

"""

482

Count unique elements across HyperLogLog keys.

483

484

Parameters:

485

- *sources (str): HyperLogLog key names

486

487

Returns:

488

int: Approximate cardinality

489

"""

490

491

def pfmerge(self, dest, *sources):

492

"""

493

Merge HyperLogLog keys across cluster nodes.

494

495

Parameters:

496

- dest (str): Destination key

497

- *sources (str): Source HyperLogLog keys

498

499

Returns:

500

bool: Success status

501

"""

502

```

503

504

### Pub/Sub Information Commands

505

506

Commands for getting information about active channels and subscriptions.

507

508

```python { .api }

509

def pubsub_channels(self, pattern='*', aggregate=True):

510

"""

511

Get list of channels with active subscribers.

512

513

Parameters:

514

- pattern (str): Channel name pattern to match

515

- aggregate (bool): Merge responses from all nodes

516

517

Returns:

518

List[str]: Active channel names matching pattern

519

"""

520

521

def pubsub_numpat(self, aggregate=True):

522

"""

523

Get number of active pattern subscriptions.

524

525

Parameters:

526

- aggregate (bool): Merge responses from all nodes

527

528

Returns:

529

int: Total number of pattern subscriptions

530

"""

531

532

def pubsub_numsub(self, *args, **kwargs):

533

"""

534

Get subscriber counts for specific channels.

535

536

Parameters:

537

- *args: Channel names to check

538

- aggregate (bool): Merge responses from all nodes (via kwargs)

539

540

Returns:

541

List[Tuple[str, int]]: Channel names and subscriber counts

542

"""

543

```

544

545

## Usage Examples

546

547

### Basic Client Setup

548

549

```python

550

from rediscluster import RedisCluster

551

552

# Single host startup

553

rc = RedisCluster(host='127.0.0.1', port=7000, decode_responses=True)

554

555

# Multiple startup nodes for redundancy

556

startup_nodes = [

557

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

558

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

559

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

560

]

561

rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)

562

563

# From URL

564

rc = RedisCluster.from_url("redis://127.0.0.1:7000", decode_responses=True)

565

```

566

567

### Advanced Configuration

568

569

```python

570

# Production configuration with connection pooling

571

rc = RedisCluster(

572

startup_nodes=startup_nodes,

573

decode_responses=True,

574

max_connections=32,

575

max_connections_per_node=8,

576

read_from_replicas=True,

577

cluster_down_retry_attempts=5,

578

socket_timeout=5,

579

socket_connect_timeout=5

580

)

581

582

# Read-only replica configuration

583

rc = RedisCluster(

584

startup_nodes=startup_nodes,

585

readonly_mode=True,

586

read_from_replicas=True

587

)

588

```

589

590

### Cluster Management

591

592

```python

593

# Get cluster information

594

info = rc.cluster_info()

595

print(f"Cluster size: {info['cluster_size']}")

596

print(f"Cluster state: {info['cluster_state']}")

597

598

# Get node topology

599

nodes = rc.cluster_nodes()

600

for node_id, node_info in nodes.items():

601

print(f"Node {node_id}: {node_info['host']}:{node_info['port']} - {node_info['role']}")

602

603

# Get slot mappings

604

slots = rc.cluster_slots()

605

for slot_range in slots:

606

start_slot, end_slot = slot_range[0], slot_range[1]

607

master = slot_range[2]

608

print(f"Slots {start_slot}-{end_slot}: master {master[0]}:{master[1]}")

609

```

610

611

### Multi-Key Operations

612

613

```python

614

# Multi-key operations work transparently across nodes

615

keys_values = {"user:1": "data1", "user:2": "data2", "session:abc": "active"}

616

rc.mset(keys_values)

617

618

values = rc.mget(["user:1", "user:2", "session:abc"])

619

print(values) # ['data1', 'data2', 'active']

620

621

# Delete multiple keys

622

deleted = rc.delete("user:1", "user:2", "session:abc")

623

print(f"Deleted {deleted} keys")

624

```