Redis设置Key/value的规则定义和注意事项(附工具类)

2023-05-16

Redis设置Key/value的规则定义和注意事项(附工具类)

对于redis的存储key/value键值对,经过多次踩坑之后,我们总结了一套规则;这篇文章主要讲解定义key/value键值对时的定义规则和注意事项。


前面一篇文章讲了如何定义Redis的客户端和Dubbo集成存储器;当我们真正开始开发的时候,就会突然发现,有点不知道如何去定义Redis的Key和Value值格式,不要着急,马上我们就可以明白如何去定义和使用,下面我们开始讲解如何定义。

Spring+Dubbo集成Redis的两种解决方案

1、redis value 值格式

在Java常规开发中,我们需要有面向对象的思想,相对于对象来说,比较常用且能快速转换的格式就是 JSON 了;比较常用的Java处理JSON数据有三个比较流行的类库FastJSONGsonJackson,他们的优劣点这里我就不一一介绍了,本文用阿里的FastJSON

上面提到了JSON,这是因为在Redis的存储中,我们使用它来存储value值,为什么要这样做呢?主要是因为json格式有如下几种好处:

· 1.标准,主流数据交换格式
· 2.简单,结构清晰,相对于XML来说更加的轻量级,易于解析
· 3.语言无关,任何语言都能轻松搞它
· 4.类型安全,值是有类型的,比如整数、字符串、布尔等

下面我们来看看如何使用json来存储value,代码如下:


/**
 * 在redis数据库中插入 key和value 并且设置过期时间
 *
 * @param key k
 * @param value v
 * @param exp   过期时间 s
 * @return boolean
 */
@Override
public boolean set(String key, V value, int exp) {
    Jedis jedis = null;
    // 将 value 转换成 json 对象
    // String jKey = JSON.toJSONString(key);
    String jValue = JSON.toJSONString(value);
    // 操作是否成功
    boolean isSucess = true;
    if (StringUtils.isEmpty(key)) {
        LOG.info("key is empty");
        return false;
    }
    try {
        // 获取客户端对象
        jedis = redisCache.getResource();
        // 执行插入
        jedis.setex(key, exp, jValue);
    } catch (Exception e) {
        LOG.info("client can't connect server");
        isSucess = false;
        if (null != jedis) {
            // 释放jedis对象
            redisCache.brokenResource(jedis);
        }
        return false;
    } finally {
        if (isSucess) {
            // 返还连接池
            redisCache.returnResource(jedis);
        }
    }
    return true;
}

代码中redis value在存储前我们对其做了一次转换,将对象V转换为json对象后存储;下面我们来看看在redis中value值的格式:

zhangsan

上面我们可以看到在redis可视化工具rdm(Redis Desktop Manager)中,key键对应的value用json非常清晰的显示出来了,非常方便我们查阅redis中存储的数据。

不知道大家注意到没有,上面的代码中有一行我是注释掉了,代码如下:

// String jKey = JSON.toJSONString(key);

这一行的意思是将key键也json化,不是说json非常友好吗?那为什么要注释这一行呢?下面为大家解释为何要这样做。

首先,使用json格式的数据都会变成一个josn格式的String字符串,比如 "zhangsan" ,当这个字符串作为key存储时,默认会带有json的特性,那就是双引号 "" 也会带入到redis的key设置中,所以在rdm中我们看到的key值都会默认带上 "" ,这样着实不是非常的美观,特别是对于我们的复杂业务而言,后面会给大家讲如何在rdm中使用key值规则定义业务线文件夹。

json zhangsan

2、redis key 键格式

上面讲了简单的key存储,如 zhangsan 的存储,此时普通的需求可以满足;然而在实际业务中,往往key键的存储会非常的复杂,比如我们现在有一个需求:

需求:根据基础数据系统中的数据字典类型查询对应的字典集合

这时,我们需要关注的业务就变得复杂了,就不能使用常规的key键存储方式,上面的需求大致可以拆分为:

1.系统:基础数据系统
2.模块:数据字典
3.方法:根据数据字典类型查询
4.参数:字典类型

为什么要这样拆分呢?为了可读性;也为了抽象出key存储规则;因为业务复杂情况下,我们定义的key键太多时就不便于管理,也不便于查找,以 系统-模块-方法-参数 这样的规则定义,我们可以很清晰的了解redis key存储的值是做了什么事情,而且rdm中也可以以此来分组,后面会讲到。

下面贴上根据此规则定义抽象出的redis工具类:

package com.yclimb.mdm.redis;

/**
 * Redis 工具类
 *
 * @author yclimb
 * @date 2018/4/19
 */
public class RedisUtils {

    /**
     * 主数据系统标识
     */
    public static final String KEY_PREFIX = "mdm";
    /**
     * 分割字符,默认[:],使用:可用于rdm分组查看
     */
    private static final String KEY_SPLIT_CHAR = ":";

    /**
     * redis的key键规则定义
     * @param module 模块名称
     * @param func 方法名称
     * @param args 参数..
     * @return key
     */
    public static String keyBuilder(String module, String func, String... args) {
        return keyBuilder(null, module, func, args);
    }

    /**
     * redis的key键规则定义
     * @param module 模块名称
     * @param func 方法名称
     * @param objStr 对象.toString()
     * @return key
     */
    public static String keyBuilder(String module, String func, String objStr) {
        return keyBuilder(null, module, func, new String[]{objStr});
    }

    /**
     * redis的key键规则定义
     * @param prefix 项目前缀
     * @param module 模块名称
     * @param func 方法名称
     * @param objStr 对象.toString()
     * @return key
     */
    public static String keyBuilder(String prefix, String module, String func, String objStr) {
        return keyBuilder(prefix, module, func, new String[]{objStr});
    }

    /**
     * redis的key键规则定义
     * @param prefix 项目前缀
     * @param module 模块名称
     * @param func 方法名称
     * @param args 参数..
     * @return key
     */
    public static String keyBuilder(String prefix, String module, String func, String... args) {
        // 项目前缀
        if (prefix == null) {
            prefix = KEY_PREFIX;
        }
        StringBuilder key = new StringBuilder(prefix);
        // KEY_SPLIT_CHAR 为分割字符
        key.append(KEY_SPLIT_CHAR).append(module).append(KEY_SPLIT_CHAR).append(func);
        for (String arg : args) {
            key.append(KEY_SPLIT_CHAR).append(arg);
        }
        return key.toString();
    }

    /**
     * redis的key键规则定义
     * @param redisEnum 枚举对象
     * @param objStr 对象.toString()
     * @return key
     */
    public static String keyBuilder(RedisEnum redisEnum, String objStr) {
        return keyBuilder(redisEnum.getKeyPrefix(), redisEnum.getModule(), redisEnum.getFunc(), objStr);
    }

}

上面代码中有此文字描述 分割字符,默认[:],使用:可用于rdm分组查看 ;redis key默认使用冒号分割,好处在于可以在rdm中以文件夹的形式分组查看,如图:

冒号分组

3、使用枚举类来定义规则

上面的工具类中的有如下代码,使用了枚举的形式来赋值:

/**
 * redis的key键规则定义
 * @param redisEnum 枚举对象
 * @param objStr 对象.toString()
 * @return key
 */
public static String keyBuilder(RedisEnum redisEnum, String objStr) {
    return keyBuilder(redisEnum.getKeyPrefix(), redisEnum.getModule(), redisEnum.getFunc(), objStr);
}

下面是枚举类代码:

package com.yclimb.mdm.redis;

/**
 * Redis 枚举类
 *
 * @author yclimb
 * @date 2018/4/19
 */
public enum RedisEnum {

    /**
     * 数据字典Service - 根据字典类型查询字典数据
     */
    MDM_MSTDATADICTIONARYSERVICE_QUERYLISTBYENTITYREDIS(
            RedisUtils.KEY_PREFIX, "MstDataDictionaryService", "queryListByEntityRedis", "数据字典Redis缓存");

    /**
     * 系统标识
     */
    private String keyPrefix;
    /**
     * 模块名称
     */
    private String module;
    /**
     * 方法名称
     */
    private String func;
    /**
     * 描述
     */
    private String remark;

    RedisEnum(String keyPrefix, String module, String func, String remark) {
        this.keyPrefix = keyPrefix;
        this.module = module;
        this.func = func;
        this.remark = remark;
    }

    getter and setter....
}

使用上面的枚举类,可以根据模块和方法定义需要的枚举类型,便于管理和维护,使用起来也非常方便,使用代码如下:


@Override
public List<MstDataDictionary> queryListByEntityRedis(MstDataDictionary mstDataDictionary) {
	// redis key 获取
	String redisKey = RedisUtils.keyBuilder(RedisEnum.MDM_MSTDATADICTIONARYSERVICE_QUERYLISTBYENTITYREDIS, (null == mstDataDictionary ? "" : mstDataDictionary.toString()));
	// 查询redis缓存
	List<MstDataDictionary> mstDataDictionaryList = (List<MstDataDictionary>) redisCacheService.get(redisKey);
	// 如果没有缓存则查询数据库后赋值
	if (mstDataDictionaryList == null || mstDataDictionaryList.size() <= 0) {
		mstDataDictionaryList = mstDataDictionaryMapper.queryListByEntity(mstDataDictionary);
		redisCacheService.set(redisKey, mstDataDictionaryList);
	}
	return mstDataDictionaryList;
}

OK,到这里就差不多讲完了,根据上面所说的分模块方式,自定义redis的key键名称,value值格式使用json来存储;

对于key键的规则定义也可以使用 Constants 常量类来实现,具体规则看个人爱好和需求。

结语

具体的定义规则工具类代码都在上面了,也是源码。

到此本文就结束了,关注公众号查看更多推送!!!


关注我的公众号


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis设置Key/value的规则定义和注意事项(附工具类) 的相关文章

  • 如何在多线程应用程序中使用 StackExchange.Redis IDatabase 对象?

    我从 StackExchange Redis 文档中收到有关如何使用 IDatabase 的混合消息 在里面基本使用文档 https github com StackExchange StackExchange Redis blob mas
  • 有没有办法在 Redis 和关系数据库中使用带有 @RedisHash 的实体?

    我正在使用Spring引导 为了将我的实体保存在关系数据库上 我配置了一个数据源和我的域类 例如 Entity Table schema schema name name tb name public class table name ex
  • 使用 data.table 中的多个键来获得条件搜索

    我有一个data table首先 我想根据某些条件获得一个子集 例如 我有 library data table dt lt data table rn 1 10 B rep 1 2 5 dt rn B 1 1 1 2 2 2 3 3 1
  • 连接到 localhost:6379 时出现错误 99。无法分配请求的地址

    设置 我有一个虚拟机 并在虚拟机中运行三个容器 一个 nginx 代理 一个非常简约的 Flask 应用程序和 redis Flask 应在端口 5000 上提供服务 而 redis 应在 6379 上提供服务 这些容器中的每一个都可以作为
  • 使用 sidekiq 处理两个独立的 Redis 实例?

    下午好 我有两个独立但相关的应用程序 他们都应该有自己的后台队列 阅读 单独的 Sidekiq 和 Redis 进程 然而 我希望偶尔能够将工作推给app2的队列来自app1 从简单的队列 推送的角度来看 如果app1没有现有的 Sidek
  • 如何清理redis中不活跃的玩家?

    我正在制作一个使用 redis 来存储游戏状态的游戏 它可以很好地跟踪位置和玩家 但我没有一个好的方法来清理不活跃的玩家 每当玩家移动时 这是一个半慢速移动游戏 想想每秒 1 5 帧 我就会用新位置更新哈希并删除旧位置键 跟踪活跃玩家的最佳
  • Docker&Celery - 错误:Pidfile (celerybeat.pid) 已存在

    应用程序包括 姜戈 雷迪斯 芹菜 码头工人 Postgres 在将项目合并到 docker 之前 一切都运行顺利且正常 但是一旦将其移入容器 就开始出现问题 起初它开始得很好 但过了一会儿我确实收到了以下错误 celery beat 1 E
  • AWS Redis 从外部连接

    有没有办法从外部 AWS 网络连接 AWS 上托管的 Redis 实例 我有一个基于 Windows 的 EC2 实例在 AWS 上运行 另一个是 Redis 缓存节点 我知道有人问过这个问题 但答案是在基于 Linux 的系统中 但我的是
  • socket.io redis 和内存泄漏

    我的socket io版本是 电子邮件受保护 cdn cgi l email protection and 电子邮件受保护 cdn cgi l email protection 我在 Windows 上 在某些地方 我看到问题已得到解决 我
  • 使用brew在MacOSx上安装Redis JSON

    如何使用brew 在 macOSx 上安装 RedisJSON 如何在不编译redis的情况下启用redis上的模块 我不想使用 docker 客户端 Redis Stack 可能是最简单的方法 它不仅仅是 RedisJSON 还包括 Re
  • 如何从 python 将无穷大传递给 redis?

    我正在使用 redis py 并希望将 inf 和 inf 与 ZRANGEBYSCORE 一起使用 我尝试使用 inf 的字符串和浮点来执行此操作 但它们返回一个空集 我怎样才能做到这一点 EDIT 我尝试执行以下命令 redis Str
  • 我的 Redis 自动生成的密钥

    我不知道我的 Redis 版本 4 0 9 到底发生了什么 我正在运行一个应用程序并使用 Redis 来存储我的数据库 但是 然后 Redis 自动创建 3 个新键 Backup1 Backup2 Backup3 并删除我的所有数据 这是我
  • 为什么Redis中不建议使用KEYS?

    在Redis中 建议不要使用按键命令 https redis io commands KEYS 为什么会这样呢 是因为它的时间复杂度是 O N 吗 或者是别的什么原因 我做了下面的实验来证明KEYS命令有多么危险 当带有 KEYS 的一个命
  • Outlook 添加、文本框、删除\退格键不起作用

    我开发了一个 Outlook 插件 自定义任务窗格 在用户控件中带有 Web 浏览器 当我在网络浏览器的文本框中写入内容时 退格键或删除按钮旁边的所有功能都运行良好 但我无法使用这些键 我是否遗漏了什么 我迟到了几年 但我设法解决了这个问题
  • Spring Data Redis - Lettuce连接池设置

    尝试在 spring data redis 环境中设置 Lettuce 连接池 下面是代码 Bean LettuceConnectionFactory redisConnectionFactory GenericObjectPoolConf
  • 如何在C#中捕获键盘上的按键

    我有个问题 我需要写一个C 程序 输入 允许用户输入多行文本 按 Ctrl Enter 完成输入 输出 标准化 按照时间增加的正确顺序重新排列行 我尝试过 但我不知道如何从键盘捕获 Ctrl Enter 我期望输出像 例子 Created
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • Spring Data Redis JedisConnectionException:流意外结束

    雷迪斯3 0 5Spring数据Redis 1 3 6绝地武士2 6 3 我们的 Web 应用程序通过 pub sub 从 Redis 接收数据 还以键 值对的形式在 Redis 上执行数据读 写 读 写发生在监听线程 独立监控线程和htt
  • jq:删除具有空字符串值的键

    我有以下 JSON data NAME Test 1 ID 1 IP 192 168 1 2 80 NAME Test 2 ID 2 IP NAME Test 3 ID 3 IP 192 168 1 3 80 NAME Test 4 ID
  • Caffeine Expiry 中如何设置多个过期标准?

    我正在使用 Caffeine v2 8 5 我想创建一个具有可变到期时间的缓存 基于 值的创建 更新以及 该值的最后一次访问 读取 无论先发生什么都应该触发该条目的删除 缓存将成为三层值解析的一部分 The key is present i

随机推荐

  • Linux 入门

    文章目录 一 概述二 安装CentOS下载地址VMware下载地址 三 linux文件与目录结构Linux系统中一切皆文件Linux目录结构 四 VI VIM 编辑器vi vim是什么一般模式常用语法键盘图编辑模式指令模式 五 网络配置六
  • S_OK,S_FALSE,E_FAIL

    今天在调试一个ICOP的操作的时候 xff0c 发现连接被动关闭的时候老是会在一处断言处失败 xff0c 跟了很久终于发现了问题 在此记录一下 xff1a 断言报错的代码如下 xff1a HRESULT CIoCPWorker UnregI
  • 游戏开发图书推荐--我读过的技术经典图书

    很多同学问我学游戏开发应该看些什么书 xff0c 我在这里抛砖引玉 xff0c 给一份推荐表 xff0c 希望大家共同提高 由于本人英文不太好 xff0c 推荐的大部书籍都是国人编写的 xff0c 有些经典的外文图书可能是翻译不好 xff0
  • Win7 应用程序无法正常启动(0xc000000d)的解决方法

    自从重装了WIN7系统后 xff0c VS2010编译出来的项目程序就不能正常启动 xff0c 启动的时候总是提示 应用程序无法正常启动 xff08 0xc000000d xff09 请单击 确定 关闭应用程序 在网上查找了很多解决方案 x
  • MySQL存储过程where条件执行失败的问题

    前几天对服务器实体做了属性缓存机制 xff0c 当时测试也没有出现大的问题 xff0c 昨天有人跟我说 xff0c 登陆的时候角色等级显示错误 xff0c 我复测了一下 xff0c 发现不只是等级错误 xff0c 进入游戏后角色位置 金钱
  • VS2010/VS2012 设置全局头文件和库路径

    在VS2010之前 xff0c 设置项目的全局头文件和库路径是非常方便的 xff0c 直接选择菜单Tools gt Options gt Projects and Solutions gt VC 43 43 Directories xff0
  • Linux下rz/sz安装及使用方法

    新搞的云服务器用SecureCRT不支持上传和下载 xff0c 没有找到rz命令 记录一下如何安装rz sz命令的方法 一 工具说明 在SecureCRT这样的ssh登录软件里 通过在Linux界面里输入rz sz命令来上传 下载文件 对于
  • 关于mysql存储过程创建动态表名及参数处理

    转载请注明出处 xff1a 帘卷西风的专栏 http blog csdn net ljxfblog 最近游戏开始第二次内测 xff0c 开始处理操作日志 xff0c 最开始把日志放到同一个表里面 xff0c 发现一天时间 xff0c 平均1
  • 关于mysql自增id的获取和重置

    转载请注明出处 xff1a 帘卷西风的专栏 http blog csdn net ljxfblog mysql获取自增id的几种方法 使用max函数 xff1a select max id from tablename 优点 xff1a 使
  • LXC的安装与配置使用

    1 简介 在云端技术的领域 xff0c 虚拟系统扮演了重要的角色 xff0c 但不管虚拟系统怎样演进 xff0c 效能如何的提升 xff0c 不可否认的虚拟系统 xff08 Guest OS xff09 对实体系统 xff08 Host O
  • 关于SQL中Union和Join的用法

    转载请注明出处 xff1a 帘卷西风的专栏 http blog csdn net ljxfblog 一直以来 xff0c 对于数据库SQL方面都是半吊子水平 xff0c 能写一些基本的增删改查的语句 xff0c 大部分时间都是用下Where
  • 使用Cmake生成跨平台项目编译解决方案

    项目最近有需求在windows下面运行 xff0c 我花了几周时间将linux的服务器移植到windows下面 xff0c 目前已经能够正常运行服务器 xff0c 目前又有了新需求 xff0c 两边的代码结构和组织是分开的 xff0c 因此
  • linux下shell技巧

    经常看到一些大牛操作linux的时候 xff0c 双手运指如飞 xff0c 指令如流水般输出 xff0c 会不会感到羡慕呢 xff1f 本文就整理了一些linux下shell的技巧 xff0c 保管你学会之后 xff0c shell输出ap
  • Cmake在windows支持预编译头文件(stdafx.h)

    最近一直在研究cmake构建项目 xff0c 之前接触cmake的时候就感觉不太喜欢cmake xff0c 觉得它太乱了 xff0c 产生了太多的中间文件 xff0c 产生的项目文件也不是特别友好 xff0c 在windows下 xff0c
  • 位置控制代码

    Copyright c 2013 2016 PX4 Development Team All rights reserved Redistribution and use in source and binary forms with or
  • 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。

    最近公司开发网站针对微信公众号的支付功能 由于公司目前的这个项目网站是使用asp代码开发的 xff0c 但是微信官方给出的demo中是没有asp版本的 xff0c 所以楼主只有下载demo的php版本作为参考写了一个asp版本的代码 阅读官
  • Nacos实战一:架构及部署

    2018年 xff0c 阿里巴巴开源 Nacos xff0c 由此成为继 Eureka Consul Apollo 等服务注册发现 amp 配置的又一开源框架 xff0c 到如今2021年 xff0c Nacos 已经历了 0 01 gt
  • Windows Server搭建Tomcat服务器及Java项目应用

    Windows Server搭建Tomcat服务器及Java项目应用 本文主要介绍使用阿里云Windows Server搭建Tomcat服务器及Java项目应用 xff0c 将文章写下来以后自己也可以及时看看 工具和软件 服务器 xff1a
  • 【Node.js】安装使用nvm管理nodejs版本

    Node js 安装使用nvm管理nodejs版本 本文主要介绍mac linux下如何安装nvm来管理nodejs版本 一 下载nvm安装 方式一 xff1a brew方式 1 xff1a brew list nvm 命令检测是否安装nv
  • Redis设置Key/value的规则定义和注意事项(附工具类)

    Redis设置Key value的规则定义和注意事项 xff08 附工具类 xff09 对于redis的存储key value键值对 xff0c 经过多次踩坑之后 xff0c 我们总结了一套规则 xff1b 这篇文章主要讲解定义key va