Skip to content

Commit

Permalink
Change redis client logic and deprecate hosts with addrs in redis conf (
Browse files Browse the repository at this point in the history
TykTechnologies#2765)

This PR deprecates `hosts` field in redis configuration. Instead `addrs` is defined. Example:
```
"addrs": [
"localhost:30001",
"localhost:30002",
"localhost:30003"
],
```

Also, this PR changes the redis client definition logic. The old version was defining cluster client if given address number is more than one. Otherwise, it was defining a simple redis client.
With this PR, if `enable_cluster` is `true`, the client will be automatically defined as cluster client no matter number of given addresses in config.

Fixes TykTechnologies#2742
  • Loading branch information
furkansenharputlu authored and buger committed Dec 26, 2019
1 parent ead67c6 commit 8e75109
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 16 deletions.
10 changes: 8 additions & 2 deletions cli/linter/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
"null"
]
},
"addrs": {
"type": [
"array",
"null"
]
},
"optimisation_max_active": {
"type": "integer"
},
Expand Down Expand Up @@ -1030,8 +1036,8 @@
"enable_http_profiler": {
"type": "boolean"
},
"ssl_force_common_name_check":{
"type":"boolean"
"ssl_force_common_name_check": {
"type": "boolean"
}
}
}
3 changes: 2 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ type StorageOptionsConf struct {
Type string `json:"type"`
Host string `json:"host"`
Port int `json:"port"`
Hosts map[string]string `json:"hosts"`
Hosts map[string]string `json:"hosts"` // Deprecated: Addrs instead.
Addrs []string `json:"addrs"`
Username string `json:"username"`
Password string `json:"password"`
Database int `json:"database"`
Expand Down
102 changes: 89 additions & 13 deletions storage/redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ func NewRedisClusterPool(isCache bool) redis.UniversalClient {
poolSize = cfg.MaxActive
}

if cfg.EnableCluster {
log.Info("--> Using clustered mode")
}

timeout := 5 * time.Second

if cfg.Timeout > 0 {
Expand All @@ -127,9 +123,13 @@ func NewRedisClusterPool(isCache bool) redis.UniversalClient {

var seedHosts []string

for h, p := range cfg.Hosts {
addr := h + ":" + p
seedHosts = append(seedHosts, addr)
if len(cfg.Addrs) != 0 {
seedHosts = cfg.Addrs
} else {
for h, p := range cfg.Hosts {
addr := h + ":" + p
seedHosts = append(seedHosts, addr)
}
}

if len(seedHosts) == 0 {
Expand All @@ -145,11 +145,8 @@ func NewRedisClusterPool(isCache bool) redis.UniversalClient {
}
}

if !cfg.EnableCluster {
seedHosts = seedHosts[:1]
}

client := redis.NewUniversalClient(&redis.UniversalOptions{
var client redis.UniversalClient
opts := &RedisOpts{
Addrs: seedHosts,
Password: cfg.Password,
DB: cfg.Database,
Expand All @@ -159,11 +156,90 @@ func NewRedisClusterPool(isCache bool) redis.UniversalClient {
IdleTimeout: 240 * timeout,
PoolSize: poolSize,
TLSConfig: tlsConfig,
})
}

if cfg.EnableCluster {
log.Info("--> [REDIS] Using clustered mode")
client = redis.NewClusterClient(opts.cluster())
} else {
log.Info("--> [REDIS] Using single node mode")
client = redis.NewClient(opts.simple())
}

return client
}

// RedisOpts is the overriden type of redis.UniversalOptions. simple() and cluster() functions are not public
// in redis library. Therefore, they are redefined in here to use in creation of new redis cluster logic.
// We don't want to use redis.NewUniversalClient() logic.
type RedisOpts redis.UniversalOptions

func (o *RedisOpts) cluster() *redis.ClusterOptions {
if len(o.Addrs) == 0 {
o.Addrs = []string{"127.0.0.1:6379"}
}

return &redis.ClusterOptions{
Addrs: o.Addrs,
OnConnect: o.OnConnect,

Password: o.Password,

MaxRedirects: o.MaxRedirects,
ReadOnly: o.ReadOnly,
RouteByLatency: o.RouteByLatency,
RouteRandomly: o.RouteRandomly,

MaxRetries: o.MaxRetries,
MinRetryBackoff: o.MinRetryBackoff,
MaxRetryBackoff: o.MaxRetryBackoff,

DialTimeout: o.DialTimeout,
ReadTimeout: o.ReadTimeout,
WriteTimeout: o.WriteTimeout,
PoolSize: o.PoolSize,
MinIdleConns: o.MinIdleConns,
MaxConnAge: o.MaxConnAge,
PoolTimeout: o.PoolTimeout,
IdleTimeout: o.IdleTimeout,
IdleCheckFrequency: o.IdleCheckFrequency,

TLSConfig: o.TLSConfig,
}
}

func (o *RedisOpts) simple() *redis.Options {
addr := "127.0.0.1:6379"
if len(o.Addrs) > 0 {
addr = o.Addrs[0]
}

return &redis.Options{
Addr: addr,
OnConnect: o.OnConnect,

DB: o.DB,
Password: o.Password,

MaxRetries: o.MaxRetries,
MinRetryBackoff: o.MinRetryBackoff,
MaxRetryBackoff: o.MaxRetryBackoff,

DialTimeout: o.DialTimeout,
ReadTimeout: o.ReadTimeout,
WriteTimeout: o.WriteTimeout,

PoolSize: o.PoolSize,
MinIdleConns: o.MinIdleConns,
MaxConnAge: o.MaxConnAge,
PoolTimeout: o.PoolTimeout,
IdleTimeout: o.IdleTimeout,
IdleCheckFrequency: o.IdleCheckFrequency,

TLSConfig: o.TLSConfig,
}
}

// Connect will establish a connection to the r.singleton()
func (r *RedisCluster) Connect() bool {
redisSingletonMu.Lock()
Expand Down

0 comments on commit 8e75109

Please sign in to comment.