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 }