dot Redis 8 发布了——并且是开源的

了解更多

如何使用 Scala 和 Redis 构建强大的在线学习平台

在线学习从未如此普及。 无论您是想了解有关加密货币的更多信息,提高您的编程技能,甚至只是学习一门新语言,数字时代都让每个人都可以访问大量的优质内容。 

然而,随着时间的推移,在线学习已被视为另一种数字商品,用户希望所有在线内容都能即时呈现。速度仍然对性能至关重要,页面加载时间的任何滞后或延迟都会影响用户的体验。 

因此,这些高期望要求任何称职的在线学习平台都必须由能够以超高效率处理、处理和传输数据的数据库提供支持……这正是Launchpad App 使用 Redis 的原因。 

从头到尾,此应用程序旨在通过将学习者与基于其兴趣的最相关的课程联系起来,从而连接、教育和赋能学习者。 

让我们研究一下这是如何实现的。 但在我们深入研究之前,您可能还想查看我们在 Launchpad 上的所有其他精彩应用程序。 

https://www.youtube.com/embed/7k1EXPh3m4s
  1. 您将构建什么? 
  2. 您需要什么?
  3. 架构
  4. 开始

1. 您将构建什么?

您将构建一个强大的在线学习平台,将学生和教师彼此连接起来,以及一个多样化的在线课程库。 速度是性能的关键,您将部署许多不同的 Redis 组件来实现此目标。 

下面我们将揭示使此应用程序得以实现所需的组件以及每个项目的功能。 

2. 您需要什么?

  • Scala/Play Framework/Akka Streams:用作开源 Web 应用程序,使使用 Java 和 Scala 构建应用程序变得容易。
  • React用作 JavaScript 库,可以轻松构建用户界面。
  • RedisGraph用作强大的图形数据库,可将 Cypher 查询转换为在 GraphBLAS 引擎上执行的矩阵运算。
  • Redis Streams:管理数据消耗
  • RedisBloom为 Redis 提供对其他概率数据结构的支持。
  • RedisGears用作 Redis 中数据处理的引擎
  • RediSearch为 Redis 提供强大的搜索引擎。
  • RedisJSON将 ECMA-404 JSON 数据交换标准实现为本机数据类型
  • RedisTimeSeries提供时间序列数据
  • Keycloak用作适用于现代应用程序的开源身份和访问管理解决方案

3. 架构

数据模型通过使用 RedisGraph 的节点和关系来表达。 该模型非常简单,因为它涉及学生、课程和主题实体,表达了彼此之间不同类型的关系。 

X-Mentor 遵循事件驱动架构方法,其中考虑了以下领域事件

  • student-enrolled(学生已注册)
  • student-interested(学生感兴趣)
  • student-interest-lost(学生失去兴趣)
  • course-created(课程已创建)
  • course-rated(课程已评分)
  • course-recommended(课程已推荐)
  • Student-progress-registered(学生进度已注册)

4. 开始

先决条件

  • Docker Engine 和 Docker Compose

步骤 1:克隆存储库

https://github.com/redis-developer/x-mentor

步骤 2:启动 Docker

$ docker-compose ps
Name                         Command               State            Ports              
---------------------------------------------------------------------
x-mentor_x-gears_1           python3 init.py --url redi ...   Up                                   
x-mentor_x-keycloak_1        /opt/jboss/tools/docker-en ...   Up       0.0.0.0:8880->8080/tcp, 8443/tcp
x-mentor_x-mentor-client_1   /docker-entrypoint.sh ngin ...   Up       0.0.0.0:3000->80/tcp            
x-mentor_x-mentor-core_1     /opt/docker/conf/wait-for- ...   Up       0.0.0.0:9000->9000/tcp          
x-mentor_x-redis_1           redis-server --loadmodule  ...   Up       0.0.0.0:6379->6379/tcp          
[node1] (local) [email protected] ~/x-mentor
$ 

步骤 3:访问应用程序

等待 Keycloak 和 x-mentor-core 准备就绪,然后转到 https://:3000。 

您可以通过 8880 端口访问 Keycloak,如下所示

使用 admin/admin 登录到 Keycloak。

步骤 4:登录

此步骤通过以下方式启动针对 Keycloak 的身份验证过程

  1. 验证用户的用户名是否已存在于 users Bloom 过滤器中
  2. 提供身份验证令牌

使用以下代码检查并查看用户名是否已存在于 users Bloom 过滤器中

BF.EXISTS users '${student.username}'

步骤 5:注册

注册涉及 4 个步骤

  1. 针对 Keycloak 注册用户
  2. 将用户的用户名添加到 users Bloom 过滤器
  3. 在 RedisGraph 中创建用户
  4. 添加学生的时序键(注册学生进度需要)
  • 要将用户名添加到 users Bloom 过滤器,请插入以下代码
BF.ADD users '${student.username}'
  • 要将学生集成到图中,请使用以下代码
GRAPH.QUERY xmentor "CREATE (:Student {username: '${student.username}', email: '${student.email}'})"
  • 要创建学生进度时序键,请使用以下代码
TS.CREATE studentprogress:${username} RETENTION 0 LABELS student ${username}

步骤 6:创建课程

在此步骤中,我们将向您展示如何创建课程以在在线学习平台上发布。 每门课程都将作为 JSON 存储在 RedisJSON 中。 

:

按照以下命令操作

  1. 从 Redis 键 course-last-index 获取最后一个课程 ID
GET course-last-index
  1. 将课程 ID 键增加 1
INCR course-last-index
  1. 将课程作为 JSON 存储在 redisJSON 中
JSON.SET course:${course.id} . '${course.asJson}'
  1. 将课程 ID 添加到课程 Bloom 过滤器
BF.ADD courses '${course.id}'
  1. 在图中创建课程
GRAPH.QUERY xmentor "CREATE (:Course {name: '${course.title}', id: '${course.id.get}', preview: '${course.preview}'})"
  1. 发布课程创建事件,该事件通过服务器发送事件将通知发送到前端
XADD course-created $timestamp title ${course.title} topic ${course.topic}

步骤 7:注册课程

在这里,我们将揭示如何让学生注册特定课程。 

以下是您需要遵循的步骤

  • 验证学生是否存在于 users Bloom 过滤器中
BF.EXISTS users ${student.username}
  • 从 redisJSON 获取课程作为 JSON
JSON.GET course:${course.id}
  • 突出显示 redisGraph 中学生和课程之间的关系
GRAPH.QUERY xmentor "MATCH (s:Student), (c:Course) WHERE s.username = '${studying.student}' AND c.name = '${studying.course}' CREATE (s)-[:studying]->(c)"

步骤 8:课程评论

作为任何在线资源的一部分,用户通常能够提供评论。 要实现此功能,您需要执行以下步骤

  1. 首先,验证学生和课程之间是否存在学习关系。 
  2. 接下来,验证学生和课程之间是否存在评分关系。
  3. 第三,在图中创建评分关系(参见下图)。
  4. 发布事件 course-rated 流

下图说明了 Redis Graph 和 Redis Streams 之间的交互。

要实现此功能,请按照以下命令操作

  • 按学生过滤课程
GRAPH.QUERY xmentor "MATCH (student)-[:studying]->(course) where student.username = '$student' RETURN course"
  • 获取用户评级的课程
GRAPH.QUERY xmentor "MATCH (student)-[:rates]->(course) where student.username ='$student' RETURN course"
  • 在图中创建评分关系
GRAPH.QUERY xmentor "MATCH (s:Student), (c:Course) WHERE s.username = '${rating.student}' AND c.name = '${rating.course}' CREATE (s)-[:rates {rating:${rating.stars}}]->(c)"
  • 将事件发布到 course-rated 流
XADD course-rated $timestamp student $student_username course $course 
	starts $stars

步骤 9:课程搜索

所有

以下命令从 redisJSON 中检索带有 rediSearch 的查询课程

FT.SEARCH courses-idx ${query}*

按 ID

BF.EXISTS courses ${course.id}

JSON.GET course:${course.id}

按学生

GRAPH.QUERY xmentor “MATCH (student)-[:studying]->(course) where student.username = ‘$student’ RETURN course”

FT.SEARCH courses-idx ${course.title}

步骤 10:学生的兴趣

现在我们将向您展示如何允许学生根据自己的兴趣过滤首选课程。 下面是如何操作的

  1. 从 RedisGraph 获取所有感兴趣的关系。 
  2. 区分已经存在的关系和新的关系。 这将允许您将新的兴趣与现有的兴趣分开。 
  3. 在 RedisGraph 中创建新的感兴趣的关系
  4. 删除不再适用的感兴趣的关系
  5. 发布到 student-interest-lost 和 student-interested 流

下图显示了 RedisGraph 和 Redis Streams 之间的交互。

以下是您需要遵循的命令

  • 捕获所有学生的兴趣
GRAPH.QUERY xmentor "MATCH (student)-[:interested]->(topic) WHERE 
student.username ='$student' RETURN topic"
  • 创建兴趣关系
GRAPH.QUERY xmentor "MATCH (s:Student), (t:Topic) WHERE s.username = 
	'${interest.student}' AND t.name = '${interest.topic}' CREATE 
(s)-[:interested]->(t)"
  • 删除兴趣关系
GRAPH.QUERY xmentor "MATCH (student)-[interest:interested]->(topic) WHERE student.username='${interest.student}' and topic.name='${interest.topic}' DELETE interest"
  • 发布到 student-interested 流
XADD student-interest-lost $timestamp student ${student.username} topic $topic
  • 发布到 student-interest-lost 流
XADD student-interest-lost $timestamp student ${student.username} topic $topic

步骤 11:课程推荐系统

在这里,我们将向您展示如何创建一个课程推荐系统,将用户与与其兴趣最相关的课程联系起来。 这在很大程度上取决于 RedisGraph 的高级功能。 

在图形数据库中搜索节点之间的关系是实现最有效推荐策略的最简单方法。 让我们看看如何做到这一点。

为了让您创建一个特殊的推荐系统,将用户的个人兴趣与最相关的课程相匹配

如何执行注册推荐策略
  1. 随机选择学生注册的课程 
  2. 获取课程的主题
  3. 查找注册了同一课程的学生
  4. 根据当前注册的学生搜索同一主题的课程
  5. 推荐这些课程
如何执行兴趣推荐策略
  1. 随机选择学生的兴趣
  2. 查找注册了该主题课程的学生
  3. 根据当前注册的学生搜索同一主题的其他课程
  4. 提供推荐的课程 
如何执行发现推荐策略
  1. 获取所有主题
  2. 识别学生感兴趣的所有主题
  3. 收集用户注册的所有主题 
  4. 选择用户既不感兴趣也不注册的主题
  5. 获取所选主题的课程并推荐它们 
如何访问图形数据
  • 所有学生的课程
GRAPH.QUERY xmentor "MATCH (student)-[:studying]->(course) where student.username = '$student' RETURN course"
  • 获取所有主题
GRAPH.QUERY xmentor "MATCH (topic:Topic) RETURN topic"
  • 按课程获取主题
GRAPH.QUERY xmentor "MATCH (topic:Topic)-[:has]->(course:Course) 
  • 识别注册(学习关系)课程的学生
GRAPH.QUERY xmentor "MATCH (student)-[:studying]->(course) WHERE course.name = '$course' RETURN student"
  • 按主题生成课程
GRAPH.QUERY xmentor "MATCH (topic)-[:has]->(course) WHERE 
	topic.name = '${topic.name}' RETURN course"
  • 揭示学生的兴趣
GRAPH.QUERY xmentor "MATCH (student)-[:interested]->(topic) WHERE student.username ='$student' RETURN topic"
  • 根据主题过滤学生注册的课程
GRAPH.QUERY xmentor "MATCH (student)-[:studying]->(course), 
	(topic)-[:has]->(course) where student.username = '${student.username}'  
	and topic.name = '${topic.name}' RETURN course"
  • 识别用户注册的主题
GRAPH.QUERY xmentor "MATCH (student)-[:studying]->(course), (topic)-[:has]->(course) WHERE student.username = '${student.username}' RETURN topic"

步骤 12:学生进度注册

此功能将允许您跟踪用户在平台上观看课程所花费的时间。 然后,该信息将用于实施排行榜。 

一旦 x-mentor-core 收到请求,它将发布学生进度注册域事件。这将最终通过以下命令成为 student-progress-registered 流(这是一个 Redis 流)中的一个元素

XADD student-progress-registered $timestamp student $student_username duration $duration

所有发送到 RedisGears 的数据都将被推送到流中,然后使用以下命令将此数据汇集到 Redis TimeSeries 中

TS.ADD studentprogress:$student_username $timestamp $duration RETENTION 0 LABELS student $student_username

第 13 步:排行榜

排行榜功能使您可以拥有一个排行榜,显示使用 X-Mentor 的顶级学生的排名。学生根据他们在平台上观看内容的时间长短进行排名——观看时间越长,排名越高。

要实现这一点,您需要分离两个功能

  • 注册学生进度
  • 获取排行榜数据

当用户请求排行榜数据时,首先在 Redis 中查找时间序列键

LRANGE student-progress-list 0 -1 // to retrieve all the list elements

对于每个键,您需要使用 Redis TimeSeries 获取三个月时间窗口内的样本范围,并执行求和聚合。您可以使用以下代码来实现这一点

TS.RANGE $student_key $thee_months_back_timestamp $timestamp AGGREGATION sum 1000

以下是为此需要实施的额外先决条件。

  • student_key 是学生的时间序列键。例如:studentprogress:codi.sipes 是学生 codi.sipes 的时间序列键。
  • three_months_back_timestamp 是一个 Unix 时间戳,表示比 timestamp 晚三个月的时间点(以便拥有三个月的时间窗口)。
  • timestamp 是当前时间戳(Unix 时间戳格式)。
  • 接下来,使用 1000 毫秒的时间桶对这些时间窗口中的样本值执行求和聚合。

执行这些命令将为您提供每个学生的累计屏幕时间。一旦您收到这些排名,您就可以根据屏幕时间最多的人创建一个排名系统。

结论:使用 Redis 赋能学习者

在这个数字时代,任何应用程序的一个简单先决条件就是以最快的速度运行。对于电子学习平台来说尤其如此,因为用户需要在很长一段时间内参与其课程内容。

仅仅是延迟就会在用户和应用程序之间产生摩擦,从而抑制其连接教师和学生以及通过其课程提供价值的能力。将 Redis 作为应用程序的主要数据库消除了这种威胁,并帮助创建了一个完全优化的应用程序,可以轻松满足用户的需求。

要更直观地了解此应用程序是如何创建的,您可以观看此YouTube 视频。我们还在 Redis Launchpad 上为您提供各种应用程序,这些应用程序正在对世界各地的日常生活产生影响。

请务必查看它们!

谁构建了这个应用程序?

Sergio Cano

塞尔吉奥是一位全栈工程师,用他自己的话说,“喜欢解决问题和学习新东西。”

作为一个热情的学习者,不难看出他从哪里获得了构建此应用程序的灵感。

请务必点击此处查看他的个人资料,看看他还参与了哪些其他项目。