redis.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. package cache
  2. import (
  3. "sync"
  4. "time"
  5. "github.com/go-redis/redis"
  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. /*
  82. config.MaxRedirects = redisClusterConfig.MaxRedirects
  83. config.ReadOnly = redisClusterConfig.ReadOnly
  84. config.RouteByLatency = redisClusterConfig.RouteByLatency
  85. config.MaxRetries = redisClusterConfig.MaxRetries
  86. config.MinRetryBackoff = redisClusterConfig.MinRetryBackoff
  87. config.MaxRetryBackoff = redisClusterConfig.MaxRetryBackoff
  88. // */
  89. config.Password = redisClusterConfig.Password
  90. config.DialTimeout = redisClusterConfig.DialTimeout
  91. config.ReadTimeout = redisClusterConfig.ReadTimeout
  92. config.WriteTimeout = redisClusterConfig.WriteTimeout
  93. config.PoolSize = redisClusterConfig.PoolSize
  94. config.PoolTimeout = redisClusterConfig.PoolTimeout
  95. config.IdleTimeout = redisClusterConfig.IdleTimeout
  96. config.IdleCheckFrequency = redisClusterConfig.IdleCheckFrequency
  97. client := redis.NewClusterClient(&config)
  98. client.Ping()
  99. return &RedisCache{cc: client}
  100. }
  101. // Get get value from cache
  102. func (c RedisCache) Get(key string) (string, error) {
  103. return c.c.Get(key).Result()
  104. }
  105. // GetCluster get value from cluster cache
  106. func (c RedisCache) GetCluster(key string) (string, error) {
  107. return c.cc.Get(key).Result()
  108. }
  109. // Set set key-value to cache
  110. func (c RedisCache) Set(key, value string, expiration time.Duration) error {
  111. return c.c.Set(key, value, expiration).Err()
  112. }
  113. // SetCluster set key-value to cache
  114. func (c RedisCache) SetCluster(key, value string, expiration time.Duration) error {
  115. return c.cc.Set(key, value, expiration).Err()
  116. }
  117. // Del Del value from cache
  118. func (c RedisCache) Del(key string) (int64, error) {
  119. return c.c.Del(key).Result()
  120. }
  121. // DelCluster Del value from cluster cache
  122. func (c RedisCache) DelCluster(key string) (int64, error) {
  123. return c.cc.Del(key).Result()
  124. }
  125. // Subscribe subscribe message
  126. func (c RedisCache) Subscribe(channels string, cb func(channel string, message string, err error)) {
  127. pubsub := c.c.Subscribe(channels)
  128. defer pubsub.Close()
  129. var (
  130. msg *redis.Message
  131. err error
  132. )
  133. msg, err = pubsub.ReceiveMessage()
  134. for err == nil {
  135. cb(msg.Channel, msg.Payload, nil)
  136. msg, err = pubsub.ReceiveMessage()
  137. }
  138. cb("", "", err)
  139. return
  140. }
  141. // SubscribeCluster subscribe cluster message
  142. func (c RedisCache) SubscribeCluster(channels string, cb func(channel string, message string, err error)) {
  143. pubsub := c.cc.Subscribe(channels)
  144. defer pubsub.Close()
  145. var (
  146. msg *redis.Message
  147. err error
  148. )
  149. msg, err = pubsub.ReceiveMessage()
  150. for err == nil {
  151. cb(msg.Channel, msg.Payload, nil)
  152. msg, err = pubsub.ReceiveMessage()
  153. }
  154. cb("", "", err)
  155. return
  156. }
  157. // Publish publish message
  158. func (c RedisCache) Publish(channel, message string) error {
  159. return c.c.Publish(channel, message).Err()
  160. }
  161. // PublishCluster publish message
  162. func (c RedisCache) PublishCluster(channel, message string) error {
  163. return c.cc.Publish(channel, message).Err()
  164. }
  165. func connect() (*RedisCache, error) {
  166. if cache != nil {
  167. return cache, nil
  168. }
  169. //*
  170. var err error
  171. once.Do(func() {
  172. isCluster = false
  173. if len(redisConfig.Addr) > 0 {
  174. cache = NewRedisCache()
  175. }
  176. if len(redisClusterConfig.Addrs) > 0 {
  177. cache = NewRedisClusterCache()
  178. isCluster = true
  179. }
  180. })
  181. //*/
  182. return cache, err
  183. }
  184. // Get key from cache
  185. func Get(key string) (string, error) {
  186. c, err := connect()
  187. if err != nil {
  188. return "", err
  189. }
  190. if isCluster {
  191. return c.GetCluster(key)
  192. }
  193. return c.Get(key)
  194. }
  195. // Set key-value to cache
  196. func Set(key, value string, expiration time.Duration) error {
  197. c, err := connect()
  198. if err != nil {
  199. return err
  200. }
  201. if isCluster {
  202. return c.SetCluster(key, value, expiration)
  203. }
  204. return c.Set(key, value, expiration)
  205. }
  206. // Del delete key from cache
  207. func Del(key string) (int64, error) {
  208. c, err := connect()
  209. if err != nil {
  210. return 0, err
  211. }
  212. if isCluster {
  213. return c.DelCluster(key)
  214. }
  215. return c.Del(key)
  216. }