一种使用 Redis 深度驱动的,为构建轻量级分布式应用程序(Microservices)的工程方案(一)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 一种使用 Redis 深度驱动的,为构建轻量级分布式应用程序(Microservices)的工程方案(一)

Hydra 是一个轻量级的 NodeJS 库,用于构建分布式计算应用程序,比如微服务。我们对轻量级的定义是:轻处理外部复杂性和基础设施依赖 —— 而不是有限的轻处理。 Hydra 声称对基础设施的依赖很轻,这是因为它唯一的外部依赖是 Redis

Hydra 利用 Redis 丰富的数据结构来实现重要的微服务所需的功能。如 presence(在线状态)、service discovery (服务发现)、load balancing (负载平衡)、messaging(消息传递)、queuing(队列)等。


Hydra 到底是什么?


Hydra 是一个 NodeJS 模块,可以将其导入到 JavaScript Node 应用程序中,以使其具有微服务功能。Hydra 通过利用 Redis 做到这一点。


在这里,我们看到三个微服务 - 每个微服务都带有一个连接到 Redis 的 Hydra 模块。在这种模式下,大多数服务不会直接与 Redis 通信。而是底层的 Hydra 模块代理 Redis。


微信图片_20220610212435.png

关于此图的另一点是,Hydra 只是另一个导入的模块 - 如绿色所示。Hydra 在底部仅以蓝色显示,以说明其存在和与 Redis 的关系。

Hydra 模块公开一个 JS 类接口,该接口共有36个成员函数。


微信图片_20220610212446.png

该快照提供了简化抽象的感觉。成员函数(例如 findServicesendMessage)非常简单。


Hydra 如何利用 Redis



这张幻灯片显示了许多重要的微服务问题。每个都是 non-trivial(非平凡的) 微服务所必需的。我们将详细研究 Hydra 如何使用 Redis 来实现所有这些功能。

微信图片_20220610212503.png


请记住,这里的目标是展示如何做到这一点 —— 而不是说每种方法都是您应该如何在自己的服务中实现该特性。一个恰当的例子是,虽然你可以在 Redis 中存储你的微服务配置数据,或者使用 Redis 作为一个 logger —— 但这并不意味着你应该这样做。至少,除非你确切地知道你在做什么,以及需要做哪些权衡。


另外,请记住,您也许不需要Hydra。这些功能都是由 Redis 实现的,您当然可以在自己的应用程序中做到这一点。(如:Golang 来一版)

我将向您展示的一个关键点是,其中一些特性只有在组合时才能实现。例如,请求(request)和消息路由(message routing)依赖于状态(presence)、运行状况(health)、服务发现(service discovery)和负载平衡(load balancing)。


如您所知,这些特性中的每一个都可以使用各种基础设施工具来解决。然而,Hydra 的一个关键目标是简化构建微服务,同时最小化外部基础设施需求。在构建可用于生产的服务时,您需要决定需要哪些 Hydra 特性,以及哪些特性将从其他工具获得。这不是一个非此即彼的命题,而是一个你想要达到的目标和你能多快开始的问题。


就是说,很有趣的是,仅使用 Redis 和您喜欢的编程语言就可以实现所有这些功能。


Key 空间组织



了解 Hydra 如何利用 Redis 的第一步是查看它如何组织对 Redis key 空间的使用。

Hydra 使用的键 —— 由 24 段标签组成,标签之间用冒号分隔。段标签被命名为:前缀(Prefix)、服务名称(Service name)、实例 ID(Instance ID)和类型(type)。


微信图片_20220610212526.png


前缀段允许过滤 Hydra key 和非 Hydra key。因此,如果你大量使用 Redis,那么能够过滤特定的 key 是至关重要的。


服务名称段帮助过滤特定服务类型的 key。例如授权(authorization)、用户(user)或图像处理(image processing)服务类型。

实例ID(Instance ID)段允许过滤唯一服务实例的 key。运行微服务时,通常需要运行一个服务类型的多个实例。每个服务实例都分配有唯一的 ID,并且能够区分它们是有用的。


最后,还有“类型(Type)”部分,用于对 key 的用途进行分类。并非每个 key 中都存在所有段。例如,某些 key 中不需要服务名称(Service name)和实例ID(instance ID)。


这是用户服务(user service) key 的示例。我们看到前缀 hydra:service 后跟服务名称,在本例中为 “user-svcs”。接下来,我们看到唯一的实例ID(unique instance ID)。最后,我们看到此 key 的类型为 presence(presence)。因此,我们说 presence 信息存储(presence information)在此 key 地址中。


微信图片_20220610212541.png

在前面的描述中,一个令人困惑的地方是,key 由名称组成,名称中有24个段标签,用冒号分隔。然而,在这里我们看到 hydra:service 也用冒号分隔。当时的想法是,可能还有另一种 hydra:other 类型,service 只是其中之一。关于消息传递还有另一个不一致的地方,稍后我们将对此进行讨论。

我们可以输入 redis-cli 和输入 Redis 命令来查看各种键。在接下来的演示中我们会看到一些例子。


微信图片_20220610212554.png

image.gif

一个关于我们将使用的 redis-cli 示例的快速说明:你将看到 keys 命令的使用 —— 这是为了方便 —— Hydra 内部使用 Redis scan 命令。


所以重述一下 —— Hydra 使用的 key 是按段组织的,这使它们更容易查询。此外,一致的组织使它们更容易扩展和维护。随着我们继续,我们将看到 key 在每个微服务特性的组织中所扮演的角色。让我们从检查 presence(examining presence)开始。


Presence(呈现 type)



在微服务领域中,发现服务、了解服务是否正常以及是否可以路由到该服务的能力至关重要。这些特性依赖于知道某个特定的服务实例确实存在并可供使用。对于服务发现(service discovery)、路由(routing)和负载平衡(load balancing)等特性,这也是必需的。


每隔一秒钟,Hydra 就会更新它的服务 key 的生存时间(TTL)。在三秒钟的时间内这样做失败将导致 key 过期,主机应用程序被视为不可用。


微信图片_20220610212624.png

image.gif

在这里我们可以看到使用的 Redis 命令是 “get”“setex”,它们设置了一个 key 和一个到期时间。


我们可以使用带有模式匹配项的 “keys” 命令来查询 presence key。注意,存在三个 key。这告诉我们存在 “ asset-svcs” 运行的三个实例。


如果我们尝试检索其中一个 key 的内容,我们会看到它包含实例ID(instance ID)。

并对键使用 TTL 命令可以向我们显示,它还有 2 秒钟的剩余时间。


微信图片_20220610212646.png

image.gif

所以回顾一下。可以使用自动过期的 key 来管理微服务的存在。Hydra 代表主机服务自动更新密钥。这意味着这不是开发人员做的事情。在3秒内更新 key 失败将导致服务被视为不可用。这可能意味着服务不健康。

这将我们带入下一个主题…


Health(健康 type)



能够监视微服务的运行状况是另一个重要功能。Hydra 每 5 秒钟收集并写入一个健康信息快照。


您可以检查快照以快速查看单个服务实例的运行状况。并且,快照可以由监控工具(例如 HydraRouter 仪表板)使用。


这就是健康 key 的样子。请注意,唯一的新位是标识 key 为关于 health“type” 段。


微信图片_20220610212704.png

image.gif

当我们查看密钥的内容时,我们看到它包含一个字符串化的 JSON 对象。在这种情况下,它用于 “project-svcs”


微信图片_20220610212717.png

image.gif

JSON 解串可以更容易地查看存储的内容。它包含了很多有用的信息。


微信图片_20220610212741.png

image.gif

因此,可以按服务实例存储运行状况(health)信息。使用包含字符串化的JSON文本的字符串 key 进行管理。而且这些信息可以通过监视应用程序来使用。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
NoSQL 安全 测试技术
Redis游戏积分排行榜项目中通义灵码的应用实战
Redis游戏积分排行榜项目中通义灵码的应用实战
65 4
|
1月前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
104 5
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
70 8
|
2月前
|
监控 NoSQL 网络协议
【Azure Redis】部署在AKS中的应用,连接Redis高频率出现timeout问题
查看Redis状态,没有任何异常,服务没有更新,Service Load, CPU, Memory, Connect等指标均正常。在排除Redis端问题后,转向了AKS中。 开始调查AKS的网络状态。最终发现每次Redis客户端出现超时问题时,几乎都对应了AKS NAT Gateway的更新事件,而Redis服务端没有任何异常。因此,超时问题很可能是由于NAT Gateway更新事件导致TCP连接被重置。
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
46 5
|
3月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
5月前
|
NoSQL Redis
基于Redis的高可用分布式锁——RedLock
这篇文章介绍了基于Redis的高可用分布式锁RedLock的概念、工作流程、获取和释放锁的方法,以及RedLock相比单机锁在高可用性上的优势,同时指出了其在某些特殊场景下的不足,并提到了ZooKeeper作为另一种实现分布式锁的方案。
141 2
基于Redis的高可用分布式锁——RedLock
|
5月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
2月前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
61 16
|
3月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
78 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁