redis add sentinel slaveOnly filed (#1948)

This commit is contained in:
whosafe
2022-07-06 19:54:36 +08:00
committed by GitHub
parent ab929e465b
commit 80442efe94
5 changed files with 179 additions and 3 deletions

93
.github/workflows/docker-compose.yml vendored Normal file
View File

@ -0,0 +1,93 @@
version: '2'
services:
redis-master:
container_name: redis-master
image: 'bitnami/redis:latest'
environment:
- REDIS_REPLICATION_MODE=master
- REDIS_PASSWORD=111111
ports:
- 6380:6379
redis-slave1:
container_name: redis-slave1
image: 'bitnami/redis:latest'
environment:
- REDIS_REPLICATION_MODE=slave
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PASSWORD=111111
- REDIS_PASSWORD=111111
ports:
- 6381:6379
depends_on:
- redis-master
links:
- redis-master
redis-slave2:
container_name: redis-slave2
image: 'bitnami/redis:latest'
environment:
- REDIS_REPLICATION_MODE=slave
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PASSWORD=111111
- REDIS_PASSWORD=111111
ports:
- 6382:6379
depends_on:
- redis-master
links:
- redis-master
redis-sentinel-1:
container_name: redis-sentinel-1
image: 'bitnami/redis-sentinel:latest'
environment:
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PORT_NUMBER=6379
- REDIS_MASTER_PASSWORD=111111
depends_on:
- redis-master
- redis-slave1
- redis-slave2
ports:
- 26379:26379
links:
- redis-master
- redis-slave1
- redis-slave2
redis-sentinel-2:
container_name: redis-sentinel-2
image: 'bitnami/redis-sentinel:latest'
environment:
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PORT_NUMBER=6379
- REDIS_MASTER_PASSWORD=111111
depends_on:
- redis-master
- redis-slave1
- redis-slave2
links:
- redis-master
- redis-slave1
- redis-slave2
ports:
- 26380:26379
redis-sentinel-3:
container_name: redis-sentinel-3
image: 'bitnami/redis-sentinel:latest'
environment:
- REDIS_MASTER_HOST=redis-master
- REDIS_MASTER_PORT_NUMBER=6379
- REDIS_MASTER_PASSWORD=111111
depends_on:
- redis-master
- redis-slave1
- redis-slave2
ports:
- 26381:26379
links:
- redis-master
- redis-slave1
- redis-slave2

View File

@ -132,6 +132,9 @@ jobs:
with:
go-version: ${{ matrix.go }}
- name: Start containers
run: docker-compose -f ".github/workflows/docker-compose.yml" up -d --build
- name: Before Script
run: |
find . -name "*.go" | xargs gofmt -w
@ -161,6 +164,9 @@ jobs:
cd -
done
- name: Stop containers
run: docker-compose -f ".github/workflows/docker-compose.yml" down
- name: Report Coverage
uses: codecov/codecov-action@v2
with:

View File

@ -11,8 +11,8 @@ import (
"time"
"github.com/go-redis/redis/v8"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/text/gstr"
)
@ -34,7 +34,7 @@ const (
// NewAdapterGoRedis creates and returns a redis adapter using go-redis.
func NewAdapterGoRedis(config *Config) *AdapterGoRedis {
fillWithDefaultConfiguration(config)
client := redis.NewUniversalClient(&redis.UniversalOptions{
opts := &redis.UniversalOptions{
Addrs: gstr.SplitAndTrim(config.Address, ","),
Password: config.Pass,
DB: config.Db,
@ -48,7 +48,20 @@ func NewAdapterGoRedis(config *Config) *AdapterGoRedis {
WriteTimeout: config.WriteTimeout,
MasterName: config.MasterName,
TLSConfig: config.TLSConfig,
})
}
var client redis.UniversalClient
if opts.MasterName != "" {
redisSentinel := opts.Failover()
redisSentinel.SlaveOnly = config.SlaveOnly
client = redis.NewFailoverClient(redisSentinel)
} else if len(opts.Addrs) > 1 {
client = redis.NewClusterClient(opts.Cluster())
} else {
client = redis.NewClient(opts.Simple())
}
return &AdapterGoRedis{
client: client,
config: config,

View File

@ -36,6 +36,7 @@ type Config struct {
TLS bool `json:"tls"` // Specifies whether TLS should be used when connecting to the server.
TLSSkipVerify bool `json:"tlsSkipVerify"` // Disables server name verification when connecting over TLS.
TLSConfig *tls.Config `json:"-"` // TLS Config to use. When set TLS will be negotiated.
SlaveOnly bool `json:"slaveOnly"` // Route all commands to slave read-only nodes.
}
const (

View File

@ -0,0 +1,63 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gredis_test
import (
"context"
"testing"
"github.com/gogf/gf/v2/database/gredis"
"github.com/gogf/gf/v2/test/gtest"
)
var (
sentinelCtx = context.TODO()
sentinelConfig = &gredis.Config{
Address: `127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381`,
MasterName: `mymaster`,
Pass: "111111",
}
)
func TestConn_sentinel_master(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
sentinelConfig.SlaveOnly = false
redis, err := gredis.New(sentinelConfig)
t.AssertNil(err)
t.AssertNE(redis, nil)
defer redis.Close(sentinelCtx)
conn, err := redis.Conn(sentinelCtx)
t.AssertNil(err)
defer conn.Close(sentinelCtx)
_, err = conn.Do(sentinelCtx, "set", "test", "123")
t.AssertNil(err)
defer conn.Do(sentinelCtx, "del", "test")
r, err := conn.Do(sentinelCtx, "get", "test")
t.AssertNil(err)
t.Assert(r.String(), "123")
})
}
func TestConn_sentinel_slave(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
sentinelConfig.SlaveOnly = true
redis, err := gredis.New(sentinelConfig)
t.AssertNil(err)
t.AssertNE(redis, nil)
defer redis.Close(sentinelCtx)
conn, err := redis.Conn(sentinelCtx)
t.AssertNil(err)
defer conn.Close(sentinelCtx)
_, err = conn.Do(sentinelCtx, "set", "test", "123")
t.AssertNQ(err, nil)
})
}