APP下载

采用Redis高并发应用系统设计与实现方法∗

2020-07-13周立军

计算机与数字工程 2020年5期
关键词:任务调度课表内存

张 杰 刘 凯 周立军

(海军航空大学航空基础学院 烟台 264001)

1 引言

随着互联网信息技术的发展,校园信息化程度不断提升,传统的信息系统一般可抽象为三层相对独立模型:表示层、应用层和数据库层,并且在维护、部署、稳定性等方面具有一定的优势,但是在并发性和扩展性方面,存在难以逾越瓶颈。当今移动互联网高速发展已经深刻影响数字化校园的系统架构,尤其时移动互联网的广泛应用,用户前端展示与访问已经不再局限于单一的Web、Win-Form、APP等形式[1],甚至包括对第三方开放的扩展服务,此时信息系统的并发访问能力将成为每一个系统必须面对的关键问题。

本文主要阐述了信息系统高并发访问涉及的相关技术,针对数据库读写系统瓶颈,即数据库读写属于磁盘IO,性能低[2~3],分析了选课系统中高并发的功能点,通过将选课部分数据和业务逻辑转移到内存缓存,并搭建了一个基于Redis高速读写的高并发选课系统,实现了选课信息发布、学生选课及课表查询等功能,通过实验表明:采用Redis的选课系统在高并发访问性能方面具有明显优势,响应速度和并发处理能力有较大提升。

2 系统总体设计

选课计划系统用于根据教学计划、教学资源等,每周制定的选课计划及相关信息,供学员在除正课之外的时间进行自主选择,系统分为包括教务处、教研室、学生管理单位及学生等角色,其中本文重点分析选课子系统的设计与实现。

图1 系统功能设计

选课子系统主要功能包括选课批次管理、选课计划管理、学员选课、选课排课、系统管理等,其中,学员选课包括多种展示方式,如Web网页、APP终端、Win-Form程序等形式,并且当选课的课程表发布时,会存在短时间内高并发访问操作情况发生,并且对系统的稳定性与并发处理能力要求较高,为了提升系统扩展性、降低程序耦合度,系统设计实现时将前端显示和业务处理分离。

图2 选课系统总体架构

系统功能按照服务进行拆分,用户经过授权后,可调用选课系统开放的服务完成相应功能,如选课业务中学员经登陆验证后,通过RESTful API调用系统后端选课服务。

3 关键技术

本文提出的高并发系统设计方法涉及的关键技术主要包括:Redis缓存热点数据和Quartz任务调度定时加载热点数据。

3.1 Redis内存数据库

Redis是一种基于内存的高性能Key-Value数据库[4],在解决高并发与大数据等应用场景,可用于提升热点数据访问的性能,Redis与传统的关系型数据库有所不同,支持链表(List)、字符串(String)、集合(set)和有序集合(zset)等4种抽象数据结构,此外,还支持数据计算中常用的集合并、交和补集等操作及多种排序算法[5],Redis所有数据都是保存在内存中,通过不定期半持久化模式(异步方式保存到磁盘上)和持久化模式等操作,提供周期性地把数据操作写到AOF文件中,数据恢复时将数据加载到内存中,保障数据安全,在Redis中缓存的选课数据及所使用数据类型如表1所示。

表1 热点数据缓存及类型说明

3.2 Quartz作业调度

Quartz是一个开源完全作业调度框架,将任务调度的相关问题进行了抽象,提出了调度器、触发器和任务等三个核心概念,分别对应Scheduler、Trigger和Job,为应用程序进行作业调度提供了简单强大的机制,当一个在预先确定的任务(如定时发布选课课表)的时间到达时,负责执行指定任务或功能(将选课数据加载到Redis数据缓存),Quartz实现上述功能的主要接口是Scheduler,通过SchedulerFactory创建一个Scheduler任务调度实例,它提供了的操作包括:将任务纳入日程或者从日程中取消、开始/停止/暂停日程进度等,其中Trigger和Job是任务调度的元数据,Scheduler是实际执行调度的控制器,Trigger是用于定义调度时间的元素,描述触发Job执行的时间触发规则,Job用于表示被调度的任务,按状态可分为无状态(stateless)和有状态(stateful)两种类型。对于同一个trigger来说,有状态的job不能被并行执行,只有上次触发的任务被执行完之后,才能触发下次执行[6~7]。

Quartz作业调度框架与Java内置java.util.Tim⁃er定时器相比,除了具有可持久化、灵活、功能强大等优点,Quartz可通过cron表达式精确到特定时间执行,且Quartz每次执行任务都将创建一个新的对象,所以某一次执行任务过程中抛出异常,对下一次任务的执行不会产生影响,Timer在执行某个任务程中抛出异常,则整个定时器生命周期就结束,将失去定时器的作用[8]。

4 系统核心业务设计与实现

选课子系统核心业务是学员选课,具体业务流程包括:

1)教研室为单位,提交下一周自主学习训练任务,教研室应主要对本学期开设课程安排辅导答疑和实验室自习等自主学习任务;

2)教科处审核并发布自主学习训练计划;

3)学员通过个人账户登录校园网(周末),制定自主学习计划;

4)教科处进入选课管理进行学员调整和选开课排课;

5)发布每周自主学习选排课供查询、下载、打印。

图3 系统高并发核心业务分析

通过分析选课子系统核心业务流程中存在高并发的模块主要涉及:学生选课的课表信息(按周进行发布)和学员个人课表查询,在系统实现时,采用Quartz任务调度,在给定时间(每周六24点)按教学周将选课数据从Mysql数据库缓存至Redis服务器,学生按照教学周查询已经开放的课表时直接从Redis内存中读取数据,较大程度提升客户端相应速度和数据处理能力[9]。

图4 高并发选课业务流程

选课业务中存在典型的高并发应用场景,供学员选课的信息在特定时间发布,学员会在课程发布后集中完成选课操作,由于选课课程有明确人数限制,高并发选课操作发生时,频繁的数据库查询和写入操作,容易导致数据库宕机[10],为了缓解数据库服务器的处理能力与高并发访问的矛盾,系统采用以下设计方法进行改进:

1)由定时器按教学周,读取选课课程数据进行Redis缓存;

2)当学员选择一门课程时,首先检查是否已选过,并检查是否已经超过人数限制,满足条件进行选课,否则返回选课失败及原因;

3)实现选课操作,生成学员选课记录并存入到Redis,更新选课人数;

4)使用Redis消息队列发送选课记录,消息接收后完成存入Mysql数据库。

在第2)、3)步骤完成的动作,必须满足事务性和原子性,否则在高并发情况下,无法保证数据一致性,但Redis为了保证性能,其事务具有一定局限性(如不支持回滚)[11~12],为了解决这个问题,可采用Lua编写脚本,提交到Redis执行,Redis会将整个Lua脚本作为一个整体执行,在执行过程中不会被其他命令插入(Redis具有单线程特性),第2)、3)步骤对应的Lua脚本如下:

通过将Lua脚本嵌入到选课服务端,当学员选课时调用Lua脚本,借助Lua脚本,Redis将多个查询、修改等动作包装成一个具有原子性操作,在提升了性能的同时,可有效保证数据一致性。

5 实验分析

在高并发情况下,如集中学员选课场景,容易出现多人同时对已选课人数进行查询与修改,为了保证数据一致性,防止出现超出选课人数限制的情况发生,传统实现方法是对该部分数据进行加锁(如排它锁、乐观锁、悲观锁等)[13],但普遍存在性能上的缺失,导致系统并发处理能力降低[14]。通过使用Redis将选课相关热点数据存入缓存,建立Tom⁃cat+Redis+Mysql建立高并发选课系统,缓解高并发时数据库的访问压力,并提升处理性能。

为了验证系统构架在并发处理能力方面的性能,选择Apache JMeter进行负载功能测试和性能测试,相比其他测试软件(如Loadrunner),JMeter具有轻量、开源等优势[15~16]。分别设计两种方案:传统数据库(方案1)与Redis数据缓存(方案2)方式分别完成选课操作,使用JMeter建立用户线程方式分别模拟500、1000、2000用户在1s内并发访问选课系统,如表2所示,实验环境软件硬件条件:i5/8G内 存 、Windows 7/Jdk1.8/Tomcat8.5/Jmeter5.0/Je⁃dis2.4/Mysql5.6。

表2 Jmeter性能统计数据(时间单位:ms)

实验数据表明:采用Redis数据缓存方式,在并发处理能力的各项指标提升明显,尤其是吞吐量(单位时间处理请求的数量)可提升40%左右。

6 结语

本文分析了当前信息系统在应对高并发访问存在的瓶颈,以典型的学员选课应用场景为例,从系统设计到核心功能实现,阐述了使用Redis将选课等热点数据进行缓存,针对选课并发操作的过程,采用Lua脚本实现多个动作(Redis查询、修改等)封装成一个原子性操作[17],在提升Redis操作性能同时,有效避免数据不一致性;最后,通过使用Jmeter性能测试工具,对文中提出数据缓存方案与传统数据库实现方式对比进行测试,测试结果表明Redis数据缓存方式并发性能明显提升,本文使用Quartz和Redis提升系统并发能力的方法,具有一定的通用性和借鉴作用。

猜你喜欢

任务调度课表内存
基于生产函数的云计算QoS任务调度算法
学生出招解决”日课牌“问题
基于动态能量感知的云计算任务调度模型
如果我是校长
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
INNO EDU 创新教育大会
内存搭配DDR4、DDR3L还是DDR3?
各地区学生课表
基于HMS的任务资源分配问题的研究