Stored-作业帮自研NoSQL数据库

  文/徐锐波

  

  概述

  项目背景

  为支撑在线业务的海量缓存需求及复杂IO场景,以更低的成本承载更大规模的流量及数据。

  项目现状

  承载作业帮90%的KV存储流量,常态峰值QPS:1500万缓存&存储数据量:130TB读耗时均值:0.1毫秒,写耗时均值:0.15毫秒可用性:99.9999%

  项目收益

  以当前存储量计算,较之标准Redis,成本节省400%.

  Bitalosdb:自研存储引擎,全新的IO架构,综合性能更极致。raft协议:深度优化Raft协议,大幅提升写性能及数据同步效率,完善选举策略,保障集群状态更加稳定。多云多主(CRDT):确保多云多主同时写入时,数据能自适应解决冲突问题,达成最终一致。兼容Redis协议:支持Redis用户无缝接入Stored,以满足更大容量的存储需求。

  存储全景图

  存储引擎

  问题:标准LSM-Tree存在读写放大问题;数据规模越大,读写放大的资源消耗越大;如何用更低的成本承载更大规模写入、大流量读取?

  方案:基于Bitalos-Trees解决读放大,基于Bithash实现KV分离解决写放大,基于冷热数据分离进一步节省内存及硬盘消耗

  Bitalosdb-IO架构

  Bitalos-Trees承载数据更新及热数据存储,提供高性能索引的同时,解决读放大。Bithash承载value存储,提供高性能读写的同时,解决写放大。Bitable承载冷数据存储,根据数据规模及访问频度,计算相对冷数据,流量低峰时转存至Bitable;提升数据压缩率,减少索引内存消耗,实现更合理的资源利用。

  KV分离-技术方案分析

  方案A

  

  方案B

  

  方案C

  分析

  总结方案A&B在vlog-GC时,需要查询&更新索引,消耗额外的CPU及IO资源。方案C在vLog读取时,会触发多次随机读取,读性能存在优化空间。Bitalosdb在保障vLog高性能读取的同时,实现GC在vLog内部闭环,无需查询&更新索引。

  Bitalosdb-KV分离技术(Bithash)

  文件结构

  

  数据写入

  

  数据读取

  

  索引写入

  当单文件的数据写入量超过Bithash单文件容量阈值时,关闭当前Bithash文件,并将内存索引落盘

  

  Bitalosdb-索引技术(Bitalos-Tree)

  基于前缀树的层级B+树

  

  分层过程每个虚线框代表一棵B+树,对于每一层(Trie Layer) B+树,采用M字节长度切割key进行索引。比如,两个key存放在同一层,那么它们的前M字节是相同的。极端情况下,所有key都是M字节,那么它们都位于Trie Layer 0;如果新增一个10*M字节长度的key,显然没必要把这个key放在Trie Layer 10;如果这个10*M字节的key前M字节和其他key一致,那么它也会被放在Trie Layer 0,如果不一致,那么需要生成新的子树,把这个10*M字节的key放在Trie Layer 1,即层数是懒惰生成的。

  Bitalosdb-性能

  对标引擎Rocksdb V7.6.0,截止当前最新版本机器配置CPU:Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHzDISK:2*3.5TB NVMe SSD (RAID 0)压测对比Cgroup:8Core;Concurrency:8;Key:32B,Value:1KB(100% Random)Bitalosdb VS Rocksdb,分别在数据规模:25GB、50GB、100GB进行压测,性能对比,如下:Bitalosdb VS Rocksdb,按单核CPU计算QPS,性能对比,如下:

  存储服务

  基于Raft协议的高性能数据一致性技术

  深度优化标准Raft数据同步机制:Bitalos-Server充分运用了批量处理、全异步IO、并行传输等关键技术,较之标准Raft协议,提升3倍以上的写性能

  

  基于Raft协议的预选举技术

  标准选举流程:当任一从节点与主节点心跳超时,会直接发起投票,导致集群选主影响写流量;然而,部分情况是因为单节点的网络抖动造成瞬时心跳超时,无需发起投票&选主。Bitalos-Server优化选举流程,新增预选举机制当任一从节点与主节点心跳超时,会发起预选举,尝试连接其他从节点,并确认其他从节点与当前主节点的状态是否正常如多数从节点与主节点状态正常,即结束预选举;如多数从节点与主节点状态异常,即发起正式选举;如预选举超时,即发起新一轮预选举

  基于CRDT的多云多主技术

  背景

  作业帮业务常态化在多云异地提供服务,作为业务强依赖的KV存储,需要提供更低的写延迟和更高的可用性,Bitalos-Server支持多云异地多主部署;然而,相同数据在多主写入并在多云集群间同步时可能产生冲突,检查并解决冲突是多主写入系统必须要处理的问题

  要求幂等 a☆a = a交换律 a☆b = b☆a结合律 a☆(b☆c) = (a☆b)☆c方案幂等单云集群内每条写入日志都会分配raft-log-id,多云集群间数据同步按raft-log-id顺序更新数据库,从而实现幂等效果交换律、结合律无状态value更新(如set、hset操作)的最终一致性使用LWW-Register语义有状态value更新(如incrby、hincrby)的最终一致性使用Counter语义集合类数据结构(hash、set、zset)中集合元素的最终一致性使用OR-Set语义

  

  结语

  随着作业帮的持续发展,业务数量和使用场景不断增加,对NoSQL数据库可用性及性能的要求越来越高。在此背景下,团队秉持着追求极致的理念,持续探索IO架构及存储算法,致力于向着更高可用、更高性能的目标继续演进;追求提供尽可能高的写/读吞吐,和较低的访问延迟。由于篇幅限制,更多技术细节及优化会在后续文章中讲述。

  作者介绍:

  徐锐波,2018年底加入作业帮,先后负责作业帮直播课中台及用户产品中台;同时带领存储技术团队基于多项原创技术,从0到1研发NoSQL数据库-Stored。幸福、卢文伟、刘方等人对本文亦有贡献。

  出处:https://mp.weixin.qq.com/s/x9JxMSGTeGcE9ey3cNHwbw