redis.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package cache
  2. import (
  3. "context"
  4. "errors"
  5. "time"
  6. "github.com/go-redis/redis/v8"
  7. )
  8. var (
  9. ctx = context.Background()
  10. defaultRedis *RedisCache
  11. )
  12. // RedisOptions options
  13. type RedisOptions struct {
  14. DB int
  15. PoolSize int
  16. DialTimeout time.Duration
  17. ReadTimeout time.Duration
  18. WriteTimeout time.Duration
  19. PoolTimeout time.Duration
  20. Password string
  21. Addr string
  22. }
  23. // RedisClusterOptions cluster option
  24. type RedisClusterOptions struct {
  25. DB int
  26. PoolSize int
  27. MaxRetries int
  28. MinRetryBackoff time.Duration
  29. MaxRetryBackoff time.Duration
  30. DialTimeout time.Duration
  31. ReadTimeout time.Duration
  32. WriteTimeout time.Duration
  33. PoolTimeout time.Duration
  34. IdleTimeout time.Duration
  35. IdleCheckFrequency time.Duration
  36. Password string
  37. Addrs []string
  38. }
  39. // RedisCache define
  40. type RedisCache struct {
  41. cluster bool
  42. ps *redis.PubSub
  43. c *redis.Client
  44. cc *redis.ClusterClient
  45. }
  46. // NewRedisCache new RedisCache object
  47. func NewRedisCache(opt RedisOptions) (rc *RedisCache, err error) {
  48. rc = new(RedisCache)
  49. c := redis.NewClient(&redis.Options{
  50. Addr: opt.Addr,
  51. Password: opt.Password,
  52. DialTimeout: opt.DialTimeout,
  53. ReadTimeout: opt.ReadTimeout,
  54. WriteTimeout: opt.WriteTimeout,
  55. PoolSize: opt.PoolSize,
  56. PoolTimeout: opt.PoolTimeout,
  57. })
  58. _, err = c.Ping(ctx).Result()
  59. rc.c = c
  60. rc.cluster = false
  61. return
  62. }
  63. // NewRedisClusterCache new RedisCluster object
  64. func NewRedisClusterCache(opt RedisClusterOptions) (rc *RedisCache, err error) {
  65. rc = new(RedisCache)
  66. var cfg redis.ClusterOptions
  67. cfg.Addrs = opt.Addrs
  68. cfg.Password = opt.Password
  69. cfg.DialTimeout = opt.DialTimeout
  70. cfg.ReadTimeout = opt.ReadTimeout
  71. cfg.WriteTimeout = opt.WriteTimeout
  72. cfg.PoolSize = opt.PoolSize
  73. cfg.PoolTimeout = opt.PoolTimeout
  74. cfg.IdleTimeout = opt.IdleTimeout
  75. cfg.IdleCheckFrequency = opt.IdleCheckFrequency
  76. c := redis.NewClusterClient(&cfg)
  77. _, err = c.Ping(ctx).Result()
  78. rc.cc = c
  79. rc.cluster = true
  80. return
  81. }
  82. // Get get value from cache
  83. func (c RedisCache) Get(k string) (string, error) {
  84. if c.cluster {
  85. return c.cc.Get(ctx, k).Result()
  86. }
  87. return c.c.Get(ctx, k).Result()
  88. }
  89. // Set key-value to cache
  90. func (c RedisCache) Set(k, v string, expiration time.Duration) (string, error) {
  91. if c.cluster {
  92. return c.cc.Set(ctx, k, v, expiration).Result()
  93. }
  94. return c.c.Set(ctx, k, v, expiration).Result()
  95. }
  96. // Del delete key from cache
  97. func (c RedisCache) Del(ks ...string) (int64, error) {
  98. if c.cluster {
  99. return c.cc.Del(ctx, ks...).Result()
  100. }
  101. return c.c.Del(ctx, ks...).Result()
  102. }
  103. // Publish posts the message to the channel.
  104. func (c RedisCache) Publish(channel string, message interface{}) (int64, error) {
  105. if c.cluster {
  106. return c.cc.Publish(ctx, channel, message).Result()
  107. }
  108. return c.c.Publish(ctx, channel, message).Result()
  109. }
  110. // Subscribe subscribes the client to the specified channels.
  111. func (c *RedisCache) Subscribe(channels ...string) error {
  112. if c.cluster {
  113. c.ps = c.cc.Subscribe(ctx, channels...)
  114. } else {
  115. c.ps = c.c.Subscribe(ctx, channels...)
  116. }
  117. return c.ps.Ping(ctx)
  118. }
  119. // CloseSubscribe close
  120. func (c *RedisCache) CloseSubscribe() error {
  121. if c.ps == nil {
  122. return nil
  123. }
  124. return c.ps.Close()
  125. }
  126. // Unsubscribe the client from the given channels, or from all of them if none is given.
  127. func (c *RedisCache) Unsubscribe(channels ...string) error {
  128. if c.ps == nil {
  129. return nil
  130. }
  131. return c.ps.Unsubscribe(ctx, channels...)
  132. }
  133. // ReceiveSubscribeMessage returns a Message or error ignoring Subscription and Pong messages. This is low-level API and in most cases Channel should be used instead.
  134. func (c *RedisCache) ReceiveSubscribeMessage() (channel, message string, err error) {
  135. if c.ps == nil {
  136. err = errors.New("not init subscribe")
  137. return
  138. }
  139. var msg *redis.Message
  140. msg, err = c.ps.ReceiveMessage(ctx)
  141. if err != nil {
  142. return
  143. }
  144. channel = msg.Channel
  145. message = msg.Payload
  146. return
  147. }
  148. // Info redis info
  149. func (c RedisCache) Info(section ...string) (string, error) {
  150. if c.cluster {
  151. return c.cc.Info(ctx, section...).Result()
  152. }
  153. return c.c.Info(ctx, section...).Result()
  154. }
  155. // ClusterInfo redis cluster info
  156. func (c RedisCache) ClusterInfo() (string, error) {
  157. if c.cluster {
  158. return c.cc.ClusterInfo(ctx).Result()
  159. }
  160. return c.c.ClusterInfo(ctx).Result()
  161. }
  162. // SetDefaultRedisOption set default option
  163. func SetDefaultRedisOption(opt RedisOptions) (err error) {
  164. defaultRedis, err = NewRedisCache(opt)
  165. return
  166. }
  167. // SetDefaultRedisClusterOption set default cluster option
  168. func SetDefaultRedisClusterOption(opt RedisClusterOptions) (err error) {
  169. defaultRedis, err = NewRedisClusterCache(opt)
  170. return
  171. }
  172. // RedisGet get value from cache
  173. func RedisGet(k string) (string, error) {
  174. return defaultRedis.Get(k)
  175. }
  176. // RedisSet key-value to cache
  177. func RedisSet(k, v string, expiration time.Duration) (string, error) {
  178. return defaultRedis.Set(k, v, expiration)
  179. }
  180. // RedisDel delete keys from cache
  181. func RedisDel(keys ...string) (int64, error) {
  182. return defaultRedis.Del(keys...)
  183. }
  184. // RedisInfo redis info
  185. func RedisInfo(section ...string) (string, error) {
  186. return defaultRedis.Info(section...)
  187. }
  188. // RedisClusterInfo redis cluster info
  189. func RedisClusterInfo() (string, error) {
  190. return defaultRedis.ClusterInfo()
  191. }
  192. // Publish posts the message to the channel.
  193. func RedisPublish(channel string, message interface{}) (int64, error) {
  194. return defaultRedis.Publish(channel, message)
  195. }
  196. // Subscribe subscribes the client to the specified channels.
  197. func RedisSubscribe(channels ...string) error {
  198. return defaultRedis.Subscribe(channels...)
  199. }
  200. // RedisCloseSubscribe close
  201. func RedisCloseSubscribe() error {
  202. return defaultRedis.CloseSubscribe()
  203. }
  204. // Unsubscribe the client from the given channels, or from all of them if none is given.
  205. func RedisUnsubscribe(channels ...string) error {
  206. return defaultRedis.Unsubscribe(channels...)
  207. }
  208. // RedisReceiveSubscribeMessage returns a Message or error ignoring Subscription and Pong messages. This is low-level API and in most cases Channel should be used instead.
  209. func RedisReceiveSubscribeMessage() (channel, message string, err error) {
  210. return defaultRedis.ReceiveSubscribeMessage()
  211. }