Dawn's Blogs

分享技术 记录成长

0%

Triple 协议简介

Triple 协议是 Dubbo3 设计的基于 HTTP 的 RPC 通信协议规范,它完全兼容 gRPC 协议,支持 Unary、Streaming 流式等通信模型,可同时运行在 HTTP/1 和 HTTP/2 之上。

Triple 包含两个部分:

  1. 构建一套自定义的精简 HTTP RPC 子协议,支持 HTTP/1 和 HTTP/2 为传输协议,仅支持 Unary 通信

  2. 构建基于 gRPC 的扩展子协议(与 gRPC 兼容),仅支持 HTTP/2 实现,支持 Unary 和 Streaming 通信

目标

Triple 协议完全兼容 gRPC 协议,为什么 Dubbo 还要通过 Triple 重新实现一遍?目标有如下两点:

  • 在协议设计上,Triple 是一个基于 HTTP 传输层协议的 RPC 协议,它同时可运行在 HTTP/1、HTTP/2 之上
  • 完全兼容基于 HTTP/2 的 gRPC 协议,因此 Dubbo Triple 协议实现可以 100% 与 gRPC 体系互调互通。
  • 仅依赖标准的、被广泛使用的 HTTP 特性,以便在实现层面可以直接依赖官方的标准 HTTP 网络库

协议规范

Triple 包含两个部分:

  1. 构建一套自定义的精简 HTTP RPC 子协议,支持 HTTP/1 和 HTTP/2 为传输协议,仅支持 Unary 通信

  2. 构建基于 gRPC 的扩展子协议(与 gRPC 兼容),仅支持 HTTP/2 实现,支持 Unary 和 Streaming 通信

HTTP RPC 协议

Triple HTTP RPC 同时支持 HTTP/1、HTTP/2 作为底层传输层协议,在实现上对应支持的 content-type 类型为 application/json、application/proto。

阅读全文 »

本节介绍一些在 Redis 中除了五大基本数据类型之外的数据类型,包括用法和使用场景。

BitMap

BitMap 位图,用于存储一串连续的二进制数组,可以通过 offset 定位元素,特别适合一些数据量大且使用二值统计的场景。

位图之间可以做逻辑运算,如与、或、非、异或。

内部实现

BitMap 底层使用 string 类型作为实现,Redis 的字符串类型是二进制安全的,所以可以作为位图的底层数据结构。

HyperLogLog

Redis HyperLogLog 是 Redis 2.8.9 版本新增的数据类型,用于统计一个集合中不重复的元素个数(不精确的去重计数)。但要注意,HyperLogLog 是统计规则是基于概率完成的,不是非常准确,**标准误算率是 0.81%**。

HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的内存空间总是固定的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数,和元素越多就越耗费内存的 Set 和 Hash 类型相比,HyperLogLog 就非常节省空间。

GEO

Redis GEO 是 Redis 3.2 版本新增的数据类型,主要用于存储地理位置信息,并对存储的信息进行操作。

内部实现

GEO 本身并没有设计新的底层数据结构,而是直接使用了 Sorted Set 集合类型

GEO 类型使用 GeoHash 编码方法实现了经纬度到 Sorted Set 中元素权重分数的转换。这样一来,就可以把经纬度保存到 Sorted Set 中,利用 Sorted Set 提供的按权重进行有序范围查找的特性,实现 LBS 服务中频繁使用的搜索附近的需求。

Stream

Redis Stream 是 Redis 5.0 版本新增加的数据类型,Redis 专门为消息队列设计的数据类型。有以下两个特性:

  • 自动生成全局唯一消息 ID
  • 支持以消费组形式消费数据。

过期删除

Redis 可以设置 key 的过期时间,对于过期的 key,Redis 需要进行清理。

过期时间

当对一个 key 设置了过期时间,Redis 会把该 key 带上过期时间存储到一个过期字典(哈希表)中,过期字典保存了所有 key 的过期时间。所以在访问一个 key 时,可以在常数级时间复杂度查找 key 是否过期:

  • 不在过期字典中,说明没有设置过期时间。
  • 在过期字典中,获取过期时间,与系统当前时间进行比对是否过期。

删除策略

Redis 采用惰性删除+定期删除两种删除策略配合使用,以求在合理使用 CPU 时间和避免内存浪费之间取得平衡。

惰性删除

惰性删除中,不主动删除过期 key,只有当查询到过期 key 时才进行删除操作,删除可以选择异步删除或者同步删除。

惰性删除节省 CPU 时间,但是浪费内存

定期删除

定期删除策略的做法是,每隔一段时间随机从数据库中取出一定数量的 key 进行检查,并删除其中的过期key。

定期删除相对于惰性删除更需要 CPU 资源,但是更加节约内存

Redis 实现的定期删除需要解决两个问题:

  1. 定期检查间隔时间:默认每 10 秒钟检查一次,这是可以配置的。
  2. 随机抽查的数量:数量是写死在代码中的,数值是 20

Redis 的定期删除的流程

  1. 从过期字典中随机抽取 20 个 key;
  2. 检查这 20 个 key 是否过期,并删除已过期的 key;
  3. 如果本轮检查的已过期 key 的数量,比例大于 25%(5 个),则继续重复步骤 1;否则停止继续删除过期 key,然后等待下一轮再检查。

Redis 为了保证定期删除不会出现循环过度,导致线程卡死现象,为此增加了定期删除循环流程的时间上限,默认不会超过 25ms。

阅读全文 »