redis.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package cache
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/go-redis/redis/v7"
  6. )
  7. // RedisConfig config
  8. type RedisConfig struct {
  9. Addr string
  10. Password string
  11. DialTimeout time.Duration
  12. ReadTimeout time.Duration
  13. WriteTimeout time.Duration
  14. PoolTimeout time.Duration
  15. PoolSize int
  16. }
  17. // RedisClusterConfig redis cluster configure
  18. type RedisClusterConfig struct {
  19. // A seed list of host:port addresses of cluster nodes.
  20. Addrs []string
  21. // The maximum number of retries before giving up. Command is retried
  22. // on network errors and MOVED/ASK redirects.
  23. // Default is 16.
  24. MaxRedirects int
  25. // Enables read-only commands on slave nodes.
  26. ReadOnly bool
  27. // Allows routing read-only commands to the closest master or slave node.
  28. RouteByLatency bool
  29. //OnConnect func(*Conn) error
  30. MaxRetries int
  31. MinRetryBackoff time.Duration
  32. MaxRetryBackoff time.Duration
  33. Password string
  34. DialTimeout time.Duration
  35. ReadTimeout time.Duration
  36. WriteTimeout time.Duration
  37. // PoolSize applies per cluster node and not for the whole cluster.
  38. PoolSize int
  39. PoolTimeout time.Duration
  40. IdleTimeout time.Duration
  41. IdleCheckFrequency time.Duration
  42. }
  43. var (
  44. redisConfig RedisConfig
  45. redisClusterConfig RedisClusterConfig
  46. once sync.Once
  47. cache *RedisCache
  48. isCluster bool
  49. )
  50. // RedisCache define
  51. type RedisCache struct {
  52. c *redis.Client
  53. cc *redis.ClusterClient
  54. }
  55. // SetRedisConfig set
  56. func SetRedisConfig(cfg RedisConfig) {
  57. redisConfig = cfg
  58. }
  59. // SetRedisClusterConfig set
  60. func SetRedisClusterConfig(cfg RedisClusterConfig) {
  61. redisClusterConfig = cfg
  62. }
  63. // NewRedisCache new RedisCache object
  64. func NewRedisCache() *RedisCache {
  65. client := redis.NewClient(&redis.Options{
  66. Addr: redisConfig.Addr,
  67. Password: redisConfig.Password,
  68. DialTimeout: redisConfig.DialTimeout,
  69. ReadTimeout: redisConfig.ReadTimeout,
  70. WriteTimeout: redisConfig.WriteTimeout,
  71. PoolSize: redisConfig.PoolSize,
  72. PoolTimeout: redisConfig.PoolTimeout,
  73. })
  74. client.Ping().Result()
  75. return &RedisCache{c: client}
  76. }
  77. // NewRedisClusterCache new RedisCluster object
  78. func NewRedisClusterCache() *RedisCache {
  79. var config redis.ClusterOptions
  80. config.Addrs = redisClusterConfig.Addrs
  81. config.Password = redisClusterConfig.Password
  82. config.DialTimeout = redisClusterConfig.DialTimeout
  83. config.ReadTimeout = redisClusterConfig.ReadTimeout
  84. config.WriteTimeout = redisClusterConfig.WriteTimeout
  85. config.PoolSize = redisClusterConfig.PoolSize
  86. config.PoolTimeout = redisClusterConfig.PoolTimeout
  87. config.IdleTimeout = redisClusterConfig.IdleTimeout
  88. config.IdleCheckFrequency = redisClusterConfig.IdleCheckFrequency
  89. client := redis.NewClusterClient(&config)
  90. client.Ping()
  91. return &RedisCache{cc: client}
  92. }
  93. // Get get value from cache
  94. func (c RedisCache) Get(key string) (string, error) {
  95. if c.cc != nil {
  96. return c.cc.Get(key).Result()
  97. }
  98. return c.c.Get(key).Result()
  99. }
  100. // Set set key-value to cache
  101. func (c RedisCache) Set(key, value string, expiration time.Duration) error {
  102. if c.cc != nil {
  103. return c.cc.Set(key, value, expiration).Err()
  104. }
  105. return c.c.Set(key, value, expiration).Err()
  106. }
  107. // Del Del value from cache
  108. func (c RedisCache) Del(key string) (int64, error) {
  109. if c.cc != nil {
  110. return c.cc.Del(key).Result()
  111. }
  112. return c.c.Del(key).Result()
  113. }
  114. // Subscribe subscribe message
  115. func (c RedisCache) Subscribe(channels string, cb func(channel string, message string, err error)) {
  116. pubsub := &redis.PubSub{}
  117. if c.cc != nil {
  118. pubsub = c.cc.Subscribe(channels)
  119. } else {
  120. pubsub = c.c.Subscribe(channels)
  121. }
  122. defer pubsub.Close()
  123. var (
  124. msg *redis.Message
  125. err error
  126. )
  127. msg, err = pubsub.ReceiveMessage()
  128. for err == nil {
  129. cb(msg.Channel, msg.Payload, nil)
  130. msg, err = pubsub.ReceiveMessage()
  131. }
  132. cb("", "", err)
  133. return
  134. }
  135. // Publish publish message
  136. func (c RedisCache) Publish(channel, message string) error {
  137. return c.c.Publish(channel, message).Err()
  138. }
  139. // PublishCluster publish message
  140. func (c RedisCache) PublishCluster(channel, message string) error {
  141. return c.cc.Publish(channel, message).Err()
  142. }
  143. func connect() (*RedisCache, error) {
  144. if cache != nil {
  145. return cache, nil
  146. }
  147. //*
  148. var err error
  149. once.Do(func() {
  150. isCluster = false
  151. if len(redisConfig.Addr) > 0 {
  152. cache = NewRedisCache()
  153. }
  154. if len(redisClusterConfig.Addrs) > 0 {
  155. cache = NewRedisClusterCache()
  156. isCluster = true
  157. }
  158. })
  159. //*/
  160. return cache, err
  161. }
  162. // Get key from cache
  163. func Get(key string) (string, error) {
  164. c, err := connect()
  165. if err != nil {
  166. return "", err
  167. }
  168. return c.Get(key)
  169. }
  170. // Set key-value to cache
  171. func Set(key, value string, expiration time.Duration) error {
  172. c, err := connect()
  173. if err != nil {
  174. return err
  175. }
  176. return c.Set(key, value, expiration)
  177. }
  178. // Del delete key from cache
  179. func Del(key string) (int64, error) {
  180. c, err := connect()
  181. if err != nil {
  182. return 0, err
  183. }
  184. return c.Del(key)
  185. }