Skip to content

Commit

Permalink
Reduce observable downtime in senticache mode
Browse files Browse the repository at this point in the history
  • Loading branch information
secwall committed Nov 1, 2024
1 parent a20d793 commit 7257a72
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 14 deletions.
19 changes: 9 additions & 10 deletions internal/app/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@ import (
"github.com/yandex/rdsync/internal/redis"
)

func (app *App) updateCache() error {
func (app *App) updateCache(refState map[string]*HostState, cache *redis.SentiCacheNode) error {
var state redis.SentiCacheState
masterReadOnly := false
dcsState, err := app.getShardStateFromDcs()
if err != nil {
return err
}
for fqdn, hostState := range dcsState {
for fqdn, hostState := range refState {
if hostState == nil || !hostState.PingOk || hostState.Error != "" {
continue
}
Expand Down Expand Up @@ -53,7 +49,7 @@ func (app *App) updateCache() error {
}
state.Master.Port = app.config.Redis.Port
state.Master.RunID = hostState.RunID
state.Master.Quorum = len(dcsState)/2 + 1
state.Master.Quorum = len(refState)/2 + 1
state.Master.ParallelSyncs = app.config.Redis.MaxParallelSyncs
state.Master.ConfigEpoch = 0
} else {
Expand Down Expand Up @@ -84,17 +80,20 @@ func (app *App) updateCache() error {
}
}
if state.Master.IP == "" {
return fmt.Errorf("0 open masters within %d hosts", len(dcsState))
return fmt.Errorf("0 open masters within %d hosts", len(refState))
}
return app.cache.Update(app.ctx, &state)
return cache.Update(app.ctx, &state)
}

func (app *App) cacheUpdater() {
ticker := time.NewTicker(app.config.TickInterval)
for {
select {
case <-ticker.C:
err := app.updateCache()
dcsState, err := app.getShardStateFromDcs()
if err == nil {
err = app.updateCache(dcsState, app.cache)
}
if err != nil {
app.logger.Error("CacheUpdater: failed to update cache", "error", err)
}
Expand Down
20 changes: 20 additions & 0 deletions internal/app/switchover.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/yandex/rdsync/internal/dcs"
"github.com/yandex/rdsync/internal/redis"
)

const (
Expand Down Expand Up @@ -451,6 +452,25 @@ func (app *App) performSwitchover(shardState map[string]*HostState, activeNodes

app.repairMaster(newMasterNode, psyncActiveNodes, shardState[newMaster])

if app.mode == modeSentinel {
shardState, err = app.getShardStateFromDB()
if err == nil {
sentiCacheUpdateErrs := runParallel(func(host string) error {
sentiCacheNode, err := redis.NewRemoteSentiCacheNode(app.config, host, app.logger)
if err != nil {
return err
}
return app.updateCache(shardState, sentiCacheNode)
}, activeNodes)
combined := combineErrors(sentiCacheUpdateErrs)
if combined != nil {
app.logger.Warn("Unable to notify all senticache nodes on new master", "error", combined)
}
} else {
app.logger.Warn("Unable to get state for senticache nodes notify on new master", "error", err)
}
}

errs := runParallel(func(host string) error {
if host == newMaster || !shardState[host].PingOk {
return nil
Expand Down
13 changes: 9 additions & 4 deletions internal/redis/senticache.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ type SentiCacheNode struct {
broken bool
}

// NewSentiCacheNode is a SentiCacheNode constructor
func NewSentiCacheNode(config *config.Config, logger *slog.Logger) (*SentiCacheNode, error) {
addr := net.JoinHostPort(localhost, strconv.Itoa(config.SentinelMode.CachePort))
// NewRemoteSentiCacheNode is a remote SentiCacheNode constructor
func NewRemoteSentiCacheNode(config *config.Config, host string, logger *slog.Logger) (*SentiCacheNode, error) {
addr := net.JoinHostPort(host, strconv.Itoa(config.SentinelMode.CachePort))
opts := client.Options{
Addr: addr,
Username: config.SentinelMode.CacheAuthUser,
Expand All @@ -78,7 +78,7 @@ func NewSentiCacheNode(config *config.Config, logger *slog.Logger) (*SentiCacheN
Protocol: 2,
}
if config.SentinelMode.UseTLS {
tlsConf, err := getTLSConfig(config, config.SentinelMode.TLSCAPath, localhost)
tlsConf, err := getTLSConfig(config, config.SentinelMode.TLSCAPath, host)
if err != nil {
return nil, err
}
Expand All @@ -93,6 +93,11 @@ func NewSentiCacheNode(config *config.Config, logger *slog.Logger) (*SentiCacheN
return &node, nil
}

// NewSentiCacheNode is a local SentiCacheNode constructor
func NewSentiCacheNode(config *config.Config, logger *slog.Logger) (*SentiCacheNode, error) {
return NewRemoteSentiCacheNode(config, localhost, logger)
}

// Close closes underlying Redis connection
func (s *SentiCacheNode) Close() error {
return s.conn.Close()
Expand Down

0 comments on commit 7257a72

Please sign in to comment.