当前位置: 首页 > ai >正文

Redis中灵活结合SET和SETEX的方法及多语言工具库实现

Redis中灵活结合SET和SETEX的方法及多语言工具库实现

本文介绍如何结合Redis的SETSETEX命令实现灵活的键值操作,并提供Python、C++和Golang的封装工具库源码。


一、设计思路

通过创建统一的set函数整合两种操作:

  1. 支持永不过期(使用SET)和可过期数据(使用SETEX)
  2. 支持批量操作和异步执行
  3. 封装连接池管理
  4. 支持标准JSON序列化

二、Python实现

# redis_tool.py
import json
import redis
from typing import Union, Anyclass RedisTool:def __init__(self, host='localhost', port=6379, db=0, pool_size=10):self.pool = redis.ConnectionPool(host=host, port=port, db=db, max_connections=pool_size)def _get_conn(self):return redis.Redis(connection_pool=self.pool)def set(self,key: str,value: Union[dict, list, str, bytes],expire: int = 0  # 0表示永不过期) -> bool:"""存储数据(支持JSON和二进制)"""conn = self._get_conn()# 序列化处理if isinstance(value, (dict, list)):value = json.dumps(value)elif not isinstance(value, (str, bytes)):raise TypeError("Unsupported value type")# 选择命令if expire > 0:return conn.setex(key, expire, value)return conn.set(key, value)def get(self, key: str, parse_json: bool = False) -> Any:"""获取数据(支持JSON解析)"""conn = self._get_conn()result = conn.get(key)if result and parse_json:return json.loads(result)return resultdef batch_set(self, items: dict, expire: int = 0):"""批量设置键值"""conn = self._get_conn()pipe = conn.pipeline()for key, value in items.items():if isinstance(value, (dict, list)):value = json.dumps(value)if expire > 0:pipe.setex(key, expire, value)else:pipe.set(key, value)pipe.execute()

三、C++实现(基于hiredis)

// redis_tool.hpp
#include <hiredis/hiredis.h>
#include <string>
#include <unordered_map>
#include <nlohmann/json.hpp>class RedisTool {
public:RedisTool(const std::string& host = "127.0.0.1", int port = 6379) : context_(redisConnect(host.c_str(), port)) {}~RedisTool() {redisFree(context_);}bool set(const std::string& key, const std::string& value, int expire = 0) {redisReply* reply = nullptr;if (expire > 0) {reply = (redisReply*)redisCommand(context_, "SETEX %s %d %b", key.c_str(), expire, value.data(), value.size());} else {reply = (redisReply*)redisCommand(context_, "SET %s %b", key.c_str(), value.data(), value.size());}bool success = reply && reply->type == REDIS_REPLY_STATUS;freeReplyObject(reply);return success;}bool set_json(const std::string& key, const nlohmann::json& value, int expire = 0) {return set(key, value.dump(), expire);}std::string get(const std::string& key) {redisReply* reply = (redisReply*)redisCommand(context_, "GET %s", key.c_str());std::string result;if (reply && reply->type == REDIS_REPLY_STRING) {result = std::string(reply->str, reply->len);}freeReplyObject(reply);return result;}template<typename T>T get_json(const std::string& key) {auto str = get(key);return nlohmann::json::parse(str).get<T>();}private:redisContext* context_;
};

四、Golang实现

// redis_tool.go
package redis_toolimport ("context""encoding/json""time""github.com/go-redis/redis/v8"
)type RedisClient struct {client *redis.Clientctx    context.Context
}func NewRedisClient(addr string, db int) *RedisClient {return &RedisClient{client: redis.NewClient(&redis.Options{Addr: addr,DB:   db,}),ctx: context.Background(),}
}func (rc *RedisClient) Set(key string, value interface{}, expiration time.Duration) error {// 自动序列化JSONvar val interface{}switch v := value.(type) {case string, []byte:val = vdefault:data, err := json.Marshal(v)if err != nil {return err}val = data}return rc.client.Set(rc.ctx, key, val, expiration).Err()
}func (rc *RedisClient) Get(key string) (string, error) {return rc.client.Get(rc.ctx, key).Result()
}func (rc *RedisClient) GetJSON(key string, v interface{}) error {data, err := rc.client.Get(rc.ctx, key).Bytes()if err != nil {return err}return json.Unmarshal(data, v)
}func (rc *RedisClient) BatchSet(items map[string]interface{}, expiration time.Duration) {pipe := rc.client.Pipeline()for k, v := range items {pipe.Set(rc.ctx, k, v, expiration)}pipe.Exec(rc.ctx)
}

五、使用示例

Python:
tool = RedisTool()
tool.set("user:1", {"name": "John", "age": 30}, expire=3600)  # 带过期时间
user = tool.get("user:1", parse_json=True)
C++:
RedisTool rt;
rt.set_json("config:app", {{"theme", "dark"}, {"lang", "en"}}, 86400);
auto config = rt.get_json<nlohmann::json>("config:app");
Golang:
client := NewRedisClient("localhost:6379", 0)
client.Set("cache:homepage", "<html>...</html>", 10*time.Minute)var user User
client.GetJSON("user:100", &user)

六、设计优势

  1. 智能序列化​:自动处理JSON转换
  2. 过期策略统一​:expire=0表示永不过期
  3. 连接复用​:内置连接池管理
  4. 批量操作​:减少网络开销
  5. 类型安全​:C++模板强化类型检查

完整项目地址:https://github.com/example/redis-toolbox

通过此设计,开发者可以灵活选择存储策略,简化了缓存管理和持久化存储的统一操作,同时保证了多语言环境下API的一致性。

https://github.com/0voice

http://www.xdnf.cn/news/17715.html

相关文章:

  • iscc2025决赛wp
  • docker load镜像后 名字和标签异常解决
  • [前端算法]排序算法
  • 2023 年全国硕士研究生招生考试真题笔记
  • B站 韩顺平 笔记 (Day 17)
  • MySQL表约束
  • 【新手入门】Android Studio 项目结构拆解,快速理解文件作用!
  • 6 .循环-for
  • 边缘节点 DDoS 防护:CDN 节点的流量清洗与就近拦截方案
  • 会议征稿!IOP出版|第二届人工智能、光电子学与光学技术国际研讨会(AIOT2025)
  • C# 反射和特性(获取Type对象)
  • Python 类元编程(元类基础知识)
  • 【Part 4 未来趋势与技术展望】第一节|技术上的抉择:三维实时渲染与VR全景视频的共生
  • Go语言实战案例:使用Gin处理路由参数和查询参数
  • Nginx 超详细详解和部署实例
  • 【Python】新手入门:什么是python运算符?python运算符有哪些种类?运算符优先级是怎么样的?
  • 顺序表 —— OJ题
  • HarmonyOS Navigation路由跳转的完整示例
  • 用了Cursor AI之后,我的编程效率翻倍了?——一位程序员的真实体验分享
  • 区块链技术原理(9)-什么是以太币
  • 飞算JavaAI云原生实践:基于Docker与K8s的自动化部署架构解析
  • redis 内存使用率高居高不下,如何分析 key占用情况
  • Eclipse RCP产品动态模块设计
  • [AI React Web]`意图识别`引擎 | `上下文选择算法` | `url内容抓取` | 截图捕获
  • C++主流string的使用
  • 海康视觉平台VM创建项目
  • [Oracle数据库] ORACLE的用户维护和权限操作
  • 猫头虎AI分享:Excel MCP,让AI具备操作Excel表格|创建销售数据表、复制工作表、填充数据、写公式、绘制图表、调节颜色、添加透视表、保存为PDF
  • el-select如何获取到filterable过滤后的数据;el-select全选与filterable过滤组合使用;
  • Python 中使用多进程编程的“三两”问题