Files
juwan-backend/common/redisx/cluster.go
T

97 lines
2.0 KiB
Go

package redisx
import (
"context"
"time"
"github.com/redis/go-redis/v9"
"github.com/zeromicro/go-zero/core/stores/cache"
)
type MasterSlaveCluster struct {
Client *redis.ClusterClient
MasterHost string
SlaveHost string
HasSlave bool
}
func NewMasterSlaveCluster(cacheConf cache.CacheConf) *MasterSlaveCluster {
cacheConf = filterCacheConf(cacheConf)
if len(cacheConf) == 0 {
return &MasterSlaveCluster{}
}
master := cacheConf[0]
slave := cacheConf[0]
hasSlave := len(cacheConf) > 1
if hasSlave {
slave = cacheConf[1]
}
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{master.Host},
Username: master.User,
Password: master.Pass,
ReadOnly: hasSlave,
ClusterSlots: func(ctx context.Context) ([]redis.ClusterSlot, error) {
nodes := []redis.ClusterNode{{Addr: master.Host}}
if hasSlave {
nodes = append(nodes, redis.ClusterNode{Addr: slave.Host})
}
return []redis.ClusterSlot{{
Start: 0,
End: 16383,
Nodes: nodes,
}}, nil
},
})
return &MasterSlaveCluster{
Client: client,
MasterHost: master.Host,
SlaveHost: slave.Host,
HasSlave: hasSlave,
}
}
func ConnectMasterSlaveCluster(cacheConf cache.CacheConf, timeout time.Duration) (*MasterSlaveCluster, error) {
cluster := NewMasterSlaveCluster(cacheConf)
if cluster == nil || cluster.Client == nil {
return cluster, nil
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
if err := cluster.Ping(ctx); err != nil {
return cluster, err
}
return cluster, nil
}
func (m *MasterSlaveCluster) Ping(ctx context.Context) error {
if m == nil || m.Client == nil {
return nil
}
return m.Client.Ping(ctx).Err()
}
func filterCacheConf(cacheConf cache.CacheConf) cache.CacheConf {
if len(cacheConf) == 0 {
return cacheConf
}
filtered := make(cache.CacheConf, 0, len(cacheConf))
for _, node := range cacheConf {
if node.Host == "" {
continue
}
filtered = append(filtered, node)
}
return filtered
}