Skip to content

Commit

Permalink
Support Redis Sentinel
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronDewes committed Jan 2, 2024
1 parent e9995cd commit 32f4c3a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
12 changes: 12 additions & 0 deletions configuration/configuration.go
Expand Up @@ -271,11 +271,23 @@ type FileChecker struct {
Threshold int `yaml:"threshold,omitempty"`
}

type RedisSentinel struct {
// MasterName specifies the name of the master sentinel.
MasterName string `yaml:"masterName,omitempty"`

// Addresses specifies the addresses of the sentinels.
Addresses []string `yaml:"addresses,omitempty"`
}

// Redis configures the redis pool available to the registry webapp.
type Redis struct {
// Addr specifies the the redis instance available to the application.
Addr string `yaml:"addr,omitempty"`

// Sentinel specifies the sentinel instance available to the application.
// If this is set, the Addr field is ignored.
Sentinel RedisSentinel `yaml:"sentinel,omitempty"`

// Usernames can be used as a finer-grained permission control since the introduction of the redis 6.0.
Username string `yaml:"username,omitempty"`

Expand Down
62 changes: 41 additions & 21 deletions registry/handlers/app.go
Expand Up @@ -487,12 +487,12 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
}

func (app *App) configureRedis(cfg *configuration.Configuration) {
if cfg.Redis.Addr == "" {
if cfg.Redis.Addr == "" && (len(cfg.Redis.Sentinel.Addresses) == 0 || cfg.Redis.Sentinel.MasterName == "") {
dcontext.GetLogger(app).Infof("redis not configured")
return
}

app.redis = app.createPool(cfg.Redis)
app.redis = app.createRedisClient(cfg.Redis)

// Enable metrics instrumentation.
if err := redisotel.InstrumentMetrics(app.redis); err != nil {
Expand All @@ -514,25 +514,45 @@ func (app *App) configureRedis(cfg *configuration.Configuration) {
}))
}

func (app *App) createPool(cfg configuration.Redis) *redis.Client {
return redis.NewClient(&redis.Options{
Addr: cfg.Addr,
OnConnect: func(ctx context.Context, cn *redis.Conn) error {
res := cn.Ping(ctx)
return res.Err()
},
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: 3,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolFIFO: false,
MaxIdleConns: cfg.Pool.MaxIdle,
PoolSize: cfg.Pool.MaxActive,
ConnMaxIdleTime: cfg.Pool.IdleTimeout,
})
func (app *App) createRedisClient(cfg configuration.Redis) *redis.Client {
// This function assumes that cfg.Addresses is not empty, which is checked by the caller.
if len(cfg.Sentinel.Addresses) > 0 && cfg.Sentinel.MasterName != "" {
return redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: cfg.Sentinel.MasterName,
SentinelAddrs: cfg.Sentinel.Addresses,
OnConnect: nil,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: 3,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolFIFO: false,
MaxIdleConns: cfg.Pool.MaxIdle,
PoolSize: cfg.Pool.MaxActive,
ConnMaxIdleTime: cfg.Pool.IdleTimeout,
})
} else {
return redis.NewClient(&redis.Options{
Addr: cfg.Addr,
OnConnect: func(ctx context.Context, cn *redis.Conn) error {
res := cn.Ping(ctx)
return res.Err()
},
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: 3,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolFIFO: false,
MaxIdleConns: cfg.Pool.MaxIdle,
PoolSize: cfg.Pool.MaxActive,
ConnMaxIdleTime: cfg.Pool.IdleTimeout,
})
}
}

// configureLogHook prepares logging hook parameters.
Expand Down

0 comments on commit 32f4c3a

Please sign in to comment.