97 lines
2.0 KiB
Go
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
|
|
}
|