小红书KV存储架构:万亿级数据与跨云多活不在话下( 二 )


2)典型场景风控服务 。 实时查询对P999要求极高 , 千万QPS下HBase已经不能满足性能需求 , 时延抖动比较大 。 画像存储服务 。 数据的维度多 , 字段读取的业务方多 , 对时延要求敏感 。
三、架构设计
RedKV整体架构分3层 , 接入层兼容Redis协议 , 支持各种语言的社区版SDK和公司定制的中间件版;接入代理层支持千万QPS的读写能力 , 无状态扩展;存储层提供高可靠读写服务 。 RedKV1.0架构如下图1 , 下面我们详细地展开3层组件的介绍 。
小红书KV存储架构:万亿级数据与跨云多活不在话下
文章图片
图1RedKV1.0整体架构
1、Client接入层
RedKV集群部署完成后 , 通过公司内部提供的ServiceMesh组件做服务发现 , 对Client提供服务 。
2、Proxy
Proxy层由一个无状态CorvusPlus进程组成 。 它兼容老的RedisClient , 扩缩容、升级对无Client和后端集群无感 , 支持多线程、IO多路复用和端口复用特性 。 对比开源版本 , CorvusPlus增强了自我防护和可观测特性 , 实现了可在线配置的功能特性:Proxy限流数据在线压缩线程模型优化backup-read优化长尾大key检测
1)Proxy限流
小红书当前的业务模型比较多 , 客户端行为无法预期 , 可能出现的发版错误、系统问题及网络抖动引发客户端重试 , 突发的qps会影响服务稳定性 。 在高QPS压力下 , Proxy处理客户端读写超时 , 大量重试会导致雪崩 , 业务高峰期单个Proxy带宽可能超过机器的出入带宽限制 , 而存储集群只能保证在有限的资源内提供稳定可靠的服务 。 针对这类场景 , 我们需要保证流量过载时 , Proxy和RedKV服务不被打崩 , 能保障高可用 。
基于以上问题和目标 , 对比原生的RedisCluster模式 , RedKV基于令牌桶的流控算法支持了对连接数、带宽和QPS多维度限流 。 在高QPS下 , 我们的Proxy限流防止了雪崩 , 如图2;在大带宽场景下 , 我们优化了时延 , 如图3 。
小红书KV存储架构:万亿级数据与跨云多活不在话下
文章图片
图2雪崩场景下的限流
小红书KV存储架构:万亿级数据与跨云多活不在话下
文章图片
图3大带宽场景下的限流
2)数据在线压缩
Proxy层本身只做路由转发 , 对CPU的消耗非常低 。 在大带宽的场景下 , 我们可以充分利用Proxy的CPU资源优化带宽和毛刺 。 在解析Redis协议时 , 使用LZ4算法对写入数据进行在线压缩 , 读取时在线解压 。 在推荐缓存的使用场景中网络带宽和存储空间压缩40%以上(如图4) , 总体时延并没有明显的下降 。 因为网络带宽和写入读取数据的减少 , 时延毛刺也变小了 。
小红书KV存储架构:万亿级数据与跨云多活不在话下
文章图片
图4Proxy开压缩后的带宽优化
3)线程模型的优化
Proxy采用IO多路复用技术 , 每个连接维护一个请求处理队列和响应队列 , 保序的返回给客户端 。 Proxy在收到RedKVServer的回应之后 , 如果没有收到所有发送的cmd的返回 , 则会一直等待所有cmd的返回后再发送给client , 对于读的场景这种模式非常不友好 。 经过改造 , 如果某个cmd之前的cmd都已经正常响应 , 则可以马上响应给client , 不需要再等后面的所有cmd请求完成 。
4)backup-read优化长尾
在公网环境下 , 一个CVM虚拟机和其他多个虚拟机共享一台物理机 。 当某个客户的CVM占用大量资源时 , 很容易影响到其他CVM的P99时延(由于QOS和隔离性做的不够好 , SMI中断和内存CE) 。 在网络吞吐较大的情况下 , 某云的DPDK容易被打爆 , 出现母机OOB 。 而在RedKV的内部实现中 , 如果Server请求比较大 , 某些key的查询时延比较高的时候 , 容易产生排队堆积 , 或者compaction之后的blockcache失效 , 很容易造成IO长尾 。 因此 , RedKV的P99读时延的毛刺很难避免 , 但毛刺是偶尔发生的 , 当前我们的主从节点一定是离散部署在不同的母机上 , 同时出现P99毛刺的可能很小 。 基于这点 , 我们在Proxy层做了backupread功能 , 优化了RedKV的p99时延问题 。