redis在微服务领域的贡献

捉虫大师 等级 585 2 0

本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。

前言

说到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命令阻塞等待有事件发生

redis在微服务领域的贡献

从源码和测试来看,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参数,框架将参数组装到传输体中去。

redis在微服务领域的贡献

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

总结

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


搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。

redis在微服务领域的贡献

收藏
评论区

相关推荐

我是Redis,MySQL大哥被我害惨了!
本文转自 轩辕之风 ,链接如下 https://mp.weixin.qq.com/s?__bizMzIyNjMxOTY0NA&mid2247486528&idx1&sn3f7b09eb21969fdb16f5b0805ff69fed&scene21wechat_redirect 我是Redis 你好,我是Redis,一个叫Antirez的
开发机连接Docker中的redis容器小案例
在笔者日常开发中,都是把redis装在windows系统中。虽然可以通过RedisDesktopManager等客户端工具连接操作redis,但是还是
Go-连接Redis-学习go-redis包
Redis介绍 Redis是一个开源的内存数据结构存储,常用作数据库、缓存和消息代理。目前它支持的数据结构有诸如string、hash、list、set、zset、bitmap、hyperloglog、geospatial index和stream。Redis内置了复制、Lua脚本、LRU清除、事务和不同级别的磁盘持久性,并通过Redis Sentinel
Redis实现分布式锁
一、redis分布式锁的简易实现 用redis实现分布式锁是一个老生常谈的问题了。因为redis单条命令执行的原子性和高性能,当多个客户端执行setnx(相同key)时,最多只有一个获得成功。因此在对可用性要求不是特别高的场景下,redis分布式锁方案不失为一个性价比高的实现。 1. 多个客户端执行setnx lock
php操作redis哨兵模式,主从切换后自动获取master
本文将介绍如何使用PHP来连接redis哨兵模式。哨兵模式:大概的原理就是监听redis主库心跳包,如果心跳断开,则枚举一个从库推举成为新的主库,防止redis宕机不能使用。为了增强redis的性能,防止其挂掉,引用redis哨兵监控redis集群是个不错的选择。下面三步简单记录php连接redis哨兵。 第一步、获取哨兵模式连接redis句柄对象/
为什么单线程的Redis能支持高并发?
一、Redis为什么是单线程注意:redis 单线程指的是网络请求模块使用了一个线程,即一个线程处理所有网络请求,其他模块仍用了多个线程。因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽,既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。关于redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万
Windows 下编译 PHP Redis 扩展并支持 Igbinary 序列器
这是 PHP 下扩展的下载地址:当然,通过这个地址我们能够轻松的获取到 Redis 和 Igbinary 扩展并启用,但是,我们可以在页面上打开 phpinfo() 瞧瞧上方截图为重编译的 Redis 扩展,默认情况下通过上方网站下载的 Redis 扩展在 Available serializers 中只有 php 一项。目前仅编译了
聊聊dubbo协议
协议协议通俗易懂地解释就是通信双方需要遵循的约定。我们了解的常见的网络传输协议有tcp、udp、http等。再到我们常用的基础组件,一般来说client端与server端也有相应的协议,如redis、mysql、zookeeper等都是各自约定的私有协议,同样今天标题中的dubbo协议也是一种私有协议,他们都是应用层协议,基于tcp或udp设计。
Redis 未授权访问漏洞复现与利用
一、漏洞简介以及危害: 1.什么是redis未授权访问漏洞: Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上
Redis集群详解
Redis集群详解Redis有三种集群模式,分别是: 主从模式 Sentinel模式 Cluster模式 三种集群模式各有特点,关于Redis介绍可以参考这里:Redis官网:https://redis.io/ ,最新版本5.0.4 主从模式 主从模式介绍主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(sl
redis在微服务领域的贡献
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 前言说到redis,可能大家的脑海中蹦出的关键词是:NoSQL、KV、高性能、缓存等。但今天的文章从另一个角度——微服务来展开。这篇文章的起因也是源自一次面试经历,在面试一位来自陌陌的候选人(就是那个交友的陌陌)时,他提到一点让我觉得很有意思,他说red
springBoot集成redis
Redis作为一个Java后端面试中的一个常问考点,并且在项目中越来越常用,所以自己动手搭建了一个基于springboot集成redis做为数据缓存的demo(springboot集成mybatis、redis,并具有增删改查询接口)。关注微信公众号【菜鸟阿都】并回复:redis,可获得源码。后面也会继续深入研究redis相关知识,期待与大家一起学习交流。r
给dubbo贡献源码,做梦都在修bug
本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。 一在之前的文章《redis在微服务领域的贡献》中,从一次面试经历中了解了redis可以在微服务中玩的这么溜,同时也从源码角度分析了dubbo的redis注册中心。最后得出了dubbo的redis注册中心不能用于生产的结论,其中原因有如下两点: 使用了ke
作为一个码农终于把这些笔记看懂了,牛皮轰轰
Spring面试高频问题 SpringMVC面试高频问题 MyBatis面试高频问题 SpringBoot面试高频题 SpringCloud面试高频问题 Redis高级面试题 Dubbo高频常问面试问题 Java虚拟机(JVM) MySQL数据库高频面试问题 Java高频面试专题合集解析:当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,在这也是
最新Java大厂高频面试题,看这一篇就够了!
常见resdis面试真题40道(含解析)1. 什么是 Redis?2. Redis 的数据类型?3. 使用 Redis 有哪些好处?4. Redis 相比 Memcached 有哪些优势?5. Memcache 与 Redis 的区别都有哪些?6. Redis 是单进程单线程的?7. 一个字符串类型的值能存储最大容量是多少?8. Redis