github.com/shuguocloud/go-zero@v1.3.0/core/stores/kv/store.go (about)

     1  package kv
     2  
     3  import (
     4  	"errors"
     5  	"log"
     6  
     7  	"github.com/shuguocloud/go-zero/core/errorx"
     8  	"github.com/shuguocloud/go-zero/core/hash"
     9  	"github.com/shuguocloud/go-zero/core/stores/cache"
    10  	"github.com/shuguocloud/go-zero/core/stores/redis"
    11  )
    12  
    13  // ErrNoRedisNode is an error that indicates no redis node.
    14  var ErrNoRedisNode = errors.New("no redis node")
    15  
    16  type (
    17  	// Store interface represents a KV store.
    18  	Store interface {
    19  		Decr(key string) (int64, error)
    20  		Decrby(key string, increment int64) (int64, error)
    21  		Del(keys ...string) (int, error)
    22  		Eval(script, key string, args ...interface{}) (interface{}, error)
    23  		Exists(key string) (bool, error)
    24  		Expire(key string, seconds int) error
    25  		Expireat(key string, expireTime int64) error
    26  		Get(key string) (string, error)
    27  		Hdel(key, field string) (bool, error)
    28  		Hexists(key, field string) (bool, error)
    29  		Hget(key, field string) (string, error)
    30  		Hgetall(key string) (map[string]string, error)
    31  		Hincrby(key, field string, increment int) (int, error)
    32  		Hkeys(key string) ([]string, error)
    33  		Hlen(key string) (int, error)
    34  		Hmget(key string, fields ...string) ([]string, error)
    35  		Hset(key, field, value string) error
    36  		Hsetnx(key, field, value string) (bool, error)
    37  		Hmset(key string, fieldsAndValues map[string]string) error
    38  		Hvals(key string) ([]string, error)
    39  		Incr(key string) (int64, error)
    40  		Incrby(key string, increment int64) (int64, error)
    41  		Lindex(key string, index int64) (string, error)
    42  		Llen(key string) (int, error)
    43  		Lpop(key string) (string, error)
    44  		Lpush(key string, values ...interface{}) (int, error)
    45  		Lrange(key string, start, stop int) ([]string, error)
    46  		Lrem(key string, count int, value string) (int, error)
    47  		Persist(key string) (bool, error)
    48  		Pfadd(key string, values ...interface{}) (bool, error)
    49  		Pfcount(key string) (int64, error)
    50  		Rpush(key string, values ...interface{}) (int, error)
    51  		Sadd(key string, values ...interface{}) (int, error)
    52  		Scard(key string) (int64, error)
    53  		Set(key, value string) error
    54  		Setex(key, value string, seconds int) error
    55  		Setnx(key, value string) (bool, error)
    56  		SetnxEx(key, value string, seconds int) (bool, error)
    57  		Sismember(key string, value interface{}) (bool, error)
    58  		Smembers(key string) ([]string, error)
    59  		Spop(key string) (string, error)
    60  		Srandmember(key string, count int) ([]string, error)
    61  		Srem(key string, values ...interface{}) (int, error)
    62  		Sscan(key string, cursor uint64, match string, count int64) (keys []string, cur uint64, err error)
    63  		Ttl(key string) (int, error)
    64  		Zadd(key string, score int64, value string) (bool, error)
    65  		Zadds(key string, ps ...redis.Pair) (int64, error)
    66  		Zcard(key string) (int, error)
    67  		Zcount(key string, start, stop int64) (int, error)
    68  		Zincrby(key string, increment int64, field string) (int64, error)
    69  		Zrange(key string, start, stop int64) ([]string, error)
    70  		ZrangeWithScores(key string, start, stop int64) ([]redis.Pair, error)
    71  		ZrangebyscoreWithScores(key string, start, stop int64) ([]redis.Pair, error)
    72  		ZrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) ([]redis.Pair, error)
    73  		Zrank(key, field string) (int64, error)
    74  		Zrem(key string, values ...interface{}) (int, error)
    75  		Zremrangebyrank(key string, start, stop int64) (int, error)
    76  		Zremrangebyscore(key string, start, stop int64) (int, error)
    77  		Zrevrange(key string, start, stop int64) ([]string, error)
    78  		ZrevrangebyscoreWithScores(key string, start, stop int64) ([]redis.Pair, error)
    79  		ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) ([]redis.Pair, error)
    80  		Zscore(key, value string) (int64, error)
    81  		Zrevrank(key, field string) (int64, error)
    82  	}
    83  
    84  	clusterStore struct {
    85  		dispatcher *hash.ConsistentHash
    86  	}
    87  )
    88  
    89  // NewStore returns a Store.
    90  func NewStore(c KvConf) Store {
    91  	if len(c) == 0 || cache.TotalWeights(c) <= 0 {
    92  		log.Fatal("no cache nodes")
    93  	}
    94  
    95  	// even if only one node, we chose to use consistent hash,
    96  	// because Store and redis.Redis has different methods.
    97  	dispatcher := hash.NewConsistentHash()
    98  	for _, node := range c {
    99  		cn := node.NewRedis()
   100  		dispatcher.AddWithWeight(cn, node.Weight)
   101  	}
   102  
   103  	return clusterStore{
   104  		dispatcher: dispatcher,
   105  	}
   106  }
   107  
   108  func (cs clusterStore) Decr(key string) (int64, error) {
   109  	node, err := cs.getRedis(key)
   110  	if err != nil {
   111  		return 0, err
   112  	}
   113  
   114  	return node.Decr(key)
   115  }
   116  
   117  func (cs clusterStore) Decrby(key string, increment int64) (int64, error) {
   118  	node, err := cs.getRedis(key)
   119  	if err != nil {
   120  		return 0, err
   121  	}
   122  
   123  	return node.Decrby(key, increment)
   124  }
   125  
   126  func (cs clusterStore) Del(keys ...string) (int, error) {
   127  	var val int
   128  	var be errorx.BatchError
   129  
   130  	for _, key := range keys {
   131  		node, e := cs.getRedis(key)
   132  		if e != nil {
   133  			be.Add(e)
   134  			continue
   135  		}
   136  
   137  		if v, e := node.Del(key); e != nil {
   138  			be.Add(e)
   139  		} else {
   140  			val += v
   141  		}
   142  	}
   143  
   144  	return val, be.Err()
   145  }
   146  
   147  func (cs clusterStore) Eval(script, key string, args ...interface{}) (interface{}, error) {
   148  	node, err := cs.getRedis(key)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  
   153  	return node.Eval(script, []string{key}, args...)
   154  }
   155  
   156  func (cs clusterStore) Exists(key string) (bool, error) {
   157  	node, err := cs.getRedis(key)
   158  	if err != nil {
   159  		return false, err
   160  	}
   161  
   162  	return node.Exists(key)
   163  }
   164  
   165  func (cs clusterStore) Expire(key string, seconds int) error {
   166  	node, err := cs.getRedis(key)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	return node.Expire(key, seconds)
   172  }
   173  
   174  func (cs clusterStore) Expireat(key string, expireTime int64) error {
   175  	node, err := cs.getRedis(key)
   176  	if err != nil {
   177  		return err
   178  	}
   179  
   180  	return node.Expireat(key, expireTime)
   181  }
   182  
   183  func (cs clusterStore) Get(key string) (string, error) {
   184  	node, err := cs.getRedis(key)
   185  	if err != nil {
   186  		return "", err
   187  	}
   188  
   189  	return node.Get(key)
   190  }
   191  
   192  func (cs clusterStore) Hdel(key, field string) (bool, error) {
   193  	node, err := cs.getRedis(key)
   194  	if err != nil {
   195  		return false, err
   196  	}
   197  
   198  	return node.Hdel(key, field)
   199  }
   200  
   201  func (cs clusterStore) Hexists(key, field string) (bool, error) {
   202  	node, err := cs.getRedis(key)
   203  	if err != nil {
   204  		return false, err
   205  	}
   206  
   207  	return node.Hexists(key, field)
   208  }
   209  
   210  func (cs clusterStore) Hget(key, field string) (string, error) {
   211  	node, err := cs.getRedis(key)
   212  	if err != nil {
   213  		return "", err
   214  	}
   215  
   216  	return node.Hget(key, field)
   217  }
   218  
   219  func (cs clusterStore) Hgetall(key string) (map[string]string, error) {
   220  	node, err := cs.getRedis(key)
   221  	if err != nil {
   222  		return nil, err
   223  	}
   224  
   225  	return node.Hgetall(key)
   226  }
   227  
   228  func (cs clusterStore) Hincrby(key, field string, increment int) (int, error) {
   229  	node, err := cs.getRedis(key)
   230  	if err != nil {
   231  		return 0, err
   232  	}
   233  
   234  	return node.Hincrby(key, field, increment)
   235  }
   236  
   237  func (cs clusterStore) Hkeys(key string) ([]string, error) {
   238  	node, err := cs.getRedis(key)
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  
   243  	return node.Hkeys(key)
   244  }
   245  
   246  func (cs clusterStore) Hlen(key string) (int, error) {
   247  	node, err := cs.getRedis(key)
   248  	if err != nil {
   249  		return 0, err
   250  	}
   251  
   252  	return node.Hlen(key)
   253  }
   254  
   255  func (cs clusterStore) Hmget(key string, fields ...string) ([]string, error) {
   256  	node, err := cs.getRedis(key)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	return node.Hmget(key, fields...)
   262  }
   263  
   264  func (cs clusterStore) Hset(key, field, value string) error {
   265  	node, err := cs.getRedis(key)
   266  	if err != nil {
   267  		return err
   268  	}
   269  
   270  	return node.Hset(key, field, value)
   271  }
   272  
   273  func (cs clusterStore) Hsetnx(key, field, value string) (bool, error) {
   274  	node, err := cs.getRedis(key)
   275  	if err != nil {
   276  		return false, err
   277  	}
   278  
   279  	return node.Hsetnx(key, field, value)
   280  }
   281  
   282  func (cs clusterStore) Hmset(key string, fieldsAndValues map[string]string) error {
   283  	node, err := cs.getRedis(key)
   284  	if err != nil {
   285  		return err
   286  	}
   287  
   288  	return node.Hmset(key, fieldsAndValues)
   289  }
   290  
   291  func (cs clusterStore) Hvals(key string) ([]string, error) {
   292  	node, err := cs.getRedis(key)
   293  	if err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	return node.Hvals(key)
   298  }
   299  
   300  func (cs clusterStore) Incr(key string) (int64, error) {
   301  	node, err := cs.getRedis(key)
   302  	if err != nil {
   303  		return 0, err
   304  	}
   305  
   306  	return node.Incr(key)
   307  }
   308  
   309  func (cs clusterStore) Incrby(key string, increment int64) (int64, error) {
   310  	node, err := cs.getRedis(key)
   311  	if err != nil {
   312  		return 0, err
   313  	}
   314  
   315  	return node.Incrby(key, increment)
   316  }
   317  
   318  func (cs clusterStore) Llen(key string) (int, error) {
   319  	node, err := cs.getRedis(key)
   320  	if err != nil {
   321  		return 0, err
   322  	}
   323  
   324  	return node.Llen(key)
   325  }
   326  
   327  func (cs clusterStore) Lindex(key string, index int64) (string, error) {
   328  	node, err := cs.getRedis(key)
   329  	if err != nil {
   330  		return "", err
   331  	}
   332  
   333  	return node.Lindex(key, index)
   334  }
   335  
   336  func (cs clusterStore) Lpop(key string) (string, error) {
   337  	node, err := cs.getRedis(key)
   338  	if err != nil {
   339  		return "", err
   340  	}
   341  
   342  	return node.Lpop(key)
   343  }
   344  
   345  func (cs clusterStore) Lpush(key string, values ...interface{}) (int, error) {
   346  	node, err := cs.getRedis(key)
   347  	if err != nil {
   348  		return 0, err
   349  	}
   350  
   351  	return node.Lpush(key, values...)
   352  }
   353  
   354  func (cs clusterStore) Lrange(key string, start, stop int) ([]string, error) {
   355  	node, err := cs.getRedis(key)
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  
   360  	return node.Lrange(key, start, stop)
   361  }
   362  
   363  func (cs clusterStore) Lrem(key string, count int, value string) (int, error) {
   364  	node, err := cs.getRedis(key)
   365  	if err != nil {
   366  		return 0, err
   367  	}
   368  
   369  	return node.Lrem(key, count, value)
   370  }
   371  
   372  func (cs clusterStore) Persist(key string) (bool, error) {
   373  	node, err := cs.getRedis(key)
   374  	if err != nil {
   375  		return false, err
   376  	}
   377  
   378  	return node.Persist(key)
   379  }
   380  
   381  func (cs clusterStore) Pfadd(key string, values ...interface{}) (bool, error) {
   382  	node, err := cs.getRedis(key)
   383  	if err != nil {
   384  		return false, err
   385  	}
   386  
   387  	return node.Pfadd(key, values...)
   388  }
   389  
   390  func (cs clusterStore) Pfcount(key string) (int64, error) {
   391  	node, err := cs.getRedis(key)
   392  	if err != nil {
   393  		return 0, err
   394  	}
   395  
   396  	return node.Pfcount(key)
   397  }
   398  
   399  func (cs clusterStore) Rpush(key string, values ...interface{}) (int, error) {
   400  	node, err := cs.getRedis(key)
   401  	if err != nil {
   402  		return 0, err
   403  	}
   404  
   405  	return node.Rpush(key, values...)
   406  }
   407  
   408  func (cs clusterStore) Sadd(key string, values ...interface{}) (int, error) {
   409  	node, err := cs.getRedis(key)
   410  	if err != nil {
   411  		return 0, err
   412  	}
   413  
   414  	return node.Sadd(key, values...)
   415  }
   416  
   417  func (cs clusterStore) Scard(key string) (int64, error) {
   418  	node, err := cs.getRedis(key)
   419  	if err != nil {
   420  		return 0, err
   421  	}
   422  
   423  	return node.Scard(key)
   424  }
   425  
   426  func (cs clusterStore) Set(key, value string) error {
   427  	node, err := cs.getRedis(key)
   428  	if err != nil {
   429  		return err
   430  	}
   431  
   432  	return node.Set(key, value)
   433  }
   434  
   435  func (cs clusterStore) Setex(key, value string, seconds int) error {
   436  	node, err := cs.getRedis(key)
   437  	if err != nil {
   438  		return err
   439  	}
   440  
   441  	return node.Setex(key, value, seconds)
   442  }
   443  
   444  func (cs clusterStore) Setnx(key, value string) (bool, error) {
   445  	node, err := cs.getRedis(key)
   446  	if err != nil {
   447  		return false, err
   448  	}
   449  
   450  	return node.Setnx(key, value)
   451  }
   452  
   453  func (cs clusterStore) SetnxEx(key, value string, seconds int) (bool, error) {
   454  	node, err := cs.getRedis(key)
   455  	if err != nil {
   456  		return false, err
   457  	}
   458  
   459  	return node.SetnxEx(key, value, seconds)
   460  }
   461  
   462  func (cs clusterStore) Sismember(key string, value interface{}) (bool, error) {
   463  	node, err := cs.getRedis(key)
   464  	if err != nil {
   465  		return false, err
   466  	}
   467  
   468  	return node.Sismember(key, value)
   469  }
   470  
   471  func (cs clusterStore) Smembers(key string) ([]string, error) {
   472  	node, err := cs.getRedis(key)
   473  	if err != nil {
   474  		return nil, err
   475  	}
   476  
   477  	return node.Smembers(key)
   478  }
   479  
   480  func (cs clusterStore) Spop(key string) (string, error) {
   481  	node, err := cs.getRedis(key)
   482  	if err != nil {
   483  		return "", err
   484  	}
   485  
   486  	return node.Spop(key)
   487  }
   488  
   489  func (cs clusterStore) Srandmember(key string, count int) ([]string, error) {
   490  	node, err := cs.getRedis(key)
   491  	if err != nil {
   492  		return nil, err
   493  	}
   494  
   495  	return node.Srandmember(key, count)
   496  }
   497  
   498  func (cs clusterStore) Srem(key string, values ...interface{}) (int, error) {
   499  	node, err := cs.getRedis(key)
   500  	if err != nil {
   501  		return 0, err
   502  	}
   503  
   504  	return node.Srem(key, values...)
   505  }
   506  
   507  func (cs clusterStore) Sscan(key string, cursor uint64, match string, count int64) (
   508  	keys []string, cur uint64, err error) {
   509  	node, err := cs.getRedis(key)
   510  	if err != nil {
   511  		return nil, 0, err
   512  	}
   513  
   514  	return node.Sscan(key, cursor, match, count)
   515  }
   516  
   517  func (cs clusterStore) Ttl(key string) (int, error) {
   518  	node, err := cs.getRedis(key)
   519  	if err != nil {
   520  		return 0, err
   521  	}
   522  
   523  	return node.Ttl(key)
   524  }
   525  
   526  func (cs clusterStore) Zadd(key string, score int64, value string) (bool, error) {
   527  	node, err := cs.getRedis(key)
   528  	if err != nil {
   529  		return false, err
   530  	}
   531  
   532  	return node.Zadd(key, score, value)
   533  }
   534  
   535  func (cs clusterStore) Zadds(key string, ps ...redis.Pair) (int64, error) {
   536  	node, err := cs.getRedis(key)
   537  	if err != nil {
   538  		return 0, err
   539  	}
   540  
   541  	return node.Zadds(key, ps...)
   542  }
   543  
   544  func (cs clusterStore) Zcard(key string) (int, error) {
   545  	node, err := cs.getRedis(key)
   546  	if err != nil {
   547  		return 0, err
   548  	}
   549  
   550  	return node.Zcard(key)
   551  }
   552  
   553  func (cs clusterStore) Zcount(key string, start, stop int64) (int, error) {
   554  	node, err := cs.getRedis(key)
   555  	if err != nil {
   556  		return 0, err
   557  	}
   558  
   559  	return node.Zcount(key, start, stop)
   560  }
   561  
   562  func (cs clusterStore) Zincrby(key string, increment int64, field string) (int64, error) {
   563  	node, err := cs.getRedis(key)
   564  	if err != nil {
   565  		return 0, err
   566  	}
   567  
   568  	return node.Zincrby(key, increment, field)
   569  }
   570  
   571  func (cs clusterStore) Zrank(key, field string) (int64, error) {
   572  	node, err := cs.getRedis(key)
   573  	if err != nil {
   574  		return 0, err
   575  	}
   576  
   577  	return node.Zrank(key, field)
   578  }
   579  
   580  func (cs clusterStore) Zrange(key string, start, stop int64) ([]string, error) {
   581  	node, err := cs.getRedis(key)
   582  	if err != nil {
   583  		return nil, err
   584  	}
   585  
   586  	return node.Zrange(key, start, stop)
   587  }
   588  
   589  func (cs clusterStore) ZrangeWithScores(key string, start, stop int64) ([]redis.Pair, error) {
   590  	node, err := cs.getRedis(key)
   591  	if err != nil {
   592  		return nil, err
   593  	}
   594  
   595  	return node.ZrangeWithScores(key, start, stop)
   596  }
   597  
   598  func (cs clusterStore) ZrangebyscoreWithScores(key string, start, stop int64) ([]redis.Pair, error) {
   599  	node, err := cs.getRedis(key)
   600  	if err != nil {
   601  		return nil, err
   602  	}
   603  
   604  	return node.ZrangebyscoreWithScores(key, start, stop)
   605  }
   606  
   607  func (cs clusterStore) ZrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) (
   608  	[]redis.Pair, error) {
   609  	node, err := cs.getRedis(key)
   610  	if err != nil {
   611  		return nil, err
   612  	}
   613  
   614  	return node.ZrangebyscoreWithScoresAndLimit(key, start, stop, page, size)
   615  }
   616  
   617  func (cs clusterStore) Zrem(key string, values ...interface{}) (int, error) {
   618  	node, err := cs.getRedis(key)
   619  	if err != nil {
   620  		return 0, err
   621  	}
   622  
   623  	return node.Zrem(key, values...)
   624  }
   625  
   626  func (cs clusterStore) Zremrangebyrank(key string, start, stop int64) (int, error) {
   627  	node, err := cs.getRedis(key)
   628  	if err != nil {
   629  		return 0, err
   630  	}
   631  
   632  	return node.Zremrangebyrank(key, start, stop)
   633  }
   634  
   635  func (cs clusterStore) Zremrangebyscore(key string, start, stop int64) (int, error) {
   636  	node, err := cs.getRedis(key)
   637  	if err != nil {
   638  		return 0, err
   639  	}
   640  
   641  	return node.Zremrangebyscore(key, start, stop)
   642  }
   643  
   644  func (cs clusterStore) Zrevrange(key string, start, stop int64) ([]string, error) {
   645  	node, err := cs.getRedis(key)
   646  	if err != nil {
   647  		return nil, err
   648  	}
   649  
   650  	return node.Zrevrange(key, start, stop)
   651  }
   652  
   653  func (cs clusterStore) ZrevrangebyscoreWithScores(key string, start, stop int64) ([]redis.Pair, error) {
   654  	node, err := cs.getRedis(key)
   655  	if err != nil {
   656  		return nil, err
   657  	}
   658  
   659  	return node.ZrevrangebyscoreWithScores(key, start, stop)
   660  }
   661  
   662  func (cs clusterStore) ZrevrangebyscoreWithScoresAndLimit(key string, start, stop int64, page, size int) (
   663  	[]redis.Pair, error) {
   664  	node, err := cs.getRedis(key)
   665  	if err != nil {
   666  		return nil, err
   667  	}
   668  
   669  	return node.ZrevrangebyscoreWithScoresAndLimit(key, start, stop, page, size)
   670  }
   671  
   672  func (cs clusterStore) Zrevrank(key, field string) (int64, error) {
   673  	node, err := cs.getRedis(key)
   674  	if err != nil {
   675  		return 0, err
   676  	}
   677  
   678  	return node.Zrevrank(key, field)
   679  }
   680  
   681  func (cs clusterStore) Zscore(key, value string) (int64, error) {
   682  	node, err := cs.getRedis(key)
   683  	if err != nil {
   684  		return 0, err
   685  	}
   686  
   687  	return node.Zscore(key, value)
   688  }
   689  
   690  func (cs clusterStore) getRedis(key string) (*redis.Redis, error) {
   691  	val, ok := cs.dispatcher.Get(key)
   692  	if !ok {
   693  		return nil, ErrNoRedisNode
   694  	}
   695  
   696  	return val.(*redis.Redis), nil
   697  }