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

相关文章

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

Redis Pipeline(管道) 详解

《RedisPipeline(管道)详解》Pipeline管道是Redis提供的一种批量执行命令的机制,通过将多个命令一次性发送到服务器并统一接收响应,减少网络往返次数(RTT),显著提升执行效率... 目录Redis Pipeline 详解1. Pipeline 的核心概念2. 工作原理与性能提升3. 核

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Redis在windows环境下如何启动

《Redis在windows环境下如何启动》:本文主要介绍Redis在windows环境下如何启动的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis在Windows环境下启动1.在redis的安装目录下2.输入·redis-server.exe

Redis实现延迟任务的三种方法详解

《Redis实现延迟任务的三种方法详解》延迟任务(DelayedTask)是指在未来的某个时间点,执行相应的任务,本文为大家整理了三种常见的实现方法,感兴趣的小伙伴可以参考一下... 目录1.前言2.Redis如何实现延迟任务3.代码实现3.1. 过期键通知事件实现3.2. 使用ZSet实现延迟任务3.3

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.