ITOO考评学生端性能优化——Redis

2024-08-27 15:18

本文主要是介绍ITOO考评学生端性能优化——Redis,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【项目背景】

    1.学生抽题慢
    2. 做学生端的时候发现学生每次做一道题的时候触发一次数据库,把数据更新到数据库里面,这样子学生端前台响应很慢,每次点击的时候都有1-2秒的延迟。然后当学生多的时候,不断的对一张表进行更改,大家都懂得。


【解决方案】

    (加Redis)

1. 把共用的东西放到Redis里面

2. 师姐的意思大体是这样子的,我每次更新的时候并不是更新的数据库,而是Redis,一段时间后内容把整个都提交到数据库里面。(反正原话我已经忘记了……)

【代码展示】


       1. 关于问题1

            其实解决抽题中的公共部分,而且给的文档很详细很简单:

    
/**
* 代码逻辑:
* 首先查看Redis是否有题型
* 如果有的话,直接读取Redis的内容,如果没有的话,就去数据库里面查
**/
public void queryComponentById(HttpServletRequest request,
HttpServletResponse response) {
System.out.println("进入查询组件方法");
String perSortTypeId = request.getParameter("questionTypeId");
if (perSortTypeId == null || perSortTypeId.equals("")) {
return;
}
// jediscluster.del(perSortTypeId);
// 定义题型集合
List<QuestionTypeDetail> questionTypesDetailList = new ArrayList<QuestionTypeDetail>();
String getQuestionTypeDetail=jediscluster.get(perSortTypeId);
if (getQuestionTypeDetail==null || getQuestionTypeDetail.equals("")) {
questionTypesDetailList = examPageBean.queryComponentById(perSortTypeId, dataBaseName);
if (questionTypesDetailList==null || questionTypesDetailList.equals("")) {
System.out.println("没有相应的题型组件");
}else{
try {
jediscluster.set(perSortTypeId,JsonUtils.objectToJson(questionTypesDetailList));
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
JsonUtils.jsonToList(getQuestionTypeDetail, QuestionTypeDetail.class);
}
JacksonJsonUntil.beanToJson(response, questionTypesDetailList);
 
主要用到的Redis的代码例子:
    
//添加list
@RequestMapping("test4")
public void test4(HttpServletRequest request,
HttpServletResponse response) throws Exception {
jediscluster.set("listkey" ,JsonUtils.objectToJson(list));
}
     
//查询list
@RequestMapping("test6")
public void test6(HttpServletRequest request,
HttpServletResponse response) throws Exception {
List<EnrollStudent> enrollStudentList = new ArrayList<EnrollStudent>();
//获取缓存
String json = jediscluster.get("listkey");
//将json转化为list
enrollStudentList = JsonUtils.jsonToList(json,EnrollStudent.class);
}

    2. 关于问题2

     昨天才接触Redis,我还比较单纯,已经对于Redis的操作,只有文档上面的Get,set这两个方法。所以当郭郭跟我说,重名的时候,数据就会被覆盖了,我一测试,可不是嘛,于是我果断的用 perSortTypeId作为key值。
   
    但是,今天在查询的时候,才知道是因为我直接set,如果用list存储结构,用lpush()方法就能轻松解决问题了。但是也是因为关于底层Redis封装的方法太少了,用起来一直在各种转换。

    
/**
* 根据课程id,学生id,试卷id,数据库;查询考生答题记录;
* 十一期 谭倩倩
* 修改人:谭倩倩
* 修改原因:添加Radis
* @param request
* @param response
*/
@RequestMapping("/queryStudentRecord")
public void queryStudentRecord(HttpServletRequest request,
HttpServletResponse response)
{
//课程id
String CourseId= examineeArrangement.getCourseId();
//学号
String StudentCode = examineeArrangement.getStudentId();
//试卷id
String PaperId = examineeArrangement.getPaperMainId();
//数据库
String DateBaseName = "itoo_exam";
//查询考生答题记录
//把查询出来的学生答题记录保存用Radis下来_十一期 谭倩倩
List<PaperRecord> ListPaperRecord=new ArrayList<PaperRecord>();
String stuPaperRecord=examineeArrangement.getStudentId()+"ListPaperRecord";
// String getListPaperRecord=jediscluster.get(stuPaperRecord);
List<String> getListPaperRecord= jediscluster.lrange(stuPaperRecord, 0, jediscluster.llen(stuPaperRecord)-1); //lrange()方法是来查询出所有以stuPaperRecord为key健的值,上面说过因为是list结构存储。
if (getListPaperRecord==null || getListPaperRecord.equals("")||getListPaperRecord.size()==0) {
ListPaperRecord = paperRecordBean.queryAllStuPaperRecord(CourseId, StudentCode, PaperId, DateBaseName);
for (int i = 0; i < ListPaperRecord.size(); i++) {
PaperRecord enPR=ListPaperRecord.get(i);
try {
jediscluster.lpush(stuPaperRecord, JsonUtils.objectToJson(enPR));
} catch (IOException e) {
// TODO:单个实体存入Redis
e.printStackTrace();
}
}
}else{
// List<PaperRecord> changeRecord= (List<PaperRecord>)getListPaperRecord;
ListPaperRecord.clear();
for (int i = 0; i < getListPaperRecord.size(); i++) {
PaperRecord enPaRecord=JsonUtils.jsonToPojo(getListPaperRecord.get(i), PaperRecord.class);
ListPaperRecord.add(enPaRecord);
}
}
JacksonJsonUntil.beanToJson(response, ListPaperRecord);
}

    
重点逻辑:
  1. 获取Redis存储数据的个数作为循环的条件
    把list的每个实体查询出来,匹配对应的答案,
    更新list里面的数据
//缓存更新
List<PaperRecord> stuListPaperRecord=new ArrayList<PaperRecord>();
String stuPaperRecord=examineeArrangement.getStudentId()+"ListPaperRecord";
long count=jediscluster.llen(stuPaperRecord);//获取Redis存储数据的个数
// stuListPaperRecord=JsonUtils.jsonToList(StrListPaperRecord,PaperRecord.class);
if (count==0) {
examPageBean.updatePaperRecord(studentAnswer, questionId, score,teacherCode, examineeArrangement);
}else{
//更新缓存,
for (long i = 0; i < count; i++) {
//TODO:自己测试用
String strPR=jediscluster.lindex(stuPaperRecord, i);
// int i=(int)count;
// PaperRecord enPaperRecord=stuListPaperRecord.get(i);
// if (getEn.length()>0) {
// PaperRecord paperRecord=new PaperRecord();
PaperRecord paperRecord=JsonUtils.jsonToPojo(strPR, PaperRecord.class);
if (paperRecord.getQuestionContentId().equals(questionId)) {
paperRecord.setStudentAnswer(studentAnswer);
String jsonPaRecord;
try {
jsonPaRecord = JsonUtils.objectToJson(paperRecord);
jediscluster.lset(stuPaperRecord, i, jsonPaRecord);//更新Redis里面的数据
System.out.println("答题记录写入缓存成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


总结:

     其实,我是在点击“交卷”的时候把数据存储到数据库的。
       我感觉我的Redis仅仅是用了一点点,并没有很好地利用。以后有机会自己再多学习一下,感谢我老公和红霞给我各种指导和建议。
     还有,就是不要仅仅依赖技术文档。这次我明显感觉到文档给我的满足不了业务需求,不要尝试用自己的简单逻辑处理,先去查查网上有没有好的方法。




这篇关于ITOO考评学生端性能优化——Redis的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112033

相关文章

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过