53

VDL:唯品会强一致、高可用、高性能分布式日志存储介绍(产品篇)

 6 years ago
source link: http://mp.weixin.qq.com/s/2xBoTGUZ9mkSyufLbqRgNg
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

VDL:唯品会强一致、高可用、高性能分布式日志存储介绍(产品篇)

Original 怀兵 唯技术 2017-12-22 10:50 Posted on

“You can't fully understand databases, NoSQL stores, key value stores, replication, paxos, hadoop, version control, or almost any software system without understanding logs。”

--《The Log: What every software engineer should know about real-time data's unifying abstraction》

VDL是VIP Distributed Log的缩写,是唯品会自研的基于Raft协议的新一代分布式Log存储系统。这里的Log不是指glog或者log4j等日志库记录的应用程序日志,可以简单地把Log理解成广义的Data,和Database中的Data本质上是一样的,无非是VDL存储的Data数据Schema-less的,业务和用户可以灵活自解析,而Database中的Data通常和直接或间接和Schema相关。

VDL介绍系列分两篇文章对VDL进行介绍,包括:

- 产品篇: 介绍VDL产生的背景、当前产品形态和特点、后续演进思路等;
- 实现篇和质量管控篇: 实现主要剖析VDL的技术实现细节与高性能手段,和大家分享我们遭遇的挑战和踩过的坑。质量管控则介绍VDL如何保证产品质量,主要包括分布式系统如何测试,如何进行异常和错误注入,以及分布式系统中各个节点间的数据一致性如何验证等。

本篇是产品篇,会通过分布式系统的本质,讲解VDL的产生背景和产品定位。通过这篇文章,希望有更多人了解VDL,也期望为业务系统带来便利并产生价值。

 VDL的产品定位

Image

在阐述VDL的产品定位之前,我们先思考一个问题:用户对一个Storage System的诉求是什么?以及Client的诉求被正确地理解并满足了吗?如下图所示,大多数用户对一个存储系统的诉求,可以简单地概括为两点:

-存储系统按照用户写入的顺序存储数据;

-用户总是能从存储系统查询到最新的写入(结果)。

在早期的单机系统或者基于IOE的系统,这种诉求看起来无可厚非,而且也比较容易被满足,例如一个单机的MySQL数据库,由于其本身具备RDBMS系统的ACID属性,配置得当的话,这样的诉求大多数情况下都是可以满足的。

再回到我们公司目前的现状(也是大多数互联网公司的现状),Scale Up已经无法解决业务扩充的需求,不知不觉中,我们的系统已经Scale Out到一个实质上的分布式系统,存储系统也是如此。

如此以来,对于同样的用户诉求,现在的存储系统需要满足的约束条件发生了很大的变化:

-要求同一次写入,要在多个节点上不变地、按照用户发起的顺序写入;

-要求多个节点组成的存储集群,总是能够查询返回最新的写入结果。

这两个约束的本质就是Linearizability Consistency(https://en.wikipedia.org/wiki/Linearizability)。通俗地说,用户总是站在甲方的姿态,他不关心存储系统的后端如何实现,他要求一个分布式集群的行为,还是要满足单机系统的提供给他的承诺。

在一个分布式系统中,因为我们处在异步通讯的环境中,所以要满足这两个条件其实是非常困难的。万变不离其宗的就是分布式系统中的一致性,多个节点要就“一次请求的全局写入顺序编号达成一致”和“哪个节点上拥有最新的写入结果”等关键问题达成一致。仅仅是一致性达成这一点,从Paxos、Viewstamp Replication、ZAB到Raft等,核心都是解决这个问题,从理论到工程实践更是经历了一个漫长的过程。其实难题还不仅如此,即便我们就某一次写入的全局序号达成了一致,从而保证了所有的用户写入请求是一个全局有序的序列,但某一个写入请求在不同的节点上执行,也不一定会产生相同的结果:比如一次写入中依赖本地hostname、本地timestamp等等。所以我们这里讨论的前提是Log是Deterministic的,对于non-deterministic的Log,一般都是通过其中一个Node执行处理,将这个non-deterministic转化成一个Deterministic的Phyciological Log。

反过来看,如果一个存储系统不能提供给用户这样的承诺,那用户程序的逻辑势必非常复杂而且脆弱。用户可能面对的问题,比例:已经查询到某个数据的V3版本,当用户程序和存储系统之间网络中断又重连后,只能读取到V2版本(V3版本所在的节点宕机,切换到一个数据没有同步的节点上面)。相当长的一段时间内,MySQL数据库主从间的异步复制就可能存在这个问题,只是只要用户程序没有同时Crash切换,我们通常可以在用户程序本地缓存一些数据操作的流水,遇到这种情况进行补偿逻辑。

最后,回到主题即VDL的产品定位,VDL的目标是将这些复杂的问题尽可能地实现在VDL分布式存储集群的内部。给用户程序尽量简洁明了的语义承诺:线性一致性,这样用户总是可以像以往单机服务器时代一样任性(实际上,为了在不同的场景给用户更多选择,VDL可以提供另外一个一致性模型:严格遵循约束条件1,如果用户可以容忍读取到非最新写入的结果,放松约束条件2,也就是通常讲的“时序一致性”)。总而言之,VDL的产品定位是具备如下条件的通用分布式存储系统:

-强一致,提供线性一致性和时序一致性;

-高吞吐,在合理牺牲RT的情况下,有效保证系统整体的吞吐量;

-低延时,抛开实际部署拓扑中节点间物理距离引起的RTT开销,通过技术手段最大限度地降低单请求的端到端延时;

-持久化,Ack给用户之前,一定已经在多数派节点上落盘,避免用户遭遇“回档”;

-可控性,这个系统从设计到实现到代码细节,我们要完全HOLD住,不能像拿一个大型开源软件随便用用,遇到严重问题就抓瞎。

介绍完VDL的产品定位,先从我们权衡的角度来看看VDL和主流开开源产品间的定位差异,为什么不基于开源产品做二次开发?其实这个问题也比较简单,对于一个大型开源项目,例如MySQL/Kafka/Zookeeper/Cassandra等,从长远利益来看,其实要完全掌握它们和从头开发一个同类产品,投入产出比相当。

VDL和Kafka的联系和区别

Image

Kafka是一个非常成熟的消息系统,除了具备传统消息系统的Message Queue和Message Sub/Pub能力之外,还具备一些其他比较优秀的特性,例如:数据分区、灵活可控的副本策略等等。Kafka典型场景(https://kafka.apache.org/uses)包含:

-Traditional Message Broker
传统的Message Queue 和Message Sub/Pub功能

-Stream Processing - Staged Pipeline
和其他产品类似,比如Storm,就是可以让Message可以在多个Stage间流转,每一个Stage的处理逻辑可能不一样,但是Stage之间的输入/输出接口是统一的

-Commit Log
作为Commit Log来使用,这一点和VDL的目标场景之一是相同的。但是为什么我们并没有选择Kafka来作为Commit Log场景的选型呢?主要原因有三个,第一是LinkedIn公司自己的开发espresso(https://www.percona.com/live/data-performance-conference-2016/sessions/espresso-linkedins-distributed-document-store-top-mysql)数据库,就采用Kafka作为Commit Log来进行espresso数据库主从之间的复制。在Tom Quiggle去年演讲《espresso database replication with kafka》中数据来看,平均复制延迟为小于90ms,我们觉得这个延迟太大了,无法满足我们对数据库复制高性能、低延时的需求。第二,Kafka的数据复制协议,虽然总体上参考了微软PacificA论文作为理论基础,但是正如PacificA论文说的一样,这是一个复制框架、一个原型系统,Kafka具体的实现其实差距还是很大。更关键的是,从2012年Kafka复制协议的V1版本开始,直到2017年KIP-101(https://cwiki.apache.org/confluence/display/KAFKA/KIP-101+-+Alter+Replication+Protocol+to+use+Leader+Epoch+rather+than+High+Watermark+for+Truncation,最新Kafka 0.11.*版本),一直存在着比较严重的数据丢失的可能。虽然这个复制协议变得越来越像Raft协议,但是一直缺乏严谨的理论推导证明。第三,Kafka要用做一个可靠的Commit Log,需要的配置较为复杂,同时在这个严苛的配置下,性能较差。具体可以参考:Jiangjie (Becket) Qin 的演讲《Data Loss and Data Duplication in Kafka》。

-Others
Metric和应用调用链、Log聚合等。

换一个角度来看,除了Apache Kafka官方的典型场景介绍,我们看看一个消息系统,其实提供给用户的统一抽象可以理解成这样:

也就是说,消息系统是存储系统的一个抽象封装,而VDL其实定位就是消息系统的一个存储引擎。消息系统于用户而言,一个通用抽象模型是:

因此,消息系统是Log存储之上的一个更高层级的抽象,对于业务系统,可以选择使用消息系统、也可以选择直接使用Log存储系统。主要依赖业务特征,两者是相互补充的,共同构成公司数据处理的技术栈。

VDL和etcd/Zookepper/Consul的联系\区别

Image

etcd的定位是一个分布式的强一致K/V存储系统,所以其实etcd可以算是在VDL之上的一个更细分的存储形态。VDL的本质类似于etcd中的Write Ahead Log。etcd其实也是一种基于Replicated State Machine(后面我们会讲,这也是VDL使用场景之一)方法的分布式系统,不同在于VDL保证的边界是用户提交请求的全局有序,且持久化到集群中的各个副本上,之后State Machine如何replay这些Log可以根据具体情况而定。比如K/V系统,如果不考虑多个Key之间的业务关联关系,其实不同Key对应的写入请求可以并行replay到State Machine(Parallel RSM方向也有很多新成果,但落地的难度依然很大)。把Log一致性和State Machine的实现完全解耦开来,为实现State Machine的并发回放等,打下了坚实的基础,而且一个一致性的Log Stream,可以对应多个State Machine实现。

etcd建议的使用场景包含(https://coreos.com/etcd/docs/latest/learning/why.html):

-Metadata存储,当然也可以存储一些配置信息;

-Distributed Coordination,这个和Zookeeper和Consul的常用场景类似。

另外,etcd/Zookeeper/consul可以看成全局上,就是一个独立的一致性协议实例。而VDL一个LogStream就是一个Raft Group,我们通过在Raft Group级别的调度和分配,达到更好的资源利用和负载均衡效果。

VDL的应用场景

Image

 我们设想中,VDL的典型使用场景如下: 

-RSM(Replicated State Machine)

-Database replication
目前,其实主流的数据库复制都是基于Log Ship的方法,无论一个分布式系统采用哪种数据复制模式,其实基本的都是要保证Log在相同全局序号包含的内容相同,同时存在多个副本。Log可以是反应主库状态变化的Log(原始请求被主库处理后的输出),也可以是直接的用户写入请求,只是后者通常需要有手段保证这个Log是deterministic,也就是不会因为replay这个Log的节点不同,相同输入的Log产生了不同的结果输出。

-Storage Engine of Other Distributed System
正如前面提到的一样,如果我们要开发一个分布式强一致的K/V存储系统,那么使用LevelDB或者RocksDB作为本地的状态机就可以了。如果我们实现一个分布式强一致的Cache存储系统,那么我们可以使用Redis或者Memcached作为本地的状态机。当然,实际实现的过程中,State Machine的Snapshot如何实现,也有的一定的复杂度,不过无论如何这个抽象分层已经很好第把这个复杂度局限在了一个局部。

比如Apache Pulsar(http://pulsar.apache.org/),其实就是采用Apache Bookkeeper作为其后端存储系统,Pulsar负责对消息语义进行抽象和元数据的管理等。VDL在这方面的应用,基本思想就是一种Pluggable Store Engine的思想。这在很多大型存储系统中,已经是一个基本的架构形态。

-Unified Shared Log Abstraction

对公司来说,能否利用好数据对自身的高效运转非常关键,而利用数据就涉及到“数据的移动”和“数据的计算”。VDL的一个初衷就是去解决“数据移动”的问题,高效且容错地将Schema-less的数据共享在其他业务系统面前。同时,统一的共享Log服务,已经正在被很多大型互联网公司采纳和重视。比如,Facebook的LogDevice,腾讯的PaxosStore,Twitter的Distributed Log等,都体现出不同程度地对统一Schema-less Log存储的重视。Google一直对强一致高可用的存储系统十分重视,Google Research有一篇文章《Ubiq- A Scalable and Fault-tolerant Log Processing Infrastructure》,大致讲到了有些类似的思路。

另外,无论基于传统消息系统的业务架构体系,还是最近提得比较多的Streaming Platform(https://www.streaml.io/)体系,都非常依赖统一的Log存储系统。streamlio依赖Apache Bookkeeper作为分布式Log存储系统。

 VDL的衍生产品

Image

对唯品会来说,基于VDL衍生的第一个产品是Binlog Server,这个形态综合了RSM和Unified Log Abstraction两种场景。

下周将发布VDL的实现及质量管控介绍,敬请关注。



推荐阅读

【唯实践】Memcached使用那些事

唯品会大数据平台优化

Image

唯品会双十一大促技术保障实践

“唯技术”一档专为唯品技术人发声的公众号

欢迎投稿!!

只要是技术相关的文章尽管砸过来!

Image




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK