`

jdon: 如何打败CAP定理?

 
阅读更多

原文 http://www.jdon.com/42886

 

一篇谈使用读写分离方式实现如何打败CAP定理文章,可以认为是Event Sourcing的一个变种。

CAP定理认为一致性 可用性和分区容错性同时不能获得,通常我们不能丧失分区容错性,那么你就只有在可用性和一致性之间选择,这就催生了NoSQL运行。

一致性意味着你实现一个成功的写以后,将来的读到的总是写的最新结果;可用性意味着你总是能对系统进行读写,在一个分区分布式系统,你只能拥有他们其中一个。

两者权衡时,如果一致性超过可用性,那么如果数据库不能用怎么办?你所做的是将写缓冲起来后来再写,但是所冒风险当这台服务器当机缓冲就丢失,当一个客户端认为写已经成功,但是实际在缓冲中没有写到数据库,就会发生不一致性. 替代方案是你返回错误给这个客户端,说数据库不可用,try again,用户使用这样的产品感受是如何呢?

如果你选择可用性高于一致性, 通过最终一致性实现,使用最终一致性情况下,你可能读取到和你刚才写入的不是同一个数据,有时多个读者读取同样的Key总是得到不同的结果,更新也许不可能传播到所有副本,这样你的一些副本更新了,另外的也许没有更新,这就需要跟踪历史,使用vector clocks 或将更新融合的方式(称为 "read repair").

维护一个最终一致性的应用是一个非常沉重的认为,read repair将受开发人员的粗心等错误影响,一旦read repair有问题,将引入数据库不可逆转的腐bai性。

这样,逃避可用性系统不能使用有问题,最终一致性又带来复杂性,又有什么替代方案呢?

你不能逃避CAP,但是能够隔离复杂性,将其不再影响你的大部分系统;CAP引起的复杂性其实来自于我们数据系统,数据系统的根本问题是:数据库中保存的是可变数据,然后有一个增量算法在不断更新这个数据状态,这个交互过程本身带来了复杂性。

CAP定理是数据系统相对机器出错后的容错级别,还有一种容错方式:人工容错,那是开发人员不够完美,Bugs等被带入系统产品,我们数据系统必须忍受有Bug的程序写入坏数据,作者展示的一个能够打败CAP的系统也将展示如何达到更好的人工容错。

作者认为他的方案更加优雅 可扩展性和健壮性。

作者首先发问:什么是数据系统,他认为可以用下面公式简单定义:
Query = Function(All Data)

所有数据系统都可以用这个公式表达,数据系统是回答关于数据集的问题,这些问题是查询Queries, 查询的都是数据,因此Query和Data是两个重要概念。

数据有两个重要属性:首先数据是基于时间的,数据是表达一段时间内一个逻辑为真的事实。另外一个属性是数据本质上是不可变的,因为和时间有关,我们是不能回到过去改变数据的真实性。

这两个属性就意味着:对数据你其实只有两个主要的操作:读取现有数据,并(随着时间)添加更多新的数据,CRUD(增删改查)称为CR(增读)。

这样,CRUD其实没有U修改,因为修改对不可变数据是不其作用的(非常类似DDD中值对象不可变,不能修改,只能更换)。

CRUD中也没有删除Delete,其实大部分删除其实是一种创建新数据,如果Bob停止跟随Mary,但是他们不能改变他曾经跟随过他的事实,删除那个他不跟随她的数据,你会增加一个数据记录,说他在某个时刻不再跟随她了。

作者随后解释了他的这套数据定义和普通没有什么不同(banq认为实际是从业务领域带有OO概念或者说业务逻辑去理解了,对于我们理解了面向对象,事件和状态以及与事实之间关系,这些定义非常容易理解和得到认同)。

下面是对Query查询,查询是一种计算功能,你可以通过查询实现很多功能,聚合,join不同数据类型等等。查询是对整个数据集的一种功能,当然很多查询不需要整个数据集,仅仅需要一个子集,这也不影响查询这个定义。

查询可以看成不可变数据的读,对于一个分布式系统大数据,如果一个每次都是从头开始查询的响应时间又在允许的延迟内
(从头查询因为有新数据加入),那么是否可以认为我们实际通过不可变数据和查询避免了CAP定理?

当然CAP定理还会起作用,关键是不可变数据,这样就避免了数据更新,那就不可能有那么多数据片变成不一致,那就意味着没有vector clocks, or read-repair,只有数据和数据上的查询功能,你就不必面对最终一致性。

之前引起复杂性是增量更新和CAP定理,这两个真的无法很好在一起工作,可变的值需要read=repair,通过拒绝增量更新,强迫不可变数据,从头计算每次查询,你能避免复杂性。

这个方案中挑战性工作是每次都从头计算的查询,这种查询是一种预计算的批处理查询,所幸的是我们有Hadoop,它是进行批处理的最好工具。

使用Thrift和Protocol Buffers可以让Hadoop处理结构化数据,Hadoop由两个部分:分布式文件系统HDF和批处理框架MapReduce,我们将数据不断加入HDFS中,一种Append方式;而预先计算查询依靠MapReduce,也有更易使用的工具: Cascalog, Cascading, and Pig

最好,你需要将预计算的结果索引,这样结果能够被应用很快访问,有一个数据库可以做到这点:ElephantDB and Voldemort read-only

这两个是能够为查询从Hadoop中将key/value数据导出,这些数据库支持批量写和随机读,但是不支持随机写,随机写是数据库中最复杂的,通过不支持能够实现更加简单健壮,ElephantDB只有几千行代码。

案例:如果你正在建立一个通过跟踪pageView实现的Web分析应用。你需要每隔一段时间查询PageView的数值:



每个数据记录包含一个page view. 这些数据都保存在HDFS文件中,每个小时通过URL来统计PageView,这作为MapReduce jobs. 发出key是[URL, hour],每个value值死页面访问量,这些key/value数据被导出到ElephantDB数据库中,这样应用程序能够更快地获得[URL, hour]的值. 当应用系统需要知道一段时间内的pageView时,它会查询那段时间内每个小时的PageView数值,然后将它们加在一起得到最后结果。

批处理可以计算有关任何数据的任何功能,这样就可以解决大部分问题,更重要的是它简单可扩展,你只要思考数据和功能,Hadoop为你考虑并行处理。

关于人工容错,因为数据是不可变的,数据集只能append追加,即使有bug的应用程序写入坏数据,也不会覆盖好数据,这是因为没有更新update。

即使MVCC 和 HBase row versioning也不能永远实现人工容错,一旦数据库影响到了行,旧数据已经丢失。

(banq注:不断append追加的好像应该是事件这样的数据,这样新事件不会覆盖旧事件,我们通过事件回放能够找到某个时间段的数据。见Martin fowler的Evetn sourcingLMAX架构)

以上查询是几个小时前的预处理查询,如何实现实时查询呢?需要一个实时系统和前面提到的批处理系统并行运行:



实时系统可以使用依赖修改的 Riak 或 Cassandra, 这些都依赖于增量算法和状态更新。

模拟Hadoop的实时计算是Storm,下面是这样的一个结合并行系统:


Hadoop 和 ElephantDB预先计算几个小时前的数据,最近几个小时数据都在实时系统中计算。

虽然实时系统我们也使用了NoSQL,但是是否又回到了CAP定理的复杂性呢?非也,因为数据只是最近几个小时内的,当然,如果你在实时系统范了错误,也不可能完全丢失数据,因为批处理系统会帮助你纠正。

这种实时系统使用Storm + Cassandra;批处理系统使用Hadoop + ElephantDB方式可以打败CAP定理,因为它隔离降低了CAP定理的复杂性原因。

作者以亲身经历说明这种方式的人工容错性:作者也没有什么系统监视工具,一天醒来,发现 Cassandra已经超出空间,每个请求都超时出错,这导致Storm当机,数据流被备份在消息队列中,因为消息发不出,一个消息 在那里不停地重复试图发出。(banq注:很显然是一种事件消息队列方式)

因为有批处理系统,作者清空这个队列中消息,重新部署Cassandra,批处理系统象顺时针钟一样几个小时内又恢复正常工作。无数据丢失和不正常查询结果。

垃圾数据回收可以避免数据集随着时间推移越来越大。

最后,作者总结了这种批处理/实时( batch/realtime)结合的架构的好处。

相关其他文章:
为什么要用Event Sourcing?

LMAX架构

闲话淘宝网和新浪微博架构

罗素摹状词理论与面向对象OO(讨论数据与事实的关系,与时间有关的数据准确称是状态,事件是触发状态的因,因此事件与事实最接近)




分享到:
评论

相关推荐

    DDD jDon源码

    《深入剖析DDD jDon源码:构建十年稳定架构的关键洞察》 DDD(领域驱动设计)是一种先进的软件开发方法,强调以业务领域为中心进行设计,通过将复杂的业务逻辑转化为清晰的模型来驱动系统的构建。jDon框架是基于DDD...

    Jdon论坛

    本Jive(Jdon版)可在Jbuilder 7/8直接打开,请失效Jbuilder的Jsp编译功能。 建议你用Jbuilder7打开后,编辑相应设置(注意,必须是JDK1.4以上版本) 本软件在linux+jdk1.4+tomcat 4以上环境运行正常,由于采取ISO...

    jdon_struts_hibernate_samples,jdon例子

    【标题】"jdon_struts_hibernate_samples" 是一个整合了Jdon、Struts和Hibernate技术的示例项目。这个项目展示了如何在Java Web开发中有效地利用这三个框架进行业务逻辑处理、用户界面展示以及持久层操作。 【描述...

    Jdon应用系统案例开发

    说明:每个应用系统中存在大量重复的CRUD开发流程,通过本框架可快速完成这些基本基础工作量,将精力集中在特殊功能设计上。 CRUD快速开发主要简化了表现层的流程,将其固化,或者是模板化,以配置替代代码编制,...

    JDON框架源码

    Jdon Framework(简称JF)是一套适合开发中小型J2EE/JavaEE应用系统的轻量Web框架(Lightweight Java Web Framework)。是国人独立开发的中国人自己的框架产品,2005年入选全球SUN公司网站java.net正式企业应用目录。...

    Jive Jdon Jbuilder7

    《Jive Jdon Jbuilder7:深度探索Java设计模式与应用开发》 在软件开发领域,Jive Jdon Jbuilder7是一款备受瞩目的集成开发环境(IDE),它为Java开发者提供了强大的工具支持,特别是对于设计模式的应用和项目构建...

    jdon完整源码及设计文档

    《Jdon完整源码及设计文档解析》 Jdon是一个基于Java语言的开源项目,它以其独特的设计思想和丰富的功能特性,在开源社区中备受关注。本文将深入探讨Jdon项目的源码结构、设计理念以及相关的设计文档,帮助读者理解...

    jdon-mvn-repo:jdon-mvn-repo

    【jdon-mvn-repo:jdon-mvn-repo】是一个与Java开发相关的资源库,主要服务于Maven构建系统。Maven是一个强大的项目管理和依赖管理工具,它通过使用XML格式的配置文件来管理项目的构建、报告和文档。在这个资源库中...

    jdon框架的使用-中文pdf清晰版

    ### Jdon框架使用详解 #### 一、Jdon框架概述 **Jdon框架**是一款针对J2EE(Java 2 Platform, Enterprise Edition)环境下的快速开发框架,旨在提高开发效率和降低开发难度。该框架由板桥里人(banq)创建并维护,自...

    jdon+structs+hibnate示例

    【标题】"jdon+structs+hibnate示例" 涉及到的是一个融合了三个核心技术的Java Web开发实例。jdon是一个国内开源的框架,它借鉴了Spring框架的设计理念,但针对中国的开发环境和需求进行了优化。在这个示例中,jdon...

    jdon核心思想

    ### jdon核心思想 jdon框架是一套基于Java语言的企业级应用开发框架,它强调了模块化、松耦合的设计原则,并且支持敏捷开发模式。本文将深入解析jdon的核心思想,尤其是其对Struts标签库的应用与理解。 #### ...

    JdonFramework开源框架 v5.1 Build20071025_jdonframework(毕设 + 课设).zip

    4. **持久层支持**:虽然提供的信息中没有明确指出Jdon对持久层的具体支持,但根据文件名如HibernateTemplate.class,可以推测Jdon可能集成了Hibernate作为ORM工具,为开发者提供了方便的数据访问接口,简化了数据库...

    struts+jdon+hibernate.rar_j2me_struts hibernate

    Struts、JDon和Hibernate是三个在Java EE(以前称为J2EE)开发中非常重要的框架,它们分别专注于Web层、领域驱动设计和持久化管理。让我们深入了解一下这三个框架及其结合使用的方式。 **Struts** Struts是一个开源...

    jdon 数据库表

    jdon 数据库表整理。 显示简介的jdon数据关系。

    Java框架研发思考.docx

    他尝试通过集成和创新来优化多层架构的复杂性,结合DDD和并发模型提升效率,并运用CAP定理解决分布式环境下的数据一致性问题。这篇文档对于Java开发者,尤其是在面试过程中准备讨论框架设计和优化的求职者,提供了...

    框架 源代码 struts+ jdon+ hibernate

    框架 源代码 struts jdon hibernate

    Torch是什么? - Thinking In Jdon1

    Torch是一个开源的科学计算框架,专为机器学习算法设计,尤其在深度学习领域有着广泛的应用。这个框架的核心是其强大的n维数组功能,能够处理复杂的数学运算和数据操作。以下将详细介绍Torch的主要特点: ...

    JdonFramework开源框架 v6.6.zip

    Jdon Framework(简称JF)是一套适合开发中小型J2EE/JavaEE应用系统的轻量Web框架(Lightweight Java Web Framework)。是国人独立开发的中国人自己的框架产品,2005年入选全球SUN公司网站java.net正式企业应用目录。...

    Java 中的设计模式 - jdon

    《Java中的设计模式 - jdon》是一本深入探讨Java编程中设计模式的电子书,它主要聚焦于如何在实际开发中应用和理解这些经典的设计原则和模式。设计模式是软件工程中的一种最佳实践,它总结了在特定上下文中解决常见...

Global site tag (gtag.js) - Google Analytics