详解redis在微服务领域的贡献

前言

说到redis,可能大家的脑海中蹦出的关键词是:NoSQL、KV、高性能、缓存等。但今天的文章从另一个角度——微服务来展开。

这篇文章的起因也是源自一次面试经历,在面试一位来自陌陌的候选人(就是那个交友的陌陌)时,他提到一点让我觉得很有意思,他说redis在陌陌被使用的非常广泛,除了常规的缓存外,某些场景下也当NoSQL数据库来使用,还用redis作为微服务的注册中心,甚至连RPC的调用协议都用了redis协议。

注册中心

最早了解到redis可以作为注册中心是从dubbo的源码中看到,但一直也没有过多的了解,因为从没听说哪家公司使用redis来做服务发现。

在dubbo中使用redis来做服务发现还是挺简单的,引入jedis依赖,将注册中心地址改为redis地址即可:

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
</dependency>

dubbo.registry.address=redis://127.0.0.1:6379

注册上来的数据是这样,类型是hash

/dubbo/${service}/${category}

/dubbo/com.newboo.sample.api.DemoService/consumers
/dubbo/com.newboo.sample.api.DemoService/providers

hash数据结构下保存的key是注册上来的url,value是过期时间

127.0.0.1:6379> hgetall /dubbo/com.newboo.sample.api.DemoService/providers
1) "dubbo://172.23.233.142:20881/com.newboo.sample.api.DemoService?anyhost=true&application=boot-samples-dubbo&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.newboo.sample.api.DemoService&metadata-type=remote&methods=sayHello&pid=19807&release=2.7.8&side=provider&timestamp=1621857955355"
2) "1621858734778"

从理论上来说,注册中心只要符合数据存储、监听推送变更、心跳检测这几个基本的功能即可。

以dubbo为例看下redis是如何利用自身特性来完成注册中心的功能( 以dubbo 2.7.8版本为例):

服务注册

  • provider在服务注册时,将服务提供方的url写入/dubbo/${service}/providers下,数据类型为hash,key为提供方url,value为key的过期时间,默认为60s,可配置
  • 写入完成后以/dubbo/${service}/providers为key调用publish命令发布一个register事件provider在初始化时起一个单独的线程每隔1/2过期时间(默认30s)时对
  • provider进行重新重新注册并发布register事件

服务发现

  • 获取匹配/dubbo/${service}/*的key(此处用到了keys命令),拿到的有这几种:/dubbo/${service}/providers/dubbo/${service}/routers/dubbo/${service}/configuators
  • /dubbo/${service}/*拿到的key进行hgetall,拿到真实的provider列表以及配置等数据,进行组装、匹配
  • 同时对每个subscribe的服务单独开一个线程,对/dubbo/${service}执行psubscribe命令阻塞等待有事件发生

从源码和测试来看,dubbo的redis注册中心不能直接用于生产环境,原因有如下两点:

  • 使用了keys命令,会阻塞单线程的redis,keys执行期间,其他命令都得排队
  • 没有心跳检测这个功能,我测试了provider被kill -9杀死后,consumer是无法感知的。但从实现上来看是想通过存储的过期时间来判断服务是否可用,即需要对比url对应的value与当前的时间,如果过期应被剔除,但这部分貌似没有实现完整

虽然dubbo的redis注册中心生产不可用,但这并不影响他可以构建一个生产可用的注册中心,陌陌就是个很好的例子。

RPC调用协议

redis协议作为RPC调用协议也是陌陌同学告诉我的,当时我问了他两个问题:

  • 为什么选择redis协议作为RPC调用协议
  • redis协议如何透传类似header的隐式参数

第一个问题的答案也比较出乎意料,他说是为了跨语言调用,当时觉得只有http、gRPC等协议做到了跨语言,redis协议跨语言也是第一次听说。但仔细一想,确实没毛病,现在哪个后端语言没有实现redis的客户端呢?

之所以redis协议能够做到跨语言,这也全仰仗它的设计非常简洁,易于实现,详细协议内容可以参考这个链接:

http://redisdoc.com/topic/protocol.html

我就举一个例子来证明redis协议简洁到了什么程度,这是我很久之前就关注的一个项目

https://github.com/jdp/redisent

它是一个php实现的redis客户端,只有一个php文件,共196行,这196行包含了注释,变量定义,链接建立等,真正解析协议的代码非常少,请求的编码和发送只用了17行代码,解析返回的代码只有58行!正如项目的介绍那样:simple, no-nonsense

第二个问题回答的和我的预期一致,从redis协议的层面暂时无法支持类似header的隐式参数,但陌陌的RPC框架是自研的,所以他们在框架层解决了这个问题,序列化他们选择了json,如果要透传header参数,框架将参数组装到传输体中去。

遗憾的是dubbo中的redis协议实现并不完整,无法暴露redis协议,只能调用,所以测试也只能测试client连接到redis服务器进行get、set调用,意义不大。

总结

redis目前是个用途非常广泛的存储组件,虽然在微服务领域它不是主流,但这也给我们提供了一种思路,至少这条路是可以走通的。

到此这篇关于redis在微服务领域的贡献的文章就介绍到这了,更多相关redis微服务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringCloud实现Redis在各个微服务的Session共享问题

    在微服务中,需要我们在各个微服务中共享Session,使用Redis来共享Session是一个很好的解决方法,Redis是运行在内存中,查取速度很快. 1.pom文件中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> <depe

  • springcloud微服务基于redis集群的单点登录实现解析

    简介 本文介绍微服务架构中如何实现单点登录功能 创建三个服务: 操作redis集群的服务,用于多个服务之间共享数据 统一认证中心服务,用于整个系统的统一登录认证 服务消费者,用于测试单点登录 大体思路:每个服务都设置一个拦截器检查cookie中是否有token,若有token,则放行,若没有token,重定向到统一认证中心服务进行登录,登录成功后返回到被拦截的服务. 搭建redis集群服务 搭建redis集群参考文档 搭建统一认证中心 主函数添加注解 /** * 单点登录既要注册到服务注册中心,

  • 浅谈Redis在微服务架构中的几种应用场景

    本文介绍在SpringCloud中使用Redis作为Pub/Sub异步通信.缓存或主数据库和配置服务器的三种场景应用. Redis可以广泛用于微服务架构.它可能是您应用程序以多种不同方式利用的少数流行软件解决方案之一.根据要求,它可以充当主数据库,缓存或消息代理.虽然它也是一个键/值存储,但我们可以将它用作微服务体系结构中的配置服务器或发现服务器.虽然它通常被定义为内存中的数据结构,但我们也可以在持久模式下运行它. 这里我将向您展示一些使用Redis与Spring Boot和Spring Clo

  • 详解redis在微服务领域的贡献

    前言 说到redis,可能大家的脑海中蹦出的关键词是:NoSQL.KV.高性能.缓存等.但今天的文章从另一个角度--微服务来展开. 这篇文章的起因也是源自一次面试经历,在面试一位来自陌陌的候选人(就是那个交友的陌陌)时,他提到一点让我觉得很有意思,他说redis在陌陌被使用的非常广泛,除了常规的缓存外,某些场景下也当NoSQL数据库来使用,还用redis作为微服务的注册中心,甚至连RPC的调用协议都用了redis协议. 注册中心 最早了解到redis可以作为注册中心是从dubbo的源码中看到,但

  • 详解Go语言微服务开发框架之Go chassis

    引言 https://github.com/go-chassis/go-chassis是一个微服务开发框架,而微服务开发框架带来的其中一个课题就是:当单体应用向微服务转型后,有大量的配置需要管理,而你并不希望登录到远端机器去更改配置,并重启应用,尤其是现在已经是容器的时代了,也不希望因为一个配置的变更,而发布一个新的软件包.那么分布式系统中每个进程的动态配置管理及运行时热加载就成为了一个亟待解决的问题.https://github.com/go-chassis/go-archaius为gocha

  • 详解Spring Cloud微服务架构下的WebSocket解决方案

    WebSocket在现代浏览器中的应用已经算是比较普遍了,在某些业务场景下,要求必须能够在服务器端推送消息至客户端.在没有WebSocket的年代,我们使用过dwr,在那个时候dwr真实一个非常棒的方案.但是在WebSocket兴起之后,我们更愿意使用标准实现来解决问题. 首先交代一下,本篇文章不讲解WebSocket的配置,主要讲的是针对在微服务架构集群模式下解决方案的选择. 微服务架构大家应该都不陌生了,在微服务架构下,服务是分布式的,而且为了保证业务的可用性,每个服务都是以集群的形式存在.

  • 详解Spring Boot微服务如何集成fescar解决分布式事务问题

    什么是fescar? 关于fescar的详细介绍,请参阅fescar wiki. 传统的2PC提交协议,会持有一个全局性的锁,所有局部事务预提交成功后一起提交,或有一个局部事务预提交失败后一起回滚,最后释放全局锁.锁持有的时间较长,会对并发造成较大的影响,死锁的风险也较高. fescar的创新之处在于,每个局部事务执行完立即提交,释放本地锁:它会去解析你代码中的sql,从数据库中获得事务提交前的事务资源即数据,存放到undo_log中,全局事务协调器在回滚的时候直接使用undo_log中的数据覆

  • 详解Redis分布式锁的原理与实现

    目录 前言 使用场景 为什么要使用分布式锁 如何使用分布式锁 流程图 分布式锁的状态 分布式锁的特点 分布式锁的实现方式(以redis分布式锁实现为例) 总结 前言 在单体应用中,如果我们对共享数据不进行加锁操作,会出现数据一致性问题,我们的解决办法通常是加锁.在分布式架构中,我们同样会遇到数据共享操作问题,此时,我们就需要分布式锁来解决问题,下面我们一起聊聊使用redis来实现分布式锁. 使用场景 库存超卖 比如 5个笔记本 A 看 准备买3个 B 买2个 C 4个 一下单 3+2+4 =9

  • 详解基于Spring Data的领域事件发布

    领域事件发布是一个领域对象为了让其它对象知道自己已经处理完成某个操作时发出的一个通知,事件发布力求从代码层面让自身对象与外部对象解耦,并减少技术代码入侵. 一. 手动发布事件 // 实体定义 @Entity public class Department implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer departmentId; @Enumerate

  • 详解redis缓存与数据库一致性问题解决

    数据库与缓存读写模式策略 写完数据库后是否需要马上更新缓存还是直接删除缓存? (1).如果写数据库的值与更新到缓存值是一样的,不需要经过任何的计算,可以马上更新缓存,但是如果对于那种写数据频繁而读数据少的场景并不合适这种解决方案,因为也许还没有查询就被删除或修改了,这样会浪费时间和资源 (2).如果写数据库的值与更新缓存的值不一致,写入缓存中的数据需要经过几个表的关联计算后得到的结果插入缓存中,那就没有必要马上更新缓存,只有删除缓存即可,等到查询的时候在去把计算后得到的结果插入到缓存中即可. 所

  • 详解Redis主从复制实践

    复制简介 Redis 作为一门非关系型数据库,其复制功能和关系型数据库(MySQL)来说,功能其实都是差不多,无外乎就是实现的原理不同.Redis 的复制功能也是相对于其他的内存性数据库(memcached)所具备特有的功能. Redis 复制功能主要的作用,是集群.分片功能实现的基础:同时也是 Redis 实现高可用的一种策略,例如解决单机并发问题.数据安全性等等问题. 服务介绍 在本文环境演示中,有一台主机,启动了两个 Redis 示例. 实现方式 Redis 复制实现方式分为下面三种方式:

  • 详解Redis单线程的正确理解

    很多同学对Redis的单线程和I/O多路复用技术并不是很了解,所以我用简单易懂的语言让大家了解下Redis单线程和I/O多路复用技术的原理,对学好和运用好Redis打下基础. 一.Redis的单线程理解 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程.其中执行命令阶段,由于Redis是单线程来处理命令的,所有到达服务端的命令都不会立刻执行,所有的命令都会进入一个队列中,然后逐个执行,并且多个客户端发送的命令的执行顺序是不确定的,但是可以确定的是不会有两条命令被同时

  • 详解Redis集群搭建的三种方式

    一.单节点实例 单节点实例还是比较简单的,平时做个测试,写个小程序如果需要用到缓存的话,启动一个 Redis 还是很轻松的,做为一个 key/value 数据库也是可以胜任的 二.主从模式(master/slaver) redis 主从模式配置 主从模式: redis 的主从模式,使用异步复制,slave 节点异步从 master 节点复制数据,master 节点提供读写服务,slave 节点只提供读服务(这个是默认配置,可以通过修改配置文件 slave-read-only 控制).master

随机推荐