在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
package main import ( "context" "fmt" "log" "math/rand" "net/http" "sync" "time" goredis "github.com/garyburd/redigo/redis" redis "github.com/go-redis/redis/v8" ) var ctx = context.Background() var redisdb *redis.Client var once sync.Once var pool *goredis.Pool //使用单例模式创建redis client func GetInstance(opt redis.Options) *redis.Client { once.Do(func() { redisdb = redis.NewClient(&opt) }) return redisdb } //使用go-redins 获取string func GetByKey(w http.ResponseWriter, r *http.Request) { // nowtime := time.Now().UnixNano() // defer elapsed(w, nowtime) //循环使用redis 读取数据 val, err := redisdb.Get(ctx, "key").Result() if err != nil { panic(err) } //获取过期时间 // tm, err := redisdb.TTL(ctx, "key").Result() // log.Println(tm) fmt.Println("key", val) } //使用go-redis 设置string func SetByKey(w http.ResponseWriter, r *http.Request) { //第三个参数为过期时间 time.Duration err := redisdb.Set(ctx, "key", "value", 100*time.Second).Err() if err != nil { panic(err) } //Incr 操作 result, err := redisdb.Incr(ctx, "counter").Result() log.Println("Incr", result, err) } //使用go-redis 操作List func OperationList(w http.ResponseWriter, r *http.Request) { err := redisdb.RPush(ctx, "list_test", "message1", "message2", "message3", "message4", "message5").Err() if err != nil { panic(err) } //设置 log.Println(redisdb.LSet(ctx, "list_test", 2, "message set").Err()) //remove ret, err := redisdb.LRem(ctx, "list_test", 3, "message1").Result() log.Println(ret, err) //获取列表长度 rLen, err := redisdb.LLen(ctx, "list_test").Result() log.Println(rLen, err) //遍历 lists, err := redisdb.LRange(ctx, "list_test", 0, rLen-1).Result() log.Println("LRange", lists, err) //blpop没有时阻塞 -- 移出并获取列表的第一个元素 result, err := redisdb.BLPop(ctx, 1*time.Second, "list_test").Result() log.Println("result:", result, err, len(result)) //brpop 没有时阻塞 --移出并获取列表的最后一个元素 result, err = redisdb.BRPop(ctx, 1*time.Second, "list_test").Result() log.Println("result:", result, err, len(result)) } //使用go-redis 操作hash func OperationHash() { datas := map[string]interface{}{ "name": "LI LEI", "sex": 1, "age": 28, "tel": 123445578, } //添加 if err := redisdb.HMSet(ctx, "hash_test", datas).Err(); err != nil { log.Fatal(err) } //获取 rets, err := redisdb.HMGet(ctx, "hash_test", "name", "sex").Result() log.Println("rets:", rets, err) //成员 retAll, err := redisdb.HGetAll(ctx, "hash_test").Result() log.Println("retAll", retAll, err) //存在 bExist, err := redisdb.HExists(ctx, "hash_test", "tel").Result() log.Println(bExist, err) //只有在字段 field 不存在时,设置哈希表字段的值 bRet, err := redisdb.HSetNX(ctx, "hash_test", "id", 100).Result() log.Println(bRet, err) //删除 log.Println(redisdb.HDel(ctx, "hash_test", "age").Result()) } //使用go-redis 操作Set 集合 func OperationSet() { //添加 ret, err := redisdb.SAdd(ctx, "set_test", "11", "22", "33", "44").Result() log.Println(ret, err) //数量 count, err := redisdb.SCard(ctx, "set_test").Result() log.Println(count, err) //删除 ret, err = redisdb.SRem(ctx, "set_test", "11", "22").Result() log.Println(ret, err) //成员 members, err := redisdb.SMembers(ctx, "set_test").Result() log.Println(members, err) bret, err := redisdb.SIsMember(ctx, "set_test", "33").Result() log.Println(bret, err) redisdb.SAdd(ctx, "set_a", "11", "22", "33", "44") redisdb.SAdd(ctx, "set_b", "11", "22", "33", "55", "66", "77") //差集 diff, err := redisdb.SDiff(ctx, "set_a", "set_b").Result() log.Println(diff, err) //交集 inter, err := redisdb.SInter(ctx, "set_a", "set_b").Result() log.Println(inter, err) //并集 union, err := redisdb.SUnion(ctx, "set_a", "set_b").Result() log.Println(union, err) ret, err = redisdb.SDiffStore(ctx, "set_diff", "set_a", "set_b").Result() log.Println(ret, err) rets, err := redisdb.SMembers(ctx, "set_diff").Result() log.Println(rets, err) } //使用go-redis 操作sort Set 有序集合 func OperationSortSet() { addArgs := make([]*redis.Z, 100) for i := 1; i < 100; i++ { addArgs = append(addArgs, &redis.Z{Score: float64(i), Member: fmt.Sprintf("a_%d", i)}) } //log.Println(addArgs) Shuffle := func(slice []*redis.Z) { r := rand.New(rand.NewSource(time.Now().Unix())) for len(slice) > 0 { n := len(slice) randIndex := r.Intn(n) slice[n-1], slice[randIndex] = slice[randIndex], slice[n-1] slice = slice[:n-1] } } //随机打乱 Shuffle(addArgs) //添加 ret, err := redisdb.ZAddNX(ctx, "sortset_test", addArgs...).Result() log.Println(ret, err) //获取指定成员score score, err := redisdb.ZScore(ctx, "sortset_test", "a_10").Result() log.Println(score, err) //获取制定成员的索引 index, err := redisdb.ZRank(ctx, "sortset_test", "a_50").Result() log.Println(index, err) count, err := redisdb.SCard(ctx, "sortset_test").Result() log.Println(count, err) //返回有序集合指定区间内的成员 rets, err := redisdb.ZRange(ctx, "sortset_test", 10, 20).Result() log.Println(rets, err) //返回有序集合指定区间内的成员分数从高到低 rets, err = redisdb.ZRevRange(ctx, "sortset_test", 10, 20).Result() log.Println(rets, err) //指定分数区间的成员列表 30 < score < 50 rets, err = redisdb.ZRangeByScore(ctx, "sortset_test", &redis.ZRangeBy{Min: "(30", Max: "(50", Offset: 1, Count: 10}).Result() log.Println(rets, err) } //用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。 //每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数 func OperationHyperLogLog() { for i := 0; i < 10000; i++ { redisdb.PFAdd(ctx, "pf_test_1", fmt.Sprintf("pfkey%d", i)) } ret, err := redisdb.PFCount(ctx, "pf_test_1").Result() log.Println(ret, err) for i := 0; i < 10000; i++ { redisdb.PFAdd(ctx, "pf_test_2", fmt.Sprintf("pfkey%d", i)) } ret, err = redisdb.PFCount(ctx, "pf_test_2").Result() log.Println(ret, err) redisdb.PFMerge(ctx, "pf_test", "pf_test_2", "pf_test_1") ret, err = redisdb.PFCount(ctx, "pf_test").Result() log.Println(ret, err) } //发布订阅 func PubSub() { //发布订阅 pubsub := redisdb.Subscribe(ctx, "subkey") _, err := pubsub.Receive(ctx) if err != nil { log.Fatal("pubsub.Receive") } ch := pubsub.Channel() time.AfterFunc(1*time.Second, func() { log.Println("Publish") err = redisdb.Publish(ctx, "subkey", "test publish 1").Err() if err != nil { log.Fatal("redisdb.Publish", err) } redisdb.Publish(ctx, "subkey", "test publish 2") }) for msg := range ch { log.Println("recv channel:", msg.Channel, msg.Pattern, msg.Payload) } } //执行自定义redis命令 func CMD() { log.Println("ExampleClient_CMD") defer log.Println("ExampleClient_CMD Complete!") //执行自定义redis命令 Get := func(rdb *redis.Client, key string) *redis.StringCmd { cmd := redis.NewStringCmd(ctx, "get", key) redisdb.Process(ctx, cmd) return cmd } v, err := Get(redisdb, "NewStringCmd").Result() log.Println("NewStringCmd", v, err) cmd := redisdb.Do(ctx, "get", "redisdb.do").String() log.Println("redisdb.Do", cmd) } //SCAN 命令 func Scan() { log.Println("ExampleClient_Scan") defer log.Println("ExampleClient_Scan") //scan for i := 1; i < 1000; i++ { redisdb.Set(ctx, fmt.Sprintf("skey_%d", i), i, 0) } cusor := uint64(0) for { keys, retCusor, err := redisdb.Scan(ctx, cusor, "skey_*", int64(100)).Result() log.Println(keys, cusor, err) cusor = retCusor if cusor == 0 { break } } } //执行事务,事务之中又包含以上的原子操作 func Tx() { pipe := redisdb.TxPipeline() incr := pipe.Incr(ctx, "tx_pipeline_counter") pipe.Expire(ctx, "tx_pipeline_counter", time.Hour) // Execute // // MULTI // INCR pipeline_counter // EXPIRE pipeline_counts 3600 // EXEC // // using one rdb-server roundtrip. _, err := pipe.Exec(ctx) fmt.Println(incr.Val(), err) } //脚本 func Script() { IncrByXX := redis.NewScript(` if redis.call("GET", KEYS[1]) ~= false then return redis.call("INCRBY", KEYS[1], ARGV[1]) end return false `) n, err := IncrByXX.Run(ctx, redisdb, []string{"xx_counter"}, 2).Result() fmt.Println(n, err) err = redisdb.Set(ctx, "xx_counter", "40", 0).Err() if err != nil { panic(err) } n, err = IncrByXX.Run(ctx, redisdb, []string{"xx_counter"}, 2).Result() fmt.Println(n, err) } /*-------------------------------------------------------------------------分割线--------------------------------------------------------------------*/ //使用redigo获取一个string类型 func GetByKey2(w http.ResponseWriter, r *http.Request) { // nowtime := time.Now().UnixNano() // defer elapsed(w, nowtime) // //循环使用redis 读取数据 // conn, err := goredis.Dial("tcp", "192.168.3.10:6000") // if err != nil { // fmt.Println("connect redis error :", err) // return // } //从线程池中取 conn := pool.Get() defer conn.Close() name, err := goredis.String(conn.Do("GET", "name")) if err != nil { fmt.Println("redis get error:", err) } else { fmt.Printf("Got name: %s \n", name) } fmt.Println("key", name) } //使用redigo 设置一个string func SetByKey2(w http.ResponseWriter, r *http.Request) { //第三个参数为过期时间 time.Duration conn := pool.Get() _, err := conn.Do("SET", "name", "wd") if err != nil { fmt.Println("redis set error:", err) } } // 使用defer 关键字统计程序耗时时长(微秒) func elapsed(w http.ResponseWriter, beforeTime int64) { t := time.Now().UnixNano() - beforeTime fmt.Fprintln(w, t) } func main() { pool = &goredis.Pool{ MaxIdle: 100, //最大空闲 MaxActive: 800, //0表示没有限制 ,最大连接数 Wait: true, IdleTimeout: 300, Dial: func() (goredis.Conn, error) { return goredis.Dial("tcp", "192.168.3.10:6000") }, } redisdb = GetInstance(redis.Options{ Addr: "192.168.3.10:6000", //集群模式一定要配置主节点的值 否则会报MOVED 4998 Password: "", // no password set DB: 0, // use default DB // MinIdleConns: 500, //在启动阶段创建指定数量的Idle连接,并长期维持idle状态的连接数不少于指定数量; // PoolSize: 100, }) http.HandleFunc("/GetByKey", GetByKey) http.HandleFunc("/GetByKey2", GetByKey2) err := http.ListenAndServe(":9090", nil) if err != nil { fmt.Printf("http server failed, err:%v\n", err) return } }
|
请发表评论