马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
zdpgo_redis_v2
Go语言毗连Redis的另一个版本,支持上下文操作,封装了一些便捷的处理惩罚操作
安装
- github.com/zhangdapeng520/zdpgo_redis_v2
复制代码 使用教程
快速入门
- package mainimport ( "context" "fmt" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- ")var ctx = context.Background()func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", // no password set DB: 0, // use default DB }) err := rdb.Set(ctx, "key", "value", 0).Err() if err != nil { panic(err) } val, err := rdb.Get(ctx, "key").Result() if err != nil { panic(err) } fmt.Println("key", val) val2, err := rdb.Get(ctx, "key2").Result() if err == redis.Nil { fmt.Println("key2 does not exist") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value // key2 does not exist}
复制代码 通过URL地址毗连Redis
- package mainimport ( "context" "fmt" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- ")var ctx = context.Background()func main() { //url := "redis://user:password@localhost:6379/0?protocol=3" url := "redis://:@localhost:6379/0?protocol=3" opts, err := redis.ParseURL(url) if err != nil { panic(err) } rdb := redis.NewClient(opts) err = rdb.Set(ctx, "key", "value", 0).Err() if err != nil { panic(err) } val, err := rdb.Get(ctx, "key").Result() if err != nil { panic(err) } fmt.Println("key", val) val2, err := rdb.Get(ctx, "key2").Result() if err == redis.Nil { fmt.Println("key2 does not exist") } else if err != nil { panic(err) } else { fmt.Println("key2", val2) } // Output: key value // key2 does not exist}
复制代码 删除key
- package mainimport ( "context" "fmt" "sync" "time" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- ")func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: ":6379", }) _ = rdb.Set(ctx, "key_with_ttl", "bar", time.Minute).Err() _ = rdb.Set(ctx, "key_without_ttl_1", "", 0).Err() _ = rdb.Set(ctx, "key_without_ttl_2", "", 0).Err() checker := NewKeyChecker(rdb, 100) start := time.Now() checker.Start(ctx) iter := rdb.Scan(ctx, 0, "", 0).Iterator() for iter.Next(ctx) { checker.Add(iter.Val()) } if err := iter.Err(); err != nil { panic(err) } deleted := checker.Stop() fmt.Println("deleted", deleted, "keys", "in", time.Since(start))}type KeyChecker struct { rdb *redis.Client batchSize int ch chan string delCh chan string wg sync.WaitGroup deleted int}func NewKeyChecker(rdb *redis.Client, batchSize int) *KeyChecker { return &KeyChecker{ rdb: rdb, batchSize: batchSize, ch: make(chan string, batchSize), delCh: make(chan string, batchSize), }}func (c *KeyChecker) Add(key string) { c.ch <- key}func (c *KeyChecker) Start(ctx context.Context) { c.wg.Add(1) go func() { defer c.wg.Done() if err := c.del(ctx); err != nil { panic(err) } }() c.wg.Add(1) go func() { defer c.wg.Done() defer close(c.delCh) keys := make([]string, 0, c.batchSize) for key := range c.ch { keys = append(keys, key) if len(keys) < cap(keys) { continue } if err := c.checkKeys(ctx, keys); err != nil { fmt.Println("checkKeys failed", err) } keys = keys[:0] } if len(keys) > 0 { if err := c.checkKeys(ctx, keys); err != nil { fmt.Println("checkKeys failed", err) } keys = nil } }()}func (c *KeyChecker) Stop() int { close(c.ch) c.wg.Wait() return c.deleted}func (c *KeyChecker) checkKeys(ctx context.Context, keys []string) error { cmds, err := c.rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error { for _, key := range keys { pipe.TTL(ctx, key) } return nil }) if err != nil { return err } for i, cmd := range cmds { d, err := cmd.(*redis.DurationCmd).Result() if err != nil { return err } if d == -1 { c.delCh <- keys[i] } } return nil}func (c *KeyChecker) del(ctx context.Context) error { pipe := c.rdb.Pipeline() for key := range c.delCh { fmt.Printf("deleting %s...\n", key) pipe.Del(ctx, key) c.deleted++ if pipe.Len() < c.batchSize { continue } if _, err := pipe.Exec(ctx); err != nil { return err } } if _, err := pipe.Exec(ctx); err != nil { return err } return nil}
复制代码 hll
- package mainimport ( "context" "fmt" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- ")func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: ":6379", }) _ = rdb.FlushDB(ctx).Err() for i := 0; i < 10; i++ { if err := rdb.PFAdd(ctx, "myset", fmt.Sprint(i)).Err(); err != nil { panic(err) } } card, err := rdb.PFCount(ctx, "myset").Result() if err != nil { panic(err) } fmt.Println("set cardinality", card)}
复制代码 实行LUA脚本
- package mainimport ( "context" "fmt" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- ")func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: ":6379", }) _ = rdb.FlushDB(ctx).Err() fmt.Printf("# INCR BY\n") for _, change := range []int{+1, +5, 0} { num, err := incrBy.Run(ctx, rdb, []string{"my_counter"}, change).Int() if err != nil { panic(err) } fmt.Printf("incr by %d: %d\n", change, num) } fmt.Printf("\n# SUM\n") sum, err := sum.Run(ctx, rdb, []string{"my_sum"}, 1, 2, 3).Int() if err != nil { panic(err) } fmt.Printf("sum is: %d\n", sum)}var incrBy = redis.NewScript(`local key = KEYS[1]local change = ARGV[1]local value = redis.call("GET", key)if not value then value = 0endvalue = value + changeredis.call("SET", key, value)return value`)var sum = redis.NewScript(`local key = KEYS[1]local sum = redis.call("GET", key)if not sum then sum = 0endlocal num_arg = #ARGVfor i = 1, num_arg do sum = sum + ARGV[i]endredis.call("SET", key, sum)return sum`)
复制代码 将效果转换为布局体
- package mainimport ( "context" redis "github.com/zhangdapeng520/zdpgo_redis_v2
- " "github.com/zhangdapeng520/zdpgo_redis_v2
- /spew")type Model struct { Str1 string `redis:"str1"` Str2 string `redis:"str2"` Bytes []byte `redis:"bytes"` Int int `redis:"int"` Bool bool `redis:"bool"` Ignored struct{} `redis:"-"`}func main() { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: ":6379", }) _ = rdb.FlushDB(ctx).Err() // Set some fields. if _, err := rdb.Pipelined(ctx, func(rdb redis.Pipeliner) error { rdb.HSet(ctx, "key", "str1", "hello") rdb.HSet(ctx, "key", "str2", "world") rdb.HSet(ctx, "key", "int", 123) rdb.HSet(ctx, "key", "bool", 1) rdb.HSet(ctx, "key", "bytes", []byte("this is bytes !")) return nil }); err != nil { panic(err) } var model1, model2 Model // Scan all fields into the model. if err := rdb.HGetAll(ctx, "key").Scan(&model1); err != nil { panic(err) } // Or scan a subset of the fields. if err := rdb.HMGet(ctx, "key", "str1", "int").Scan(&model2); err != nil { panic(err) } spew.Dump(model1) // Output: // (main.Model) { // Str1: (string) (len=5) "hello", // Str2: (string) (len=5) "world", // Bytes: ([]uint8) (len=15 cap=16) { // 00000000 74 68 69 73 20 69 73 20 62 79 74 65 73 20 21 |this is bytes !| // }, // Int: (int) 123, // Bool: (bool) true, // Ignored: (struct {}) { // } // } spew.Dump(model2) // Output: // (main.Model) { // Str1: (string) (len=5) "hello", // Str2: (string) "", // Bytes: ([]uint8) <nil>, // Int: (int) 123, // Bool: (bool) false, // Ignored: (struct {}) { // } // }}
复制代码 版本历史
v0.1.0
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |