0
# Maintenance and Operations
1
2
Advanced instance management including maintenance scheduling, failover operations, Redis version upgrades, and authentication.
3
4
## Capabilities
5
6
### Redis Version Upgrades
7
8
Upgrade a Redis instance to a newer Redis version.
9
10
```python { .api }
11
def upgrade_instance(
12
self,
13
*,
14
name: str,
15
redis_version: str,
16
**kwargs
17
) -> operation.Operation:
18
"""
19
Upgrade a Redis instance to a newer Redis version.
20
21
Args:
22
name: Required. Redis instance resource name using the form:
23
"projects/{project_id}/locations/{location_id}/instances/{instance_id}"
24
redis_version: Required. Specifies the target version of Redis to upgrade to.
25
Format: "REDIS_X_Y" (e.g., "REDIS_6_X", "REDIS_7_X")
26
27
Returns:
28
google.api_core.operation.Operation: A long-running operation object.
29
The result will be an Instance object.
30
31
Raises:
32
google.api_core.exceptions.GoogleAPICallError: If the request failed.
33
google.api_core.exceptions.NotFound: If the instance doesn't exist.
34
google.api_core.exceptions.InvalidArgument: If the version is invalid.
35
"""
36
```
37
38
### Instance Failover
39
40
Initiate a manual failover of a Redis instance to its replica.
41
42
```python { .api }
43
def failover_instance(
44
self,
45
*,
46
name: str,
47
data_protection_mode: Optional[
48
cloud_redis.FailoverInstanceRequest.DataProtectionMode
49
] = cloud_redis.FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS,
50
**kwargs
51
) -> operation.Operation:
52
"""
53
Initiates a failover of the primary node to current replica node for a specific STANDARD_HA Redis instance.
54
55
Args:
56
name: Required. Redis instance resource name using the form:
57
"projects/{project_id}/locations/{location_id}/instances/{instance_id}"
58
data_protection_mode: Optional. Specifies different modes of operation for failover.
59
Defaults to LIMITED_DATA_LOSS.
60
61
Returns:
62
google.api_core.operation.Operation: A long-running operation object.
63
The result will be an Instance object.
64
65
Raises:
66
google.api_core.exceptions.GoogleAPICallError: If the request failed.
67
google.api_core.exceptions.NotFound: If the instance doesn't exist.
68
google.api_core.exceptions.FailedPrecondition: If instance is not STANDARD_HA tier.
69
"""
70
```
71
72
### Authentication String Retrieval
73
74
Get the AUTH string for connecting to a Redis instance with authentication enabled.
75
76
```python { .api }
77
def get_instance_auth_string(
78
self, *, name: str, **kwargs
79
) -> cloud_redis.InstanceAuthString:
80
"""
81
Gets the AUTH string for a Redis instance with AUTH enabled.
82
83
Args:
84
name: Required. Redis instance resource name using the form:
85
"projects/{project_id}/locations/{location_id}/instances/{instance_id}"
86
87
Returns:
88
cloud_redis.InstanceAuthString: The auth string for the instance.
89
90
Raises:
91
google.api_core.exceptions.GoogleAPICallError: If the request failed.
92
google.api_core.exceptions.NotFound: If the instance doesn't exist.
93
google.api_core.exceptions.FailedPrecondition: If AUTH is not enabled.
94
"""
95
```
96
97
### Maintenance Rescheduling
98
99
Reschedule upcoming maintenance for a Redis instance.
100
101
```python { .api }
102
def reschedule_maintenance(
103
self,
104
*,
105
name: str,
106
reschedule_type: cloud_redis.RescheduleMaintenanceRequest.RescheduleType,
107
schedule_time: Optional[timestamp_pb2.Timestamp] = None,
108
**kwargs
109
) -> operation.Operation:
110
"""
111
Reschedule upcoming maintenance of a Redis instance.
112
113
Args:
114
name: Required. Redis instance resource name using the form:
115
"projects/{project_id}/locations/{location_id}/instances/{instance_id}"
116
reschedule_type: Required. If reschedule type is SPECIFIC_TIME, then schedule_time is required.
117
schedule_time: Optional. Timestamp when the maintenance shall be rescheduled to.
118
Required if reschedule_type is SPECIFIC_TIME.
119
120
Returns:
121
google.api_core.operation.Operation: A long-running operation object.
122
The result will be an Instance object.
123
124
Raises:
125
google.api_core.exceptions.GoogleAPICallError: If the request failed.
126
google.api_core.exceptions.NotFound: If the instance doesn't exist.
127
google.api_core.exceptions.InvalidArgument: If schedule_time is invalid.
128
"""
129
```
130
131
## Request Types
132
133
### Upgrade Request
134
135
```python { .api }
136
class UpgradeInstanceRequest:
137
name: str
138
redis_version: str
139
```
140
141
### Failover Request
142
143
```python { .api }
144
class FailoverInstanceRequest:
145
name: str
146
data_protection_mode: FailoverInstanceRequest.DataProtectionMode
147
148
class FailoverInstanceRequest.DataProtectionMode(Enum):
149
DATA_PROTECTION_MODE_UNSPECIFIED = 0
150
LIMITED_DATA_LOSS = 1
151
FORCE_DATA_LOSS = 2
152
```
153
154
### Auth String Request
155
156
```python { .api }
157
class GetInstanceAuthStringRequest:
158
name: str
159
```
160
161
### Maintenance Reschedule Request
162
163
```python { .api }
164
class RescheduleMaintenanceRequest:
165
name: str
166
reschedule_type: RescheduleMaintenanceRequest.RescheduleType
167
schedule_time: Timestamp
168
169
class RescheduleMaintenanceRequest.RescheduleType(Enum):
170
RESCHEDULE_TYPE_UNSPECIFIED = 0
171
IMMEDIATE = 1
172
NEXT_AVAILABLE_WINDOW = 2
173
SPECIFIC_TIME = 3
174
```
175
176
## Response Types
177
178
### Auth String Response
179
180
```python { .api }
181
class InstanceAuthString:
182
auth_string: str
183
"""The AUTH string for the Redis instance."""
184
```
185
186
## Usage Examples
187
188
### Upgrade Redis Version
189
190
```python
191
from google.cloud.redis import CloudRedisClient
192
193
client = CloudRedisClient()
194
instance_name = "projects/my-project/locations/us-central1/instances/my-redis"
195
196
# Check current version and available versions
197
instance = client.get_instance(name=instance_name)
198
print(f"Current version: {instance.redis_version}")
199
print(f"Available versions: {instance.available_maintenance_versions}")
200
201
# Upgrade to Redis 7.x
202
operation = client.upgrade_instance(
203
name=instance_name,
204
redis_version="REDIS_7_X"
205
)
206
207
print(f"Upgrade operation started: {operation.name}")
208
209
# Wait for upgrade to complete (can take 10-30 minutes)
210
try:
211
result = operation.result(timeout=3600) # 1 hour timeout
212
print(f"Upgrade completed successfully")
213
print(f"New version: {result.redis_version}")
214
print(f"Instance state: {result.state}")
215
except Exception as e:
216
print(f"Upgrade failed: {e}")
217
```
218
219
### Perform Manual Failover
220
221
```python
222
from google.cloud.redis import CloudRedisClient, FailoverInstanceRequest
223
224
client = CloudRedisClient()
225
instance_name = "projects/my-project/locations/us-central1/instances/my-ha-redis"
226
227
# Check if instance supports failover (must be STANDARD_HA)
228
instance = client.get_instance(name=instance_name)
229
if instance.tier != instance.Tier.STANDARD_HA:
230
print("Failover is only supported for STANDARD_HA instances")
231
exit(1)
232
233
print(f"Current location: {instance.current_location_id}")
234
print(f"Alternative location: {instance.alternative_location_id}")
235
236
# Perform failover with limited data loss protection
237
operation = client.failover_instance(
238
name=instance_name,
239
data_protection_mode=FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS
240
)
241
242
print(f"Failover operation started: {operation.name}")
243
244
# Wait for failover to complete
245
try:
246
result = operation.result(timeout=1800) # 30 minutes timeout
247
print(f"Failover completed successfully")
248
print(f"New primary location: {result.current_location_id}")
249
except Exception as e:
250
print(f"Failover failed: {e}")
251
```
252
253
### Get Authentication String
254
255
```python
256
from google.cloud.redis import CloudRedisClient
257
258
client = CloudRedisClient()
259
instance_name = "projects/my-project/locations/us-central1/instances/my-secure-redis"
260
261
# Check if AUTH is enabled
262
instance = client.get_instance(name=instance_name)
263
if not instance.auth_enabled:
264
print("AUTH is not enabled for this instance")
265
exit(1)
266
267
# Get the AUTH string
268
try:
269
auth_info = client.get_instance_auth_string(name=instance_name)
270
auth_string = auth_info.auth_string
271
272
print(f"AUTH string retrieved successfully")
273
print(f"Use this string to authenticate: {auth_string}")
274
275
# Example connection with AUTH
276
print(f"\nConnection example:")
277
print(f"redis-cli -h {instance.host} -p {instance.port} -a {auth_string}")
278
279
except Exception as e:
280
print(f"Failed to get AUTH string: {e}")
281
```
282
283
### Reschedule Maintenance
284
285
```python
286
from google.cloud.redis import CloudRedisClient, RescheduleMaintenanceRequest
287
from google.protobuf.timestamp_pb2 import Timestamp
288
from datetime import datetime, timedelta
289
290
client = CloudRedisClient()
291
instance_name = "projects/my-project/locations/us-central1/instances/my-redis"
292
293
# Check current maintenance schedule
294
instance = client.get_instance(name=instance_name)
295
if instance.maintenance_schedule:
296
schedule = instance.maintenance_schedule
297
print(f"Current maintenance scheduled for: {schedule.start_time}")
298
print(f"Can reschedule: {schedule.can_reschedule}")
299
300
if not schedule.can_reschedule:
301
print("Maintenance cannot be rescheduled")
302
exit(1)
303
else:
304
print("No maintenance currently scheduled")
305
exit(1)
306
307
# Option 1: Reschedule to next available window
308
operation = client.reschedule_maintenance(
309
name=instance_name,
310
reschedule_type=RescheduleMaintenanceRequest.RescheduleType.NEXT_AVAILABLE_WINDOW
311
)
312
313
print(f"Rescheduling to next available window: {operation.name}")
314
315
# Option 2: Reschedule to specific time (uncomment to use)
316
# future_time = datetime.now() + timedelta(days=7) # 1 week from now
317
# schedule_timestamp = Timestamp()
318
# schedule_timestamp.FromDatetime(future_time)
319
#
320
# operation = client.reschedule_maintenance(
321
# name=instance_name,
322
# reschedule_type=RescheduleMaintenanceRequest.RescheduleType.SPECIFIC_TIME,
323
# schedule_time=schedule_timestamp
324
# )
325
326
# Wait for reschedule operation
327
try:
328
result = operation.result(timeout=300) # 5 minutes timeout
329
print(f"Maintenance rescheduled successfully")
330
if result.maintenance_schedule:
331
new_schedule = result.maintenance_schedule
332
print(f"New maintenance time: {new_schedule.start_time}")
333
except Exception as e:
334
print(f"Failed to reschedule maintenance: {e}")
335
```
336
337
### Monitor Instance Health
338
339
```python
340
from google.cloud.redis import CloudRedisClient
341
import time
342
343
def monitor_instance_health(instance_name: str, check_interval: int = 60):
344
"""Monitor Redis instance health and maintenance status."""
345
client = CloudRedisClient()
346
347
print(f"Monitoring instance: {instance_name}")
348
print(f"Check interval: {check_interval} seconds")
349
print("-" * 50)
350
351
while True:
352
try:
353
instance = client.get_instance(name=instance_name)
354
355
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
356
print(f"State: {instance.state}")
357
print(f"Current Location: {instance.current_location_id}")
358
359
if instance.status_message:
360
print(f"Status: {instance.status_message}")
361
362
# Check maintenance schedule
363
if instance.maintenance_schedule:
364
schedule = instance.maintenance_schedule
365
print(f"Maintenance: {schedule.start_time} - {schedule.end_time}")
366
print(f"Can reschedule: {schedule.can_reschedule}")
367
368
# Check for suspension reasons
369
if instance.suspension_reasons:
370
print(f"Suspension reasons: {instance.suspension_reasons}")
371
372
print("-" * 50)
373
374
# Alert on critical states
375
if instance.state in [instance.State.REPAIRING, instance.State.MAINTENANCE]:
376
print(f"ALERT: Instance in {instance.state} state")
377
elif instance.suspension_reasons:
378
print(f"ALERT: Instance suspended - {instance.suspension_reasons}")
379
380
time.sleep(check_interval)
381
382
except KeyboardInterrupt:
383
print("Monitoring stopped by user")
384
break
385
except Exception as e:
386
print(f"Error monitoring instance: {e}")
387
time.sleep(check_interval)
388
389
# Start monitoring
390
instance_name = "projects/my-project/locations/us-central1/instances/production-redis"
391
monitor_instance_health(instance_name, check_interval=120) # Check every 2 minutes
392
```
393
394
### Emergency Force Failover
395
396
```python
397
from google.cloud.redis import CloudRedisClient, FailoverInstanceRequest
398
399
def emergency_failover(instance_name: str, force: bool = False):
400
"""Perform emergency failover with data loss protection options."""
401
client = CloudRedisClient()
402
403
try:
404
# Get current instance state
405
instance = client.get_instance(name=instance_name)
406
407
if instance.tier != instance.Tier.STANDARD_HA:
408
raise ValueError("Emergency failover only available for STANDARD_HA instances")
409
410
if instance.state != instance.State.READY:
411
print(f"WARNING: Instance state is {instance.state}, not READY")
412
413
print(f"Current primary: {instance.current_location_id}")
414
print(f"Failover target: {instance.alternative_location_id}")
415
416
# Choose data protection mode
417
if force:
418
data_protection_mode = FailoverInstanceRequest.DataProtectionMode.FORCE_DATA_LOSS
419
print("WARNING: Forcing failover - potential data loss!")
420
else:
421
data_protection_mode = FailoverInstanceRequest.DataProtectionMode.LIMITED_DATA_LOSS
422
print("Using limited data loss protection")
423
424
# Confirm before proceeding
425
if not force:
426
confirm = input("Proceed with failover? (yes/no): ")
427
if confirm.lower() != 'yes':
428
print("Failover cancelled")
429
return
430
431
# Start failover
432
operation = client.failover_instance(
433
name=instance_name,
434
data_protection_mode=data_protection_mode
435
)
436
437
print(f"Emergency failover initiated: {operation.name}")
438
439
# Monitor progress
440
start_time = time.time()
441
while not operation.done():
442
elapsed = time.time() - start_time
443
print(f"Failover in progress... ({elapsed:.0f}s elapsed)")
444
time.sleep(10)
445
operation.reload()
446
447
# Check result
448
if operation.error:
449
print(f"Failover failed: {operation.error}")
450
else:
451
result = operation.result()
452
print(f"Failover completed successfully!")
453
print(f"New primary location: {result.current_location_id}")
454
print(f"Instance state: {result.state}")
455
456
except Exception as e:
457
print(f"Emergency failover error: {e}")
458
459
# Usage for emergency situations
460
instance_name = "projects/my-project/locations/us-central1/instances/critical-redis"
461
462
# Normal failover with data protection
463
emergency_failover(instance_name, force=False)
464
465
# Force failover (use only in extreme emergencies)
466
# emergency_failover(instance_name, force=True)
467
```
468
469
## Best Practices
470
471
### Pre-Upgrade Checklist
472
473
```python
474
def pre_upgrade_checklist(instance_name: str, target_version: str):
475
"""Perform pre-upgrade validation and preparation."""
476
client = CloudRedisClient()
477
478
print("Pre-upgrade checklist:")
479
print("-" * 30)
480
481
# Get instance details
482
instance = client.get_instance(name=instance_name)
483
484
# Check 1: Instance state
485
if instance.state != instance.State.READY:
486
print(f"❌ Instance state: {instance.state} (should be READY)")
487
return False
488
print(f"✅ Instance state: {instance.state}")
489
490
# Check 2: Available versions
491
if target_version not in instance.available_maintenance_versions:
492
print(f"❌ Target version {target_version} not available")
493
print(f" Available: {instance.available_maintenance_versions}")
494
return False
495
print(f"✅ Target version {target_version} is available")
496
497
# Check 3: No pending maintenance
498
if instance.maintenance_schedule:
499
print(f"⚠️ Maintenance scheduled: {instance.maintenance_schedule.start_time}")
500
else:
501
print("✅ No pending maintenance")
502
503
# Check 4: Backup recommendation
504
print("⚠️ Recommendation: Create backup before upgrade")
505
506
print("-" * 30)
507
return True
508
509
# Run checklist before upgrade
510
if pre_upgrade_checklist(instance_name, "REDIS_7_X"):
511
print("Ready for upgrade!")
512
else:
513
print("Resolve issues before upgrading")
514
```