RedKV是小红书自研的一款依据NVMeSSD的分布式NoSQL KV存储体系,支撑无中心和有中心的两种管控架构,旨在处理公司内实时落盘的KV存储需求。RedKV1.0依据Gossip协议做节点办理,在全公司现已大规模运用,实时QPS挨近1亿/秒,存储量在数PB等级。RedKV2.0选用中心Shard办理架构,支撑全球多云多副本在线弹性弹性,异地容灾和服务秒级切换。

经过分层优化,RedKV比照开源同类产品,聚合写吞吐才能均匀提高3倍,读1.5倍;对标HBase,本钱优化近40%。RedKV部分兼容Redis协议,string/hash/zset等首要数据类型很好的的支撑了公司的绝大部分在线存储事务,优化了前期Redis集群布置产生的本钱问题以及HBase带来的功用及安稳性问题。RedKV和Hive数仓的数据互通才能为离线数据事务供给了一种处理计划。

1. 小红书存储开展历史

小红书是年轻人的日子记录、同享渠道,用户能够经过短视频、图文等形式记录日子点滴,同享日子办法。在当时的事务模型下,用户的画像数据和笔记数据用来做风险控制和内容引荐。存储数据具有对象-特色的特征、维度多,画像数据量现已到达数十TB, 在线事务对画像和笔记数据的拜访P99 时延要求十分高。

2020年之前公司挑选的NoSQL存储产品首要有:Redis、HBase,跟着公司DAU的高速增加,前期的存储计划遇到如下应战:

●Redis集群首要适用于缓存场景,开启AOF数据实时落盘对功用有比较大的影响,一起每个节点需求额外挂载云盘用于存储AOF。在集群节点和存储容量受限的情况下,单节点的数据量设置过大会导致毛病后节点数据的failover时刻太长,单节点数据量设置小会导致gossip协议在安稳性高要求下节点个数受限,一起考虑突发流量的压力,Redis集群在布置上需求做一些空间预留,带来本钱高的问题。

●HBase作为一款生态完善的NoSQL存储体系,在高QPS下也产生了许多的功用和安稳性问题,如:Zookeeper压力大时安稳性难以确保(节点探活,服务注册等都依靠 Zookeeper);HBase的数据文件和WAL日志文件直接写HDFS,节点毛病后,重放HDFS上的WAL速度慢;Java GC会导致Zookeeper误杀RegionServer,一起产生毛刺;Major Compaction 会导致I/O飙升,产生长尾效应;受限HDFS的复杂性,黑盒运维对工程师来说比较困难;在小红书的事务实战中,百万QPS下HBase延时不太抱负,中心数据用大内存机型兜住,也引发本钱高的问题。

跟着事务的持续增加,开源存储产品现已不能很好的满意公司的事务开展需求, 公司需求一款安稳的高功用KV体系支撑内部事务,一方面要满意事务对功用和功用的需求,另一方面要优化本钱。

2.小红书事务需求

2.1.高QPS和低延时读取特性

特征数据存储场景:

●写入带宽到达数十GB/s,要求实时写入功用和读取功用都很高。

图片缓存的场景:

●数据量很大,要求读取时延低。能够承受毛病场景下少数数据丢掉。

高功用(P99 < 10ms):

●模型数据存储服务。记录曩昔一段时刻用户练习模型数据,对P99时延要求十分高,数据量在几十TB。

●去重存储服务。数据量在几十TB,P99<10ms, P999<20ms。

●风控数据存储服务。QPS现在到达千万等级,P999 < 30ms。

2.2.低本钱的缓存特性

对标Redis:

●兼容Redis协议,功用比Redis慢一些,但资源本钱下降50%+。

典型场景:

●广告的关键词存储和反作弊事务,处理大数据量、低QPS的存储模型。

2.3.NoSQL存储特性

对标HBase:

●支撑数据多版别,列存行取等特性,比HBase本钱削减30%+,P99时延提高6倍。

●支撑KKV等级的TTL。

●强共同:现在RedKV1.0选用的主从双副本,数据写入成功,能够经过装备同步形式来确保2副本写成功,读主写主确保强共同。关于写功用要求高的场景,能够翻开异步写,写主成功则回来,依靠增量同步从节点数据。

典型场景:

●风控服务。实时查询对P999要求极高,千万QPS下HBase现已不能满意功用需求,时延颤动比较大。

●画像存储服务。数据的维度多,字段读取的事务方多,对时延要求敏感。

3.架构规划

RedKV全体架构分3层,接入层兼容Redis协议,支撑各种语言的社区版SDK和公司定制的中间件版;接入署理层支撑千万QPS的读写才能,无状况扩展;存储层供给高牢靠读写服务。RedKV1.0架构如下图1,下面咱们详细的展开3层组件的介绍。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图1.RedKV1.0全体架构

3.1.Client接入层

RedKV集群布置完结后,经过公司内部供给的Service Mesh组件做服务发现,对Client供给服务。

3.2.Proxy

Proxy层由一个无状况CorvusPlus进程组成。它兼容老的Redis Client,扩缩容、升级对无Client和后端集群无感,支撑多线程、IO多路复用和端口复用特性。比照开源版别,CorvusPlus增强了自我防护和可观测特性,完成了可在线装备的功用特性:

  • Proxy限流
  • 数据在线紧缩
  • 线程模型优化
  • backup-read优化长尾
  • 大key检测
3.2.1.Proxy限流

小红书当时的事务模型比较多,客户端行为无法预期,或许呈现的发版过错、体系问题及网络颤动引发客户端重试,突发的qps会影响服务安稳性。在高QPS压力下,Proxy处理客户端读写超时,许多重试会导致雪崩,事务高峰期单个 Proxy 带宽或许超越机器的收支带宽约束,而存储集群只能确保在有限的资源内供给安稳牢靠的服务。针对这类场景,咱们需求确保流量过载时,Proxy和RedKV服务不被打崩,能确保高可用。

依据以上问题和目标,比照原生的Redis Cluster形式,RedKV依据令牌桶的流控算法支撑了对连接数、带宽和QPS多维度限流。在高QPS下,咱们的Proxy限流防止了雪崩,如图2;在大带宽场景下,咱们优化了时延,如图3。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图2. 雪崩场景下的限流

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图3. 大带宽场景下的限流

3.2.2.数据在线紧缩

Proxy层自身只做路由转发,对CPU的耗费十分低。在大带宽的场景下,咱们能够充分利用Proxy的CPU资源优化带宽和毛刺。在解析Redis协议时,运用LZ4算法对写入数据进行在线紧缩,读取时在线解压。在引荐缓存的运用场景中网络带宽和存储空间紧缩40%以上(如图4),整体时延并没有显着的下降。因为网络带宽和写入读取数据的削减,时延毛刺也变小了。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图4. Proxy开紧缩后的带宽优化

3.2.3.线程模型的优化

Proxy选用IO多路复用技能,每个连接维护一个恳求处理行列和响应行列,保序的回来给客户端。Proxy在收到RedKV Server的回应之后,假如没有收到一切发送的cmd的回来,则会一向等候一切cmd的回来后再发送给client,关于读的场景这种形式十分不友好。经过改造,假如某个cmd之前的cmd都现已正常响应,则能够马上响应给client,不需求再等后边的一切cmd恳求完结。

3.2.4.backup-read优化长尾

在公网环境下,一个CVM虚拟机和其他多个虚拟机同享一台物理机。当某个客户的CVM占用许多资源时,很简单影响到其他CVM的P99时延(由于QOS和阻隔性做的不够好,SMI中断和内存CE)。在网络吞吐较大的情况下,某云的DPDK简单被打爆,呈现母机OOB。而在RedKV的内部完成中,假如Server恳求比较大,某些key的查询时延比较高的时分,简单产生排队堆积,或者compaction之后的block cache失效,很简单形成IO长尾。因而,RedKV的P99读时延的毛刺很难避免,但毛刺是偶然发生的,当时咱们的主从节点一定是离散布置在不同的母机上,一起呈现P99毛刺的或许很小。依据这点,咱们在Proxy层做了backup read功用,优化了RedKV的p99时延问题。

针对以上模型,咱们的优化思路:

  • 查看节点的状况和曩昔的延时
  • 挑选2个节点中状况好的那个节点发送恳求
  • 计算P99时延,超越P95时延则向别的一个节点发送一定数意图backupread恳求数
  • 两个恳求中任意一个恳求回来成功则成功,假如超时则继续重试

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图5. Backup-read 消峰

因为backup read转发不需求仿制内存,经过索引来确保生命周期,并且只要超越P95时延的报文会被查看是否能发送backup read,因而,只要5%的报文会发送两次,对集群基本不会增加压力。图6为一个集群中 P999从35ms下降到4ms左右,作用十分显着。比照HBase相同的事务场景,客户端在相同的timeout的装备下,咱们的计划提高了客户端的成功率。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图6. Backup-read P999优化比照

3.2.5.大Key检测

咱们线上许多集群在事务运用过程中会偶发的产生一些毛刺,经过抓包发现,这儿毛刺有很大一部分原因是因为大Key形成的。为了鉴别这类问题,咱们在Proxy层支撑的大Key的可观测目标。Proxy在解析Redis的cmd能够附带计算KV的巨细。关于string读类型的command,读到的val值大于 big-string-size 断定为大key;关于写类型的command, 恳求值大于 big-string-size 断定为大key;关于hash/zset则为一次读取的kv总数巨细。经过增加read_size(一切读恳求一共读到的字节数) 和 write_size (一切写恳求一共写入的字节数)监控,rate(read_size) / rate(total_req_amount) 能够计算出均匀恳求值巨细。大Key和热Key是KV体系不可避免的2个场景,针对大Key,咱们供给了Proxy层的数据紧缩才能;关于热Key, 咱们在Server层依据HeavyKeeper[3]算法做了topK计算和处理。

3.3.RedKV Cluster

公司的存储需求场景比较多,如广告事务存储的标签和数据模型许多,一起是十分中心的事务,事务需求做资源阻隔。为了削减节点毛病缩小数据的爆破半径 ,这儿事务咱们选用无中心管控的架构,即RedKV1.0架构,它能在布置和运维上能大大简化。无中心的集群架构选用的是Gossip协议,存储节点选用多进程多实例布置,如图7。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图7. Gossip管控的KVCluster

引荐模型练习的数据量十分大,上下游事务许多,承载的QPS高,对应集群的节点也比较多,在毛病处理和扩缩容方面会触发gossip颤动。针对大集群的节点办理,咱们选用有中心管控的架构,即RedKV2.0架构。依据Shard办理的中心架构能更好的支撑数据搬迁和集群扩缩容,存储节点选用单进程多实例布置,在多活场景中能够支撑副本数弹性扩展,如图8。RedKV2.0的相关组件会在后续的技能文章中详细介绍。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图8. 依据中心管控的KVCluster

3.3.1.Gossip优化

RedKV1.0选用Gossip协议通讯,节点毛病时主从节点的切换,最长影响时刻为30s。一个节点呈现毛病时,集群中正常节点将毛病节点标记为 fail 状况需求经过一段收敛时刻。在这段时刻内,Proxy层有或许将用户恳求转发给现已 fail 的节点,导致恳求失利。减小集群收敛时刻能有用削减Proxy层过错恳求数量,提高集群的安稳性和可用性。

RedKV1.0经过如下三个步骤加快视图收敛:

●勘探时刻优化:Redis Gossip协议正常情况下会每隔100ms随机选取一个节点发送ping包,并更新节点的ping_sent值为发送ping包时刻。假如集群很大,节点数许多,那么毛病节点被ping到的概率就会变小,最多超越node_timeout/2时刻给毛病节点发送ping包。这样就会导致节点发生毛病时,集群中正常节点不能第一时刻ping到毛病节点,然后无法马上感知到毛病节点发生了毛病。为了削减这部分时刻,当集群中有节点超越2s没有收到毛病节点发送的pong报文时,就立马告诉其他节点去ping毛病节点。这样能够把节点毛病到正常节点给毛病节点发送ping的时刻控制在2s左右。

●断定PFAIL时刻优化:Gossip 协议现有完成办法是超越node_timeout(一般为15s)时刻没有收到pong报文,就将节点状况置为pfail。本次优化将这个时刻设置为3s(可装备),假如24小时内(可装备)首次超越3s没有收到pong报文,就将节点置为pfail状况。假如24小时内频频呈现,那或许是网络颤动形成,还走本来的途径等候node_timeout。

●削减PFAIL到FAIL的断守时刻:只要一个节点收到集群1/2的节点的PFAIL信息的时分,才会将毛病节点断定为FAIL状况。而PFAIL这个信息是经过Gossip协议交互的,最久需求1/2 node_timeout才会告诉到其他节点。因而为了加快PFAIL到FAIL的状况,一切的节点按照一致的规则选出一个种子节点,PFAIL信息除了随机发送一个节点意外,还会告诉这个种子节点。这样种子节点能在最快的时刻学习到集群一切节点的PFAIL信息,然后将毛病节点标记为FAIL状况广播到集群。

3.3.2.RedKV Server

RedKV Server装备多个IO线程一起监听一个端口来承受连接恳求,每个线程上的连接数目会随机均衡。每个线程只解析自己连接上的恳求,并将解分出的报文经过key挂到对应的恳求行列上,每个行列由一个Worker线程处理。这样同一个key/同一个slot上的恳求都会落到同一根Worker线程上处理,避免了对key进行加锁,削减锁冲突和线程切换。Worker线程中会对数据进行重编码,存储到Rocksdb本地存储引擎。

RedKV内部的线程模型如下图9:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图9. RedKVServer无锁线程模型

3.3.3.数据存储

RedKV当时支撑的数据类型有string、hash和zset,数据节点挑选RocksDB[2]作为本地存储引擎,集群创建时支撑装备多副本,主从节点离散布置。选用hash打散的办法存储连续slot分片的数据,能比较好的避免热门key问题。不同的数据类型包括(MetaKey,MetaValue) 和(DataKey, DataValue),规划格局如下:

MetaKey:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

MetaValue:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

DataKey:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

DataValue:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

在如上的编码办法下,key的规划中保存的slot信息,能够在扩缩容的场景中经过slot灵活的做数据搬迁。

4.生态功用

4.1.数据仿制

与传统处理计划引入同步组件的办法不同,咱们快速完成了单向数据同步以及集群扩容需求,全体架构去除了对第三方组件的依靠,经过扩展Redis仿制协议完成了RedKV数据节点的直接仿制,如图10。单向仿制的约束是扩容需求依据2n做节点同步,扩容完结后后台使命依据3.3.3中界说的key的分片删去不是本节点的数据。

在多活的布置形态下,多云集群的一对多的数据仿制选用单向仿制对主集群功用侵入较大,因而咱们完成了依据中心管控的数据仿制战略。该战略支撑多个集群的分片异构布置,经过Checkpoint办法定向同步数据,不再需求额外的后台使命去做数据筛选,能很好的支撑多对多的多云集群数据仿制、数据破环和扩缩容。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图10.RedKV的数据仿制

4.2.数据批量导入

小红书许多的离线事务数据存储在S3 Hive中,每天会有部分数据需求增量更新,其他的数据会被筛选。这类场景有几个应战:

  • 批量导入:如小红书的笔记数据,一般需求小时等级甚至天等级的更新,所以事务需求有快捷的批量导入功用。
  • 快速更新:特征数据的特色就是数据量特别大,以笔记为例,全量笔记在TB 等级数据量。假如经过 Jedis SDK 写入,那么存储集群需求支撑百万QPS的机器资源。当下小红书数据渠道支撑事务把数据从hive经过工作流直接导入RedKV,一般是每天凌晨开端写数据,比及晚高峰时许多读取。这种办法实践下来,常常导致 RedKV集群的集群内存OOM,影响安稳性。
  • 功用及安稳:数据在导入的过程中不能影响读的功用

完成计划如图11:

  • 自界说获取集群视图和数据编码的UDTF,支撑RedKV1.0的数据格局
  • 将原先的抽数据,编码,分片和排序整合成一个HiveOperator,履行完结后按指定的OutputFormat输出SST文件到一个指定S3目录
  • 经过Hadoop distcp东西做数据的跨云传输,走离线带宽不影响线上的读写事务
  • RedKV集群的节点SiderCar作为对象存储的一个Client,RedKV节点加载本节点的SST并ingest

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图11.离线数据BulkLoad

4.3.数据批量导出

小红书的事务模型练习数据经过Hash存储在RedKV集群中,事务下游需求对练习成果进行离线分析,期望RedKV具有和Hive数据流转的才能。RedKV自身是不支撑Schema的,假如要将KV数据导入Hive表,则需求将Hash的KKV数据转化为一个Table。

RedKV的内部数据按hash打散,导入Hive表则需求供给table关键字,先按前缀扫描的办法扫描存储节点,再生成Hive识别的文件,最后经过Hive Load进行加载。为了更好的兼容其他spark使命,咱们挑选Hive支撑的规范parquet列式存储文件,整个I/O链路如下图12:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图12. RedKV2Hive I/O

示例:RedKV里边的Key 写入规定以{tablename}_开端,比方一个artical表

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

RedKV中的数据选用hmset写入:

hmset {person}_1 name John quantity 20 price 200.23
hmset {person}_2 name Henry quantity 30 price 3000.45

经过以上的写入办法,能够经过装备RedKV2Hive 将KV里边的数据导入到Hive里边的Person表假如单表的数据量很大,能够选用分表写入,比方把person表分成16份

hmset {person:1}_1 name John quantity 20 price 200.23
hmset {person:1}_2 name Henry quantity 30 price 3000.45
...
hmset {person:16}_100000 name Tom quantity 43 price 234.56

4.4.数据的备份和康复

小红书的广告数据存储在自研的分布式KV体系中,数据安全首要面对如下应战:

  • 依据LSM结构的KV体系,数据compaction导致的空间放大会翻倍,数据量大后,数据备份需求大容量的磁盘
  • 单集群毛病后,集群康复的时刻不可控
  • 备份数据依靠第三方体系
  • 广告体系对数据的及时康复才能有比较高的要求,一般要求在分钟级。为了处理上述几个问题,咱们提出了一种中心管控的主备集群容灾战略,经过Proxy接入层的秒级切换能快速切流到一个特定的版别

完成计划如图13:

  • 先布置一个容灾集群,主集群对外供给读写服务,灾备集群保存特定数量的快照数据
  • 低峰期,中心管控依据装备的版别数和使命时刻会守时的向主集群发送打快照的服务
  • 快照完结后经过发生长途rsync命令将快照目录传送到容灾集群,主集群低峰期数据紧缩后数据量可控,这样灾备集群能够备份指定数量的版别信息
  • 毛病发生后,中心管控能够在灾备集群经过RPC指令指定康复到一个特定的版别
  • Proxy接入层经过服务注册与发现主键装备2组服务,经过动态的秒级切换能够将流量打向特定版别的集群,完结服务拜访的秒级切换

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图13. 集群备份

4.5.跨云多活

为了应对高速增加的事务需求,公司对云厂商的服务安稳性要求越来越高,单机房云服务难以满意公司安稳性的需求,跨云多活能够提高服务的安稳性,双写双读能够完成主备数据中心均对外供给读写服务, 这样既不会形成数据中心的资源浪费又能够完成跨地域容灾。咱们对业界常用的计划做了一些比照分析:

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

咱们归纳调研其他厂商的架构经历,提出了RedKV双活规划( Replicator as Sidecar Service同机布置)计划,如图14。

●同机布置,网络开支小;

●Sidecar Service 对主服务侵入性小;

●单独布置,易于升级

架构灵活,适合日志类存储体系双活架构。Redis 以及图数据库的多云计划都能够改造适用,详细的功用组件和实战场景会在后续技能文章详细介绍。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图14. 跨云多活架构

5.实践事例

正如第2节描绘的小红书事务需求场景,本节经过一个典型的事务场景来展现RedKV在noSQL存储下的收益。

前期在没有zprofile中台的场景下,zprofile用户和笔记信息都存储在HBase。为了确保集群的数据安全和服务安稳性,HBase选用了双集群布置,写入和读取方经过HBase Client API做数据存储。HBase的用户数据在数十TB,在百万QPS下,P99时延现已在70ms左右,跟着QPS的快速增加,时延越来越高,集群扩容带来的存储本钱也越来越高,安稳性确保也面对极大的应战。

RedKV1.0上线后,经过半年多的打磨,开端渐渐接受公司的中心事务。引荐渠道架构组也开端着手打造zprofile中台服务,收敛上下游的事务,供给规范一致的读写办法。在存储计划上,渠道架构组同学和存储组经过多次的事务交流,终究挑选运用RedKV作为底层存储,首要对接两类事务方:分别是数据生产者 producer 以及数据消费方 consumer。zprofile终究的中台架构如下图15:

●zprofile-write service 对上游供给一致的数据写入接口服务,供给用户和比较的Meta办理,用户数据写入redkv-zprofile-user集群,笔记及其他数据写入redkv-zprofile-other集群。

●zprofile-service对下游供给一致的数据消费服务,对应时延要求不高的离线服务,RedKV自身支撑单向数据仿制的才能经过2个offline小集群供给数据scan事务。

全体架构改造完结后,运用RedKV对接相同QPS的事务才能,本钱节省了36%, P99功用提高了约5倍。

小红书自研KV存储架构如何实现万亿量级存储与跨云多活

图15. zprofile中台

6.作者信息

云哲

小红书根底架构存储组,现在首要担任RedKV1.0架构下的功用开发和安稳性建造,研讨方向为分布式KV、持久化内存KV存储和表格存储。

久美

小红书根底架构存储组,现在首要担任RedKV2.0架构下的功用开发和存储中间件建造,研讨研讨方向为分布式KV和存储中间件。

文书

小红书根底架构存储组,现在首要担任RedKV1.0架构下的功用开发和跨云多活建造,研讨方向为分布式KV和存储中间件。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。