zoukankan      html  css  js  c++  java
  • go 使用go-redis 和redigo 连接redis

    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 
    ", 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
    ", err)
            return
        }
    }
    •  不清楚是写法有问题还是什么问题go-redis 的性能要比redigo的性能好很多。
  • 相关阅读:
    その他トランザクションコード
    ABAP ODATA 文字列からxstringへの変換およびその逆変換(UTF-8)
    使用ABAP CDS视图创建服务(CDSビューでODATAサービスの作成方法)
    UPDATE_ENTITY実行
    【EXCEL】簡単に合計をとる方法
    【EXCEL】XMLファイルを開く方法(XML文件打开方法)
    SAP Odata実行命令(2)
    前端资料
    api 大全
    kendo ui
  • 原文地址:https://www.cnblogs.com/chongyao/p/14031939.html
Copyright © 2011-2022 走看看