Redis内存空间节省小技巧

news2024/11/16 19:51:55

        背景:为提升会员对当前等级的权益感知,需对用户仍未领取的权益进行弹框或消息位置推荐,会员需推荐权益有10+项,且项权益均需需校验当日推荐次数并做推送限制,推荐次数记入Redis缓存,会员数据庞大,将占用大量内存空间。

        常规做法:key键 = 前缀(RECOMMONE) + 会员号(USERID) + 权益编码(REGISTER),每个会员每项权益维护一个推荐值,大量消耗内存空间;

        压缩设计:key键 = 前缀(RECOMMONE) + 会员号(USERID) ,采用同一用户只记录一条权益推荐记录,提前确认权益推荐次数的最大值并分配占位位数,每项权益通过占位标识来获取。例如值为0101040201,前两位01标识生活权益,后两个01标识注册有礼。每两位代表一项权益记录位。如图示:

实现过程:

1)定义权益枚举

       

@AllArgsConstructor
@Getter
public enum RecommendRedisPlaceholderEnum {
/**
 * 缓存键
 */
private String redisKey;
/**
 * 偏移量,及占用位置起始值
 */
private int offset;
/**
 * 占用长度
 */
private int size;
/**
 *乘率,位置计算时使用
 */
private long rate;
/**
 * 描述
 */
private String desc;
}

枚举设置:

说明如FIRST_ORDER("RECOMMEND_DAY_CHECK:", 5, 2, 10000,"生日奖励")

如果当前KEY值为0101040201, 偏移量5,表示第5位开始为生日有礼权益占位,占用Size为2位,计算时乘率为10000(设置生日有礼权益推荐值时,incryBy需要增加的值为次数*乘率

    

REGISTER_GIFT("RECOMMEND_DAY_CHECK:", 1, 2,1, "注册有礼"),

UPGRADE_GIFT("RECOMMEND_DAY_CHECK:", 3, 2, 100,"升级有礼"),

FIRST_ORDER("RECOMMEND_DAY_CHECK:", 5, 2, 10000,"生日奖励"),

EXCLUSIVE("RECOMMEND_DAY_CHECK:", 7, 2,1000000L, "每月券包"),

BRAND_DISCOUNT("RECOMMEND_DAY_CHECK:", 9, 2,100000000L, "生活特权"),

     

2)设置缓存值

        传入需增长值incNum及权益枚举类。通过incNum * reEnum.getRate() 计算用户当前权益值需增加的数值。调用incrByLong设置权益新值。

 /**

   * @param key  redis的key

   * @param incNum 需要自增的数值

   * @param time  redis的失效时间

   */

    public long setRedisValue(String key, long incNum, long time ,RecommendRedisPlaceholderEnum reEnum){

        long n = incNum * reEnum.getRate();

        if(sfRedisUtil.setNxWithAtomicity(key, String.valueOf(n), time, TimeUnit.SECONDS)){

            return incNum;

        }

        long result = sfRedisUtil.incrByLong(key, n);

        if(result == 0){

            return 0;

        }

        return handleValue(String.valueOf(result), reEnum.getOffset(), reEnum.getSize());

}

3)获取权益缓存值

        传入权益值及枚举类,通过枚举中的offset及size确定当前权益所占权益值的位置,通过sbustring截取获得。

  public int findDayRedisValue(String userId, RecommendRedisPlaceholderEnum reEnum, RecommendEquityFlowContext context){

    if(StringUtils.isNotBlank(context.getRecommendDayRedis())){

        return handleValue(context.getRecommendDayRedis(), reEnum.getOffset(), reEnum.getSize());

    }

    String value = sfRedisUtil.get(reEnum.getRedisKey()+userId);

    context.setRecommendDayRedis(value);

    return handleValue(value,reEnum.getOffset(),reEnum.getSize());

 }

4)根据缓存值计算权益次数公共方法

/**

     * 处理字符串返回对应数字

     * @param value 缓存值

     * @param offset 偏移量

     * @param size    占用位数

     * @return

     */

    private int handleValue(String value, int offset, int size){

        try {

            if(!StringUtils.isNumeric(value) || value.length() < offset || offset < 1 || size < 1){

                return 0;

            }

            int length = value.length();

            size = Math.min(length, size);

            // 计算权益开始结束位置

            int endIndex = length - offset + 1;

            int beginIndex = endIndex - size;

            beginIndex = Math.max(beginIndex, 0);

            String valueString = value.substring(beginIndex, endIndex);

            return StringUtils.isNumeric(valueString) ? Integer.parseInt(valueString) : 0;

        }catch (Exception e){

            log.error("RedisPlaceholderUtils handleValue is error");

        }

        return 0;

    }

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

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

相关文章

[实战]加密传输数据解密

前言 下面将分享一些实际的渗透测试经验&#xff0c;帮助你应对在测试中遇到的数据包内容加密的情况。我们将以实战为主&#xff0c;技巧为辅&#xff0c;进入逆向的大门。 技巧 开局先讲一下技巧&#xff0c;掌握好了技巧&#xff0c;方便逆向的时候可以更加快速的找到关键函数…

代码随想录 Leetcode226.翻转二叉树

题目&#xff1a; 代码(首刷看解析 2024年1月25日&#xff09;&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if(root nullptr) return root;swap(root->left,root->right);invertTree(root->left);invertTree(root->right);retu…

Java面试提纲

JDK 1 jdk1.8版本后的新特性有哪些? Java Development Kit (JDK) 1.8&#xff08;也称为Java 8&#xff09;在2014年3月发布&#xff0c;引入了许多重要的新特性&#xff0c;以下是其中的一些关键特性&#xff1a; Lambda表达式&#xff1a; Java 8引入了lambda表达式&#x…

java大数据hadoop2.9.2 Linux安装mariadb和hive

一、安装mariadb 版本centos7 1、检查Linux服务器是否已安装mariadb yum list installed mariadb* 2、如果安装了&#xff0c;想要卸载 yum remove mariadb rm -rf /etc/my.cnf rm -rf /var/lib/mysql 才能完全删除 3、安装mariadb 在线网络安装 yum install -y mari…

java常见的面试问题

目录 一、异常 1、 throw 和 throws 的区别&#xff1f; 2、 final、finally、finalize 有什么区别&#xff1f; 3、try-catch-finally 中哪个部分可以省略&#xff1f; 4、try-catch-finally 中&#xff0c;如果 catch 中 return 了&#xff0c;finally 还会执行吗&#…

vue3 实现自定义radio

需求背景解决效果bgRadio.vue 需求背景 实现一个自定义选中样式的 radio 解决效果 bgRadio.vue <!--/** * author: liuk * date: 2024/01/25 * describe: 背景单选框 * email: 1229223630qq.com */--> <template><div class"radio-wrap"><l…

Linux 互斥锁、读写锁、条件变量以及信号量

互斥锁 同步与互斥概述 现代操作系统基本都是多任务操作系统&#xff0c;即同时有大量可调度实体在运行。在多任务操作系统中&#xff0c;同时运行的多个任务可能&#xff1a; 都需要访问/使用同一种资源多个任务之间有依赖关系&#xff0c;某个任务的运行依赖于另一个任务 …

AP5216 平均电流型LED降压恒流驱动IC 手电筒汽车摩托车灯芯片

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W&#xff0c;最大电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮…

Java 集合Map相关面试题

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

如何使用docker实现越权漏洞-webug靶场搭建(超详解)

越权漏洞-webug靶场搭建 1.打开docker systemctl start docker 2.查找webug docker search webug 3.拉取docker.io/area39/webug 镜像 docker pull docker.io/area39/webug 4.查看镜像 docker images 5.创建容器 docker run -d -p 8080:80 --name webug docker.io/area39/we…

哈夫曼树(Huffman)

哈夫曼树 Huffman 编码问题 问题引入 什么是编码&#xff1f; 简单说就是建立【字符】到【数字】的对应关系&#xff0c;如下面大家熟知的 ASC II 编码表&#xff0c;例如&#xff0c;可以查表得知字符【a】对应的数字是十六进制数【0x61】 \000102030405060708090a0b0c0d…

五款焊在电脑上的效率软件

在当今快节奏的商业环境中&#xff0c;提高工作效率成为了每个人都渴望实现的目标。尤其是在面对繁忙的工作日程、庞杂的任务清单和团队合作的压力时&#xff0c;我们需要一些可靠的工具来帮助我们更好地管理时间、组织工作和提高生产力。幸运的是&#xff0c;现在有许多高效的…

k8s的图形化工具--rancher

什么是rancher&#xff1f; rancher是一个开源的企业级多集群的k8s管理平台 rancher和k8s的区别 都是为了容器的调度和编排系统&#xff0c;但是rancher不仅能够调度&#xff0c;还能管理k8s集群&#xff0c;自带监控&#xff08;普罗米修斯&#xff09; 实验部署 实验架构…

分类预测 | Matlab实现GRU-Attention-Adaboost基于门控循环单元融合注意力机制的Adaboost数据分类预测/故障识别

分类预测 | Matlab实现GRU-Attention-Adaboost基于门控循环单元融合注意力机制的Adaboost数据分类预测/故障识别 目录 分类预测 | Matlab实现GRU-Attention-Adaboost基于门控循环单元融合注意力机制的Adaboost数据分类预测/故障识别分类效果基本描述程序设计参考资料 分类效果 …

WinSCP如何使用公网TCP地址访问本地服务器

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…

基于 Gurobi 的纸浆运载船顺序装卸决策建模求解|Gurobi优化应用

Pulp-Carrier-Loading-Optimization-with-Gurobi 基于 Gurobi 的纸浆运载船顺序装卸决策建模求解。中山大学智能工程学院《运筹学》课程期末建模课程设计。优化工具&#xff1a;Python的Gurobi 项目仓库 Github: Pulp-Carrier-Loading-Optimization-with-Gurobi 摘要 本研究…

信驰达科技多款TI CC2340R5系列低功耗蓝牙模块强势上线

信驰达科技基于TI CC2340R5推出了多款蓝牙串口模块&#xff0c;包括RF-BM-2340B1、RF-BM-2340B1I、RF-BM-2340A2、RF-BM-2340A2I、RF-BM-2340C2&#xff0c;RF-BM-2340x系列低功耗蓝牙模块采用TI CC2340R5 5 mm x 5 mm(VQFN40) 和4 mm x 4 mm(VQFN24)封装SoC&#xff0c;支持板…

信息检索与数据挖掘 | (十二)聚类

文章目录 &#x1f4da;聚类&#x1f4da;KMeans&#x1f4da;层次聚类&#x1f407;层次聚类概述&#x1f407;dendrogram-树状图&#x1f407;linkages-衡量两个类之间的距离&#x1f407;Lance-Williams算法&#x1f407;K-means VS 层次聚类 &#x1f4da;DBSCAN &#x1f…

pdf怎么转换成jpg图片?pdf转图片工具用它就够了

有时候&#xff0c;我们可能需要将pdf文档转换为图片格式&#xff0c;以便于文档的处理和管理。通过将pdf转换为图片&#xff0c;可以将每一页pdf转换为独立的图片文件&#xff0c;便于整理、存储和管理&#xff0c;如果您有多个PDF文件需要转换成图片&#xff0c;可以批量pdf转…

WorkPlus AI智能客服解决方案,提升企业服务质量

在当今竞争激烈的商业环境中&#xff0c;提供卓越的客户服务成为企业赢得市场竞争的关键。而AI智能客服技术的不断发展&#xff0c;则成为了提高服务效率和满意度的利器。作为一款领先的AI助理解决方案&#xff0c;WorkPlus AI助理以其出色的性能和智能化的功能&#xff0c;助力…