mirror of
https://github.com/redis/go-redis.git
synced 2025-12-02 06:22:31 +03:00
* fix(pool): wip, pool reauth should not interfere with handoff * fix credListeners map * fix race in tests * better conn usable timeout * add design decision comment * few small improvements * update marked as queued * add Used to clarify the state of the conn * rename test * fix(test): fix flaky test * lock inside the listeners collection * address pr comments * Update internal/auth/cred_listeners.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update internal/pool/buffer_size_test.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * wip refactor entraid * fix maintnotif pool hook * fix mocks * fix nil listener * sync and async reauth based on conn lifecycle * be able to reject connection OnGet * pass hooks so the tests can observe reauth * give some time for the background to execute commands * fix tests * only async reauth * Update internal/pool/pool.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update internal/auth/streaming/pool_hook.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update internal/pool/conn.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore(redisotel): use metric.WithAttributeSet to avoid copy (#3552) In order to improve performance replace `WithAttributes` with `WithAttributeSet`. This avoids the slice allocation and copy that is done in `WithAttributes`. For more information see https://github.com/open-telemetry/opentelemetry-go/blob/v1.38.0/metric/instrument.go#L357-L376 * chore(docs): explain why MaxRetries is disabled for ClusterClient (#3551) Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * exponential backoff * address pr comments * address pr comments * remove rlock * add some comments * add comments --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Warnar Boekkooi <wboekkooi@impossiblecloud.com> Co-authored-by: Justin <justindsouza80@gmail.com>
Maintenance Notifications
Seamless Redis connection handoffs during cluster maintenance operations without dropping connections.
⚠️ Important Note
Maintenance notifications are currently supported only in standalone Redis clients. Cluster clients (ClusterClient, FailoverClient, etc.) do not yet support this functionality.
Quick Start
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Protocol: 3, // RESP3 required
MaintNotificationsConfig: &maintnotifications.Config{
Mode: maintnotifications.ModeEnabled,
},
})
Modes
ModeDisabled- Maintenance notifications disabledModeEnabled- Forcefully enabled (fails if server doesn't support)ModeAuto- Auto-detect server support (default)
Configuration
&maintnotifications.Config{
Mode: maintnotifications.ModeAuto,
EndpointType: maintnotifications.EndpointTypeAuto,
RelaxedTimeout: 10 * time.Second,
HandoffTimeout: 15 * time.Second,
MaxHandoffRetries: 3,
MaxWorkers: 0, // Auto-calculated
HandoffQueueSize: 0, // Auto-calculated
PostHandoffRelaxedDuration: 0, // 2 * RelaxedTimeout
}
Endpoint Types
EndpointTypeAuto- Auto-detect based on connection (default)EndpointTypeInternalIP- Internal IP addressEndpointTypeInternalFQDN- Internal FQDNEndpointTypeExternalIP- External IP addressEndpointTypeExternalFQDN- External FQDNEndpointTypeNone- No endpoint (reconnect with current config)
Auto-Scaling
Workers: min(PoolSize/2, max(10, PoolSize/3)) when auto-calculated
Queue: max(20×Workers, PoolSize) capped by MaxActiveConns+1 or 5×PoolSize
Examples:
- Pool 100: 33 workers, 660 queue (capped at 500)
- Pool 100 + MaxActiveConns 150: 33 workers, 151 queue
How It Works
- Redis sends push notifications about cluster maintenance operations
- Client creates new connections to updated endpoints
- Active operations transfer to new connections
- Old connections close gracefully
Supported Notifications
MOVING- Slot moving to new nodeMIGRATING- Slot in migration stateMIGRATED- Migration completedFAILING_OVER- Node failing overFAILED_OVER- Failover completed
Hooks (Optional)
Monitor and customize maintenance notification operations:
type NotificationHook interface {
PreHook(ctx, notificationCtx, notificationType, notification) ([]interface{}, bool)
PostHook(ctx, notificationCtx, notificationType, notification, result)
}
// Add custom hook
manager.AddNotificationHook(&MyHook{})
Metrics Hook Example
// Create metrics hook
metricsHook := maintnotifications.NewMetricsHook()
manager.AddNotificationHook(metricsHook)
// Access collected metrics
metrics := metricsHook.GetMetrics()
fmt.Printf("Notification counts: %v\n", metrics["notification_counts"])
fmt.Printf("Processing times: %v\n", metrics["processing_times"])
fmt.Printf("Error counts: %v\n", metrics["error_counts"])