Redis的各种操作

使用golang语言实现了各种redis的实现

包括初始化redisDb,在服务重启时需要删除的 redis 缓存,对redis里的值进行自增操作并设置过期时间,简单分布式锁,set,get,ttl,delete等等。

哎嘿,你就看吧,一看一个不吱声。

func InitRedisDB(cfg *dbridgeredis.RedisConfig) {defer ClearCacheOnServiceRestart()client := dbridgeredis.InitRedis(cfg)if cfg.ClusterEnable {RedisClusterDB = client.(*redis.ClusterClient)} else {redisDB = client.(*redis.Client)injectredis.SetRedis(redisDB)injectredis.Inject()}
}// IncrAndExpire 对redis里的值进行自增操作并设置过期时间
func IncrAndExpire(key string, expiration time.Duration) (count int64) {c := context.Background()currentValues := redisDB.Get(c, key)logger.Info(fmt.Sprintf("redis key=%s, currentValues=%v", key, currentValues))result := redisDB.Incr(c, key)if err := result.Err(); err != nil {logger.Error("incr redis key failed", err)} else {count = result.Val()if err := redisDB.Expire(c, key, expiration).Err(); err != nil {logger.Error("set redis key expire failed", err)}}return
}// Set value需要传指针地址
func Set(key string, value interface{}, expiration time.Duration) error {c := context.Background()if key == "" || value == nil {return errors.New("param empty")}err := hystrixPing()if err != nil {return err}data, err := json.Marshal(value)if err != nil {return err}err = redisDB.Set(c, key, data, expiration).Err()return err
}func SetNX(key string, value interface{}, expiration time.Duration) error {c := context.Background()if key == "" || value == nil {return errors.New("param empty")}data, err := json.Marshal(value)if err != nil {return err}return redisDB.SetNX(c, key, data, expiration).Err()
}// SetNXForLock 简单分布式锁
func SetNXForLock(key string, expiration time.Duration) error {c := context.Background()if key == "" {return errors.New("key empty")}suc := redisDB.SetNX(c, key, 1, expiration)if suc.Val() {return nil}return errors.New(locales.TM("common.key_exist", nil))
}// RedisDistributedLock 方便的在定时任务中使用
func RedisDistributedLock(key string, expiration time.Duration, execFunction func()) (err error) {// 设置Redis中的键为分布式锁,如果不存在if err = SetNXForLock(key, expiration); err != nil {return fmt.Errorf(fmt.Sprintf("Set redis distributed lock error|key=%s|err=", key), err)}defer func() {if err := recover(); err != nil {logger.Error(fmt.Sprintf("exec function panic: %v", err), nil)}// 删除Redis中的键err = Delete(key)if err != nil {logger.Error(fmt.Sprintf("Delete redis distributed lock error|key=%s|err=", key), err)}}()execFunction()return
}// Get ret需要传指针地址
func Get(key string, ret interface{}) error {c := context.Background()if key == "" {return errors.New("param empty")}err := hystrixPing()if err != nil {return err}handle := redisDB.Get(c, key)if err := handle.Err(); err != nil {return err}res := handle.Val()return json.Unmarshal([]byte(res), &ret)
}func TTL(key string) (int64, error) {c := context.Background()if key == "" {return -1, errors.New("param empty")}err := hystrixPing()if err != nil {return -1, err}handle := redisDB.TTL(c, key)if err := handle.Err(); err != nil {return -1, err}return int64(handle.Val().Seconds()), nil
}// Delete 删除缓存
func Delete(key string) error {c := context.Background()if key == "" {return fmt.Errorf("empty key when delete")}err := hystrixPing()if err != nil {return err}return redisDB.Del(c, key).Err()
}func Expire(key string, expiration time.Duration) error {return redisDB.Expire(context.Background(), key, expiration).Err()
}func Scan(cursor uint64, match string, count int64) *redis.ScanCmd {return redisDB.Scan(context.Background(), cursor, match, count)
}func FlushAll() {redisDB.FlushDB(context.Background())
}// Keys 获取指定 key 的所有值,并以切片的形式返回
func Keys(key string) []string {c := context.Background()var ret []stringerr := hystrixPing()if err != nil {return ret}if key == "" {return ret}handle := redisDB.Keys(c, key)if err := handle.Err(); err != nil {logger.Error("Keys err", err)return ret}res := handle.Val()return res
}// ZAdd 给有序集合中添加元素及分数
func ZAdd(key string, member interface{}, score float64) (int64, error) {c := context.Background()item := &redis.Z{Score:  score,Member: member,}addedCount, err := redisDB.ZAdd(c, key, item).Result()if err != nil {logger.Error("redis add member to zadd error", err)return 0, err}return addedCount, nil
}// ZRemRangeByRank 移除有序集合中给定的排名区间内的所有成员
// Redis ZREMRANGEBYRANK 移除有序集key中,指定排名(rank)区间 start 和 stop 内的所有成员。下标参数start和stop都是从0开始计数,
// 0是分数最小的那个元素。索引也可是负数,表示位移从最高分处开始数。例如,-1是分数最高的元素,-2是分数第二高的,依次类推。
func ZRemRangeByRank(key string, start, stop int64) (int64, error) {c := context.Background()removeCount, err := redisDB.ZRemRangeByRank(c, key, start, stop).Result()if err != nil {logger.Error("redis remove zadd member error", err)return 0, err}return removeCount, nil
}// ZRange 获取有序集合中的元素,并对其按照分数进行从大到小排序
func ZRange(key string, start, stop int64) (members []string, err error) {c := context.Background()members, err = redisDB.ZRange(c, key, start, stop).Result()if err != nil {logger.Error("redis get zadd error", err)return nil, err}if len(members) > 1 {members = utils.ReverseSlice(members)}return
}func SAdd(key string, value interface{}) (int64, error) {c := context.Background()addedCount, err := redisDB.SAdd(c, key, value).Result()if err != nil {logger.Error("redis setting error", err)return 0, err}return addedCount, nil
}func SIsMember(key string, value int) (bool, error) {c := context.Background()existValue, err := redisDB.SIsMember(c, key, value).Result()if err != nil {logger.Error("查询失败", err)return false, err}return existValue, nil
}func SIsMemberString(key string, value string) (bool, error) {c := context.Background()existValue, err := redisDB.SIsMember(c, key, value).Result()if err != nil {logger.Error("查询失败", err)return false, err}return existValue, nil
}// Incr 对redis里的值进行自增操作
func Incr(key string) (int, error) {err := hystrixPing()if err != nil {return 0, err}c := context.Background()cmd := redisDB.Incr(c, key)return int(cmd.Val()), cmd.Err()
}// Decr 对redis里的值进行自减操作
func Decr(key string) (int, error) {c := context.Background()cmd := redisDB.Decr(c, key)return int(cmd.Val()), cmd.Err()
}// DeleteBatch 批量删除缓存
func DeleteBatch(key []string) error {err := hystrixPing()if err != nil {return err}c := context.Background()return redisDB.Del(c, key...).Err()
}func UnlinkPrefixKeys(prefix string) error {err := hystrixPing()if err != nil {return err}c := context.Background()keys, _ := redisDB.Keys(c, prefix).Result()if len(keys) > 0 {// unlink 异步删err = UnlinkKeys(keys)if err != nil {logger.Error("redis unlink keys error", err)}}return nil
}func UnlinkKeys(keys []string) error {err := hystrixPing()if err != nil {return err}c := context.Background()return redisDB.Unlink(c, keys...).Err()
}func HMget(key string, fields []string) (val []interface{}, err error) {c := context.Background()return redisDB.HMGet(c, key, fields...).Result()
}func HSet(key string, field, value interface{}) (res int64, err error) {c := context.Background()return redisDB.HSet(c, key, field, value).Result()
}func HGet(key string, field string) (res string, err error) {c := context.Background()return redisDB.HGet(c, key, field).Result()
}func HDel(key, field string) (res int64, err error) {c := context.Background()return redisDB.HDel(c, key, field).Result()
}func HGetAll(key string) (map[string]string, error) {c := context.Background()return redisDB.HGetAll(c, key).Result()
}func HMSet(key string, fields map[string]string) (bool, error) {c := context.Background()return redisDB.HMSet(c, key, fields).Result()
}func Lock(lockKey string, expiration time.Duration) (bool, error) {var resp *redis.BoolCmdfor {goId := utils.GetCurrentGoroutineId()resp = redisDB.SetNX(context.Background(), lockKey, goId, expiration) //返回执行结果lockSuccess, err := resp.Result()if err == nil && lockSuccess {//抢锁成功,开启看门狗 并跳出,否则失败继续自旋tls.GoSafe(tls.GetLangLocalStorage(), func() { watchDog(goId, lockKey, expiration) })return lockSuccess, err}//time.Sleep(time.Millisecond * 30) //可以适当休眠return lockSuccess, err}
}// 自动续期看门狗
func watchDog(goId int, lockKey string, expiration time.Duration) {// 创建一个定时器NewTicker, 每隔2秒触发一次,类似于闹钟expTicker := time.NewTicker(time.Second * 2)//确认锁与锁续期打包原子化script := redis.NewScript(`if redis.call('get', KEYS[1]) == ARGV[1]thenreturn redis.call('expire', KEYS[1], ARGV[2])elsereturn 0end`)for {select {case <-expTicker.C: //因为上边是用NewTicker创建的定时器,所以每隔2s都会触发resp := script.Run(context.Background(), redisDB, []string{lockKey}, goId, expiration)if result, err := resp.Result(); err != nil || result == int64(0) {//续期失败_, _ = fmt.Printf("expire lock failed:%s", err)}case <-unlockCh: //任务完成后用户解锁通知看门狗退出return}}
}func Unlock(lockKey string) error {script := redis.NewScript(`if redis.call('get', KEYS[1]) == ARGV[1]thenreturn redis.call('del', KEYS[1])elsereturn 0end`)resp := script.Run(context.Background(), redisDB, []string{lockKey}, utils.GetCurrentGoroutineId())if result, err := resp.Result(); err != nil || result == 0 {return fmt.Errorf(fmt.Sprintf("unlock %s failed: %s", lockKey, err))}//删锁成功后,通知看门狗退出unlockCh <- struct{}{}return nil
}// LRange LRange
func LRange(key string, start, stop int64) (members []string, err error) {c := context.Background()members, err = redisDB.LRange(c, key, start, stop).Result()if err != nil {logger.Error("redis get LRange error", err)return nil, err}return
}// RPop RPop
func RPop(key string) (err error) {c := context.Background()err = redisDB.RPop(c, key).Err()if err != nil {logger.Error("redis RPop error", err)return err}return
}// LPush LPush
func LPush(key string, values ...interface{}) (err error) {c := context.Background()err = redisDB.LPush(c, key, values).Err()if err != nil {logger.Error("redis LPush error", err)return err}return
}func LPushValue(key string, value interface{}) error {c := context.Background()if key == "" || value == nil {return errors.New("param empty")}data, err := json.Marshal(value)if err != nil {return err}return redisDB.LPush(c, key, data).Err()
}func RPopValue(key string, ret interface{}) error {c := context.Background()if key == "" {return errors.New("param empty")}handle := redisDB.RPop(c, key)if err := handle.Err(); err != nil {return err}res := handle.Val()return json.Unmarshal([]byte(res), &ret)
}func AddUniqueLock() (err error) {pc, _, _, ok := runtime.Caller(1)if !ok {logger.Info("AddUniqueLock err")return}funcName := runtime.FuncForPC(pc).Name()err = SetNXForLock(fmt.Sprintf("crond_lock:%s", funcName), 3*time.Second)return
}func AddUniqueLockSecTime(sec int64) (err error) {pc, _, _, ok := runtime.Caller(1)if !ok {logger.Info("AddUniqueLock err")return}funcName := runtime.FuncForPC(pc).Name()err = SetNXForLock(fmt.Sprintf("crond_lock:%s", funcName), time.Duration(sec)*time.Second)return
}func Exists(key string) (int64, error) {c := context.Background()return redisDB.Exists(c, key).Result()
}
func SAddNX(key string, value interface{}, expiration time.Duration) (int64, error) {c := context.Background()addedCount, err := redisDB.SAdd(c, key, value).Result()if err != nil {logger.Error("redis setting error", err)return 0, err}redisDB.Expire(c, key, expiration)return addedCount, nil
}func BLPop(key string, timeout time.Duration) ([]string, error) {err := hystrixPing()if err != nil {return nil, err}return redisDB.BLPop(context.Background(), timeout, key).Result()
}func Watch(key string, function func(tx *redis.Tx) error) error {err := hystrixPing()if err != nil {return err}return redisDB.Watch(context.Background(), function, key)
}func RPush(key string, values ...interface{}) (err error) {err = hystrixPing()if err != nil {return err}return redisDB.RPush(context.Background(), key, values).Err()
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/892569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP】语言模型的发展历程 (1)

语言模型的发展历程系列博客主要包含以下文章&#xff1a; 【NLP】语言模型的发展历程 (1)【NLP】大语言模型的发展历程 (2) 本篇博客是该系列的第一篇&#xff0c;主要讲讲 语言模型&#xff08;LM&#xff0c;Language Model&#xff09; 的发展历程。 文章目录 一、统计语…

JNI使用类签名及字段签名获取字段值

1.获取逻辑: 2.获取逻辑实现代码: extern "C" JNIEXPORT void JNICALL Java_com_example_jnibasetypedemo_MainActivity_getAnimalsNameFromJNI(JNIEnv *env, jobject thiz,jobjectArray animals) {jobject animalObj;int len env->GetArrayLength(animals);//获…

Vue 封装公告滚动

文章目录 需求分析1. 创建公告组件Notice.vue2. 注册全局组件3. 使用 需求 系统中需要有一个公告展示&#xff0c;且这个公告位于页面上方&#xff0c;每个页面都要看到 分析 1. 创建公告组件Notice.vue 第一种 在你的项目的合适组件目录下&#xff08;比如components目录&a…

Win10微调大语言模型ChatGLM2-6B

在《Win10本地部署大语言模型ChatGLM2-6B-CSDN博客》基础上进行&#xff0c;官方文档在这里&#xff0c;参考了这篇文章 首先确保ChatGLM2-6B下的有ptuning AdvertiseGen下载地址1&#xff0c;地址2&#xff0c;文件中数据留几行 模型文件下载地址 &#xff08;注意&#xff1…

HTTP-响应协议

HTTP的响应过程&#xff1f; 浏览器请求数据--》web服务器过程&#xff1a;请求过程 web服务器将响应数据-》到浏览器&#xff1a;响应过程 响应数据有哪些内容&#xff1f; 1.和请求数据类似。 2. 响应体中存储着web服务器返回给浏览器的响应数据。并且注意响应头和响应体之间…

爬虫基础之爬取歌曲宝歌曲批量下载

声明&#xff1a;本案列仅供学习交流使用 任何用于非法用途均与本作者无关 需求分析: 网站:邓紫棋-mp3在线免费下载-歌曲宝-找歌就用歌曲宝-MP3音乐高品质在线免费下载 (gequbao.com) 爬取 歌曲名 歌曲 实现歌手名称下载所有歌曲 本案列所使用的模块 requests (发送…

C++ 鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

2025年中科院分区大类划分公布!新增8155本

2025年中科院分区表变更情况 扩大收录范围 2025年的期刊分区表在原有的自然科学&#xff08;SCIE&#xff09;、社会科学&#xff08;SSCI&#xff09;和人文科学&#xff08;AHCI&#xff09;的基础上&#xff0c;增加了ESCI期刊的收录&#xff0c;并根据这些期刊的数据进行…

【前端动效】HTML + CSS 实现打字机效果

目录 1. 效果展示 2. 思路分析 2.1 难点 2.2 实现思路 3. 代码实现 3.1 html部分 3.2 css部分 3.3 完整代码 4. 总结 1. 效果展示 如图所示&#xff0c;这次带来的是一个有趣的“擦除”效果&#xff0c;也可以叫做打字机效果&#xff0c;其中一段文本从左到右逐渐从…

提升租赁效率的租赁小程序全解析

内容概要 在如今快节奏的生活中&#xff0c;租赁小程序俨然成为了提升租赁效率的一把利器。无论是个人还是企业&#xff0c;都会因其便捷的功能而受益。简单来说&#xff0c;租赁小程序能让繁琐的租赁流程变得轻松、高效。在这里&#xff0c;我们将带您畅游租赁小程序的海洋&a…

Docker--Docker Compose(容器编排)

什么是 Docker Compose Docker Compose是Docker官方的开源项目&#xff0c;是一个用于定义和运行多容器Docker应用程序的工具。 服务&#xff08;Service&#xff09;&#xff1a;在Docker Compose中&#xff0c;一个服务实际上可以包括若干运行相同镜像的容器实例&#xff0…

搭建docker私有化仓库Harbor

Docker私有仓库概述 Docker私有仓库介绍 Docker私有仓库是个人、组织或企业内部用于存储和管理Docker镜像的存储库。Docker默认会有一个公共的仓库Docker Hub,而与Docker Hub不同,私有仓库是受限访问的,只有授权用户才能够上传、下载和管理其中的镜像。这种私有仓库可以部…

本地视频进度加入笔记+根据进度快速锁定视频位置

本地视频进度记录快速回溯 引言 在学习的过程中, 如果我们想快速记录当前看视频的位置, 后续回溯查找就会非常方便了。 实现效果 进度记录 通过按下快捷键ctrlaltu&#xff0c; 快速记录当前视频的进度信息,然后复制到typora软件内 快速回溯 在typora软件内, 选中视频索引…

网络传输层TCP协议

传输层TCP协议 1. TCP协议介绍 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一个要对数据的传输进行详细控制的传输层协议。 TCP 与 UDP 的不同&#xff0c;在于TCP是有连接、可靠、面向字节流的。具体来说&#xff0c;TCP设置了一大…

《自动驾驶与机器人中的SLAM技术》ch7:基于 ESKF 的松耦合 LIO 系统

目录 基于 ESKF 的松耦合 LIO 系统 1 坐标系说明 2 松耦合 LIO 系统的运动和观测方程 3 松耦合 LIO 系统的数据准备 3.1 CloudConvert 类 3.2 MessageSync 类 4 松耦合 LIO 系统的主要流程 4.1 IMU 静止初始化 4.2 ESKF 之 运动过程——使用 IMU 预测 4.3 使用 IMU 预测位姿进…

基于大语言模型的组合优化

摘要&#xff1a;组合优化&#xff08;Combinatorial Optimization, CO&#xff09;对于提高工程应用的效率和性能至关重要。随着问题规模的增大和依赖关系的复杂化&#xff0c;找到最优解变得极具挑战性。在处理现实世界的工程问题时&#xff0c;基于纯数学推理的算法存在局限…

【数据库】Unity 使用 Sqlite 数据库

1.找到需要三个 DLL Mono.Data.Sqlite.dllSystem.Data.dllsqlite3.dll 上面两个dll可在本地unity安装目录找到&#xff1a; C:\Program Files\Unity\Hub\Editor\2022.3.xxf1c1\Editor\Data\MonoBleedingEdge\lib\mono\unityjit-win32 下面dll可在sqlite官网下载到&#xff…

冒泡排序基础与实现

目录 1. 原理图 ​编辑 2. 什么是冒泡排序 3. 工作原理 3.1 具体步骤 3.2 时间复杂度 3.3 空间复杂度 4. 代码实现 5. 总结 1. 原理图 2. 什么是冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复地遍历要排序的列表&am…

忘记了PDF文件的密码,怎么办?

PDF文件可以加密&#xff0c;大家都不陌生&#xff0c;并且大家应该也都知道PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密&#xff1f; PDF和offi…

【论文笔记】Sign Language Video Retrieval with Free-Form Textual Queries

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Sign Language Video Retr…