go操作redis

go操作redis

依赖

go get github.com/redis/go-redis/v9

配置信息

/**
	type Options struct {
	    // 连接网络类型,如: tcp、udp、unix等方式
	    // 如果为空默认tcp
	    Network string

	    // redis服务器地址,ip:port格式,比如:192.168.1.100:6379
	    // 默认为 :6379
	    Addr string

	    // ClientName 是对网络连接设置一个名字,使用 "CLIENT LIST" 命令
	    // 可以查看redis服务器当前的网络连接列表
	    // 如果设置了ClientName,go-redis对每个连接调用 `CLIENT SETNAME ClientName` 命令
	    // 查看: https://redis.io/commands/client-setname/
	    // 默认为空,不设置客户端名称
	    ClientName string

	    // 如果你想自定义连接网络的方式,可以自定义 `Dialer` 方法,
	    // 如果不指定,将使用默认的方式进行网络连接 `redis.NewDialer`
	    Dialer func(ctx context.Context, network, addr string) (net.Conn, error)

	    // 建立了新连接时调用此函数
	    // 默认为nil
	    OnConnect func(ctx context.Context, cn *Conn) error

	    // 当redis服务器版本在6.0以上时,作为ACL认证信息配合密码一起使用,
	    // ACL是redis 6.0以上版本提供的认证功能,6.0以下版本仅支持密码认证。
	    // 默认为空,不进行认证。
	    Username string

	    // 当redis服务器版本在6.0以上时,作为ACL认证信息配合密码一起使用,
	    // 当redis服务器版本在6.0以下时,仅作为密码认证。
	    // ACL是redis 6.0以上版本提供的认证功能,6.0以下版本仅支持密码认证。
	    // 默认为空,不进行认证。
	    Password string

	    // 允许动态设置用户名和密码,go-redis在进行网络连接时会获取用户名和密码,
	    // 这对一些认证鉴权有时效性的系统来说很有用,比如一些云服务商提供认证信息有效期为12小时。
	    // 默认为nil
	    CredentialsProvider func() (username string, password string)

	    // redis DB 数据库,默认为0
	    DB int

	    // 命令最大重试次数, 默认为3
	    MaxRetries int

	    // 每次重试最小间隔时间
	    // 默认 8 * time.Millisecond (8毫秒) ,设置-1为禁用
	    MinRetryBackoff time.Duration

	    // 每次重试最大间隔时间
	    // 默认 512 * time.Millisecond (512毫秒) ,设置-1为禁用
	    MaxRetryBackoff time.Duration

	    // 建立新网络连接时的超时时间
	    // 默认5秒
	    DialTimeout time.Duration

	    // 从网络连接中读取数据超时时间,可能的值:
	    //  0 - 默认值,3秒
	    // -1 - 无超时,无限期的阻塞
	    // -2 - 不进行超时设置,不调用 SetReadDeadline 方法
	    ReadTimeout time.Duration

	    // 把数据写入网络连接的超时时间,可能的值:
	    //  0 - 默认值,3秒
	    // -1 - 无超时,无限期的阻塞
	    // -2 - 不进行超时设置,不调用 SetWriteDeadline 方法
	    WriteTimeout time.Duration

	    // 是否使用context.Context的上下文截止时间,
	    // 有些情况下,context.Context的超时可能带来问题。
	    // 默认不使用
	    ContextTimeoutEnabled bool

	    // 连接池的类型,有 LIFO 和 FIFO 两种模式,
	    // PoolFIFO 为 false 时使用 LIFO 模式,为 true 使用 FIFO 模式。
	    // 当一个连接使用完毕时会把连接归还给连接池,连接池会把连接放入队尾,
	    // LIFO 模式时,每次取空闲连接会从"队尾"取,就是刚放入队尾的空闲连接,
	    // 也就是说 LIFO 每次使用的都是热连接,连接池有机会关闭"队头"的长期空闲连接,
	    // 并且从概率上,刚放入的热连接健康状态会更好;
	    // 而 FIFO 模式则相反,每次取空闲连接会从"队头"取,相比较于 LIFO 模式,
	    // 会使整个连接池的连接使用更加平均,有点类似于负载均衡寻轮模式,会循环的使用
	    // 连接池的所有连接,如果你使用 go-redis 当做代理让后端 redis 节点负载更平均的话,
	    // FIFO 模式对你很有用。
	    // 如果你不确定使用什么模式,请保持默认 PoolFIFO = false
	    PoolFIFO bool

	    // 连接池最大连接数量,注意:这里不包括 pub/sub,pub/sub 将使用独立的网络连接
	    // 默认为 10 * runtime.GOMAXPROCS
	    PoolSize int

	    // PoolTimeout 代表如果连接池所有连接都在使用中,等待获取连接时间,超时将返回错误
	    // 默认是 1秒+ReadTimeout
	    PoolTimeout time.Duration

	    // 连接池保持的最小空闲连接数,它受到PoolSize的限制
	    // 默认为0,不保持
	    MinIdleConns int

	    // 连接池保持的最大空闲连接数,多余的空闲连接将被关闭
	    // 默认为0,不限制
	    MaxIdleConns int

	    // ConnMaxIdleTime 是最大空闲时间,超过这个时间将被关闭。
	    // 如果 ConnMaxIdleTime <= 0,则连接不会因为空闲而被关闭。
	    // 默认值是30分钟,-1禁用
	    ConnMaxIdleTime time.Duration

	    // ConnMaxLifetime 是一个连接的生存时间,
	    // 和 ConnMaxIdleTime 不同,ConnMaxLifetime 表示连接最大的存活时间
	    // 如果 ConnMaxLifetime <= 0,则连接不会有使用时间限制
	    // 默认值为0,代表连接没有时间限制
	    ConnMaxLifetime time.Duration

	    // 如果你的redis服务器需要TLS访问,可以在这里配置TLS证书等信息
	    // 如果配置了证书信息,go-redis将使用TLS发起连接,
	    // 如果你自定义了 `Dialer` 方法,你需要自己实现网络连接
	    TLSConfig *tls.Config

	    // 限流器的配置,参照 `Limiter` 接口
	    Limiter Limiter

	    // 设置启用在副本节点只读查询,默认为false不启用
	    // 参照:https://redis.io/commands/readonly
	    readOnly bool
	}
	*/

实例

package daily

import (
	"context"
	"fmt"
	"github.com/redis/go-redis/v9"
	"time"
)

var (
Rdb         *redis.Client
)

/*
*
go redis
 1. 下载依赖: go get github.com/redis/go-redis/v9
 2. 参考文档: https://redis.uptrace.dev/zh/guide/go-redis.html
 3. 设置临时网络代理:
    set http_proxy=http://ip:port
    set https_proxy=http://ip:port

4.取消临时网络代理:

	set http_proxy=
	set https_proxy=

*/
func initRedis() error {
	var err error
	ctx := context.Background()
	// 获取redis连接-1
	//dsn := "redis://<user>:<pass>@<host>:<port>/<db>"
	//opt, err := redis.ParseURL("redis://redis://localhost:6379/0")
	//if err != nil{
	//	panic(err)
	//}else{
	//	rc := redis.NewClient(opt)
	//}

	/**
	通用客户端
	UniversalClient 并不是一个客户端,而是对 Client 、 ClusterClient 、 FailoverClient 客户端的包装。
	根据不同的选项,客户端的类型如下:
	如果指定了 MasterName 选项,则返回 FailoverClient 哨兵客户端。
	如果 Addrs 是 2 个以上的地址,则返回 ClusterClient 集群客户端。
	其他情况,返回 Client 单节点客户端。
	*/
	//// *redis.Client.
	//rc := NewUniversalClient(&redis.UniversalOptions{
	//	Addrs: []string{":6379"},
	//})
	//
	//// *redis.ClusterClient.
	//rc := NewUniversalClient(&redis.UniversalOptions{
	//	Addrs: []string{":6379", ":6380"},
	//})
	//
	//// *redis.FailoverClient.
	//rc := NewUniversalClient(&redis.UniversalOptions{
	//	Addrs: []string{":6379"},
	//	MasterName: "mymaster",
	//})

	// 获取redis连接-2
	rc := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // 连接地址
		Password: "",               // 登录密码
		DB:       0,                // 数据库
	})
	err = rc.Ping(ctx).Err()
	Rdb = rc
	return err
}

func RedisOp() {
	// 1. 初始化连接
	ctx := context.Background()
	if err := initRedis(); err != nil {
		fmt.Println("连接失败=" + err.Error())
		return
	} else {
		fmt.Println("连接成功")
	}
	defer Rdb.Close()
	// 2. 常规命令
	// 2.1 dbsize:统计当前库数据量
	if result, err := Rdb.DBSize(ctx).Result(); err != nil {
		fmt.Println("命令dbsize执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令dbsize执行成功=", result)
	}
	// 2.2 keys *:查找特定库特定key(*:标识匹配所有)
	if result, err := Rdb.Keys(ctx, "*").Result(); err != nil {
		fmt.Println("命令keys执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令keys执行成功(切片数据)=", result)
	}
	// 2.3 exists key:判断特定key是否存在(0:不存在1:存在)
	if result, err := Rdb.Exists(ctx, "key").Result(); err != nil {
		fmt.Println("命令exists执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令exists执行成功=", result)
	}
	// 2.4.1 expire key seconds:设置key有效期
	if result, err := Rdb.Expire(ctx, "key", time.Hour*24).Result(); err != nil {
		fmt.Println("命令expire执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令expire执行成功=", result)
	}
	// 2.4.2 expireat key timestamp:设置key有效期
	if result, err := Rdb.ExpireAt(ctx, "key", time.Now().Add(time.Hour*24)).Result(); err != nil {
		fmt.Println("命令expireat执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令expireat执行成功=", result)
	}
	// 2.5.1 ttl key: 查看key有效期(默认秒|-1:表示永不过期;-2:key不存在)
	if result, err := Rdb.TTL(ctx, "key").Result(); err != nil {
		fmt.Println("命令ttl执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令ttl执行成功=", result)
	}
	// 2.5.2 pttl key:查看key有效期(默认毫秒)
	if result, err := Rdb.PTTL(ctx, "key").Result(); err != nil {
		fmt.Println("命令pttl执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令pttl执行成功=", result)
	}
	// 2.6 type key:查看特定key值类型
	if result, err := Rdb.Type(ctx, "key").Result(); err != nil {
		fmt.Println("命令type执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令type执行成功=", result)
	}
	// 2.7 del key:删除key
	if result, err := Rdb.Del(ctx, "key").Result(); err != nil {
		fmt.Println("命令del执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令del执行成功=", result)
	}
	// 2.8.1 flushdb:清空当前库数据(谨慎执行该指令)
	if result, err := Rdb.FlushDB(ctx).Result(); err != nil {
		fmt.Println("命令flushdb执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令flushdb执行成功=", result)
	}
	// 2.8.2 flushall:清空所有库数据(谨慎执行该指令)
	if result, err := Rdb.FlushAll(ctx).Result(); err != nil {
		fmt.Println("命令flushall执行失败=" + err.Error())
		return
	} else {
		fmt.Println("命令flushall执行成功=", result)
	}
    // 3.string(基本数据类型操作)
	// 3.1 set
	if err := Rdb.Set(ctx, "key", "val", 0).Err(); err != nil {
		fmt.Println("string-set-error=" + err.Error())
		return
	} else {
		fmt.Println("string-set(key=val)")
	}
	// 3.2 get
	if result, err := Rdb.Get(ctx, "key").Result(); err == redis.Nil {
		fmt.Println("string-key is not exist")
	} else if err != nil {
		fmt.Println("string-get-error=" + err.Error())
	} else {
		fmt.Println("string-get(key=key)=" + result)
	}
	/**
	127.0.0.1:6379> EVAL "redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;" 1 userAge 10 60
	(integer) 1
	127.0.0.1:6379>SCRIPT FLUSH
	命令格式:EVAL script numkeys key [key …] arg [arg …]
	- script参数是一段 Lua5.1 脚本程序。脚本不必(也不应该[^1])定义为一个 Lua 函数
	- numkeys指定后续参数有几个key,即:key [key …]中key的个数。如没有key,则为0
	- key [key …] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key)。在Lua脚本中通过KEYS[1], KEYS[2]获取。
	- arg [arg …] 附加参数。在Lua脚本中通过ARGV[1],ARGV[2]获取。

	*/
	// 4. 执行lua脚本
	// redis-cli -a <password> -h <ip> -p <port> --eval <lua脚本> <key>, <args....>
	// redis-cli --eval limitIpVisit.lua limitIp, 10, 3
	luaScript := `
	redis.call('SET', KEYS[1], ARGV[1]);
	redis.call('EXPIRE', KEYS[1], ARGV[2]); 
	return "success";
	`
	script := redis.NewScript(luaScript)
	if result, err := script.Run(ctx, Rdb, []string{"luaKey"}, []interface{}{1, 3600}).Result(); err != nil {
		fmt.Println("lua执行失败=" + err.Error())
		return
	} else {
		fmt.Println("lua执行成功=", result)
	}

}


image


posted @   爱编程_喵  阅读(158)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
jQuery火箭图标返回顶部代码

jQuery火箭图标返回顶部代码

滚动滑动条后,查看右下角查看效果。很炫哦!!

适用浏览器:IE8、360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗.

点击右上角即可分享
微信分享提示