技术分享——NOSQL综合篇

 

. 应用篇

 

1.eBay 架构经验

·      Partition Everything 切分万物

·      Asynchrony Everywhere 处处异步

·      Automate Everything 全部自动

·      Remember Everything Fails 记录失败

·      Embrace Inconsistency 亲不同是谓大同

·      Expect (R)evolution 预言演变

·      Dependencies Matter 重视依赖

·      Be Authoritative 独断专行

·      Never Enough Data

·      Custom Infrastructure 自定义基础设施

 

2. 淘宝架构经验

·      适当放弃一致性

·      备份和隔离解决稳定性问题

·      分割和异步解决性能问题( 类似 eBay Asynchrony Everywhere)

·      自动化降低人力成本( 类似 eBay Automate Everything)

·      产品化管理

 

3.Flickr 架构经验

·      使得机器自动构建 (Teach machines to build themselves)

·      使得机器自监控(Teach machines to watch themselves)

·      使得机器自修复(Teach machines to fix themselves)

·      通过流程减少 MTTR (Reduce MTTR by streamlining)

 

4.Twitter 运维经验

    最近看到的另外一个介绍Twitter 技术的视频[Slides] [Video (GFWed)] ,这是TwitterJohn AdamsVelocity 2009 的一个演讲,主要介绍了Twitter 在系统运维方面一些经验。 本文大部分整理的观点都在Twitter(@xmpp) 上发过,这里全部整理出来并补充完整。Twitter 没有自己的硬件,都是由NTTA 来提供,同时NTTA 负责硬件相关的网络、带宽、负载均衡等业务,Twitter operations team 只关注核心的业务,包括PerformanceAvailabilityCapacity Planning 容量规划,配置管理等,这个可能跟国内一般的互联网公司有所区别。

(1).Metrics

    Twitter 的监控后台几乎都是图表(critical metrics) ,类似驾驶室的转速表,时速表,让操作者可以迅速的了解系统当前的运作状态。联想到我们做的类似监控后台,数据很多,但往往还需要浏览者做二次分析判断,像这样满屏都是图表的方法做得还不够,可以学习下这方面经验。据John 介绍可以从图表上看到系统的瓶颈- 系统最弱的环节(web,mq,cache,db?) ,根据图表可以科学的制定系统容量规划,而不是事后救火。

 

(2). 配置管理

    每个系统都需要一个自动配置管理系统,越早越好,这条一整理发到Twitter 上去之后引起很多回应。

(3).Darkmode

    配置界面可以enable/disable 高计算消耗或高I/O 的功能,也相当于优雅降级,系统压力过大时取消一些非核心但消耗资源大的功能。

(4). 进程管理

    Twitter 做了一个"Seppaku" patch ,就是将Daemon 在完成了nrequests 之后主动kill 掉,以保持健康的low memory 状态,这种做法据了解国内也有不少公司是这样做。

(5). 硬件

    Twitter CPUAMD 换成Xeon 之后,获得30% 性能提升,将CPU 由双核/4 核换成8 核之后,减少了40%CPU 。不过John 也说,这种升级不适合自己购买硬件的公司。

 

5.Twitter 代码协同经验

(1).Review 制度

    Twitter 有上百个模块,如果没有一个好的制度,容易引起代码修改冲突,并把问题带给最终用户。所以Twitter 有一强制的source code review 制度,如果提交的代码的svn comment 没有"reviewed by xxx" ,则precommit 脚本会让提交失败。review 过的代码提交后会通过自动配置管理系统应用到上百台服务器上。有@xiaomics 同学在Twitter 上马上就问,时间成本能否接受?如果有紧急功能怎么办?个人认为紧急修改时有两人在场,一人修改一人review 也不是什么难事。

(2). 部署管理

    从部署图表可以看到每个发布版本的CPUlatency 变化,如果某个新版本latency 图表有明显的向上跳跃,则说明该发布版本存在问题。另外在监控首页列出各个模块最后deploy 版本的时间,可以清楚的看到代码库的现状。

(3). 团队沟通

    Campfire 来协同工作,campfire 有点像群,但是更适合协同工作。对于Campfire 就不做更多介绍,可参考Campfire 官方说明。

 

6.Twitter 中的Cache 使用

·      Memcache key hash ,使用FNV hash 代替 MD5 hash ,因为FNV 更快。

·      开发了Cache Money plugin(Ruby) ,给应用程序提供read-throughwrite-through cache ,就像一个db 访问的钩子。当读写数据库的时候会自动更新cache ,避免了繁琐的cache 更新代码。

·      "Evictions make the cache unreliable for important configuration data" Twitter 使用memcache 的一条经验是,不同类型的数据需放在不同的mc, 避免eviction ,跟作者前文Memcached 数据被踢(evictions>0) 现象分析中的一些经验一致。http://timyang.net/data/memcached-lru-evictions/

·      Memcached SEGVs Memcached 崩溃(cold cache problem) 据称会给这种高度依赖CacheWeb2.0 系统带来灾难,不知道Twitter 具体怎么解决。

·      WebTwitter 使用了Varnish 作为反向代理,并对其评价较高。

 

十一. 其他篇

1. 云计算架构

(1). 层次图

 

    作者认为,金字塔概念最能说明每一层的大小,它也表达了每个层是依赖前层的消息传递。在概念上,硬件是基础和广泛层。SaaS 层是顶峰,也是最轻层。这种观点是来自于将购买SaaS 的的最终用户角度。对于一个非常大的企业内部,PaaS 平台层将是顶峰。使用内部开发的软件的内部各部门将实现他们的顶峰SaaS 。还要注意: 大小和层位置并不一定等同于重要性。硬件层可能是最重要的,因为它是所有超过一定点的商品。

(2). 硬件层-The Hardware Layer

    必须考虑容错和冗余,大部分人认为没有容错硬件廉价商品。冗余和容错处理在软件层内,硬件预计要失败的,当然故障多电源容错服务器,RAID 磁盘阵列也是必要的。

(3). 虚拟层-The Virtualiz a tion Layer

    基于操作系统OS 的虚拟化层,虚拟资源能够在线即时增加拓展,允许供应商提供基础设施作为服务(SaaS)VMwareCitrix 公司、Sun 都提供虚拟化产品。

(4).The IaaS Layer

    提供和控制的基于虚拟层的计算方式,终端用户能够精确控制每个虚拟机没分钟每小时耗费多少钱。比如提供一个共同的接口,如门户网站暴露的API ,允许最终用户创建和配置虚拟机模板的需求。最终用户还可以控制何时打开或破坏虚拟机,以及如何在虚拟机互相联网。在这个领域的主要竞争者例子是亚马逊网络服务的EC2S3 和数据库服务。

(5).The PaaS Layer

    这一层的目的是尽量减少部署云的复杂性和麻烦,最终用户利用和开发的这层的API 和编程语言。两个很好的例子是谷歌的App EngineForce.com 平台。在App Engine 中,谷歌公开云存储、平台和数据库,以及使用PythonJava 编程语言的API 。开发人员能够编写应用程序并部署到这一层中,后端可伸缩性架构设计完全交给谷歌负责,最终用户完全不必担心管理基础设施。Force.com 平台类似,但采用了自定义的编程语言名为Apex 。如果你是一个大型企业寻求内部开发应用的部署,这层是你的顶峰。

(6).The SaaS Layer

    如果您是中小型企业(SME) 和大企业不希望开发自己的应用程序时,SaaS 的层是你的顶峰( 是你将直接面对的) 。您只是进行有兴趣地采购如电子邮件或客户关系管理服务,这些功能服务已经被供应商开发成功,并部署到云环境中了,您只需验证的应用是否符合你的使用需要,帐单可以基于包月租费等各种形式。作为最终用户的您不会产生开发和维护拓展应用程序软件的任何成本。越来越多的企业订阅Salesforce.comSugar CRMSaaS 产品。

 

2. 反模式

(1). 单点失败(Single Point of Failure)

    大部分的人都坚持在单一的设备上部署我们的应用,因为这样部署的费用会比较低,但是我们要清楚任何的硬件设备都会有失败的风险的,这种单点失败会严重的影响用户体验甚至是拖垮你的应用,因此除非你的应用能容忍失败带来的损失,否则得话应该尽量的避免单点风险,比如做冗余、热备等。

(2). 同步调用

    同步调用在任何软件系统中都是不可避免的,但是我们软件工程师必须明白同步调用给软件系统带来的问题。如果我们将应用程序串接起来,那么系统的可用性就会低于任何一个单一组件的可用性。比如组件A 同步调用了组件B ,组件A 的可用性为99.9% ,组件B 的可用性为99.9% ,那么组件A 同步调用组件B 的可用性就是99.9% *99.9%=99.8% 。同步调用使得系统的可用性受到了所有串接组件可用性的影响,因此我们在系统设计的时候应该清楚哪些地方应该同步调用,在不需要同步调用的时候尽量的进行异步的调用( 而我这里所说的异步是一种基于应用的异步,是一种设计上的异步,因为J2EE 目前的底层系统出了JMS 是异步API 以外,其它的API 都是同步调用的,所以我们也就不能依赖于底层J2EE 平台给我们提供异步性,我们必须从应用和设计的角度引入异步性)

(3). 不具备回滚能力

    虽然对应用的每个版本进行回滚能力测试是非常耗时和昂贵的,但是我们应该清楚任何的业务操作都有可能失败,那么我们必须为这种失败作好准备,需要对系统的用户负责,这就要求系统一定要具有回滚的能力。当失败的时候能进行及时的回滚。( 说到回滚大家可能第一时间想到的是事务的回滚,其实这里的回滚应该是一种更宽泛意义的回滚,比如我们记录每一次的失败的业务操作,这样在出现错误的时候就不是依靠于事务这种技术的手段,而是通过系统本身的回滚能力来进行回滚失败业务操作)

(4). 不记录日志

    日志记录对于一个成熟稳定的系统是非常重要的,如果我们不进行日志记录,那么我就很难统计系统的行为。

(5). 无切分的数据库

    随着系统规模的慢慢变大,我们就需要打破单一数据的限制,需要对其进行切分。

(6). 无切分的应用

    系统在规模小的时候,也许感觉不出无切分的应用带来的问题,但是在目前互联网高速发展的时代,谁能保证一个小应用在一夜或者是几夜以后还是小应用呢?说不定哪天,我们就发现应用在突如其来的访问量打击的支离破碎。因此我们就需要让我们的系统和我们一样具有生命力,要想让系统具有应付大负载的能力,这就要求我们的应用具有很好的伸缩性,这也就要求应用需要被良好的切分,只有进行了切分,我们才能对单一的部门进行伸缩,如果应用是一块死板的话,我们是没有办法进行伸缩的。就好比火车一样,如果火车设计之初就把他们设计为一体的,那么我们还怎么对火车的车厢进行裁剪?因此一个没有切分的应用是一个没有伸缩性和没有可用性的应用。

(7). 将伸缩性依赖于第三方厂商

    如果我们的应用系统的伸缩性依赖于第三方的厂商,比如依赖于数据库集群,那么我们就为系统的伸缩性埋下了一个定时炸、弹 。因为只有我们自己最清楚我们自己的应用,我们应该从应用和设计的角度出发去伸缩我们的应用,而不是依赖于第三方厂商的特性。

3.OLAP

    联机分析处理(OLAP) 的概念最早是由关系数据库之父E.F.Codd1993 年提出的,他同时提出了关于OLAP12 条准则。OLAP 的提出引起了很大的反响,OLAP 作为一类产品同联机事务处理(OLTP) 明显区分开来。

(1).OLAP 报表产品最大的难点在哪里?

    目前报表工具最大的难点不在于报表的样式( 如斜线等) ,样式虽较繁琐但并非本质困难。最根本的难点在于业务部门知道报表代表的真正含义,却不知道报表的数据统计模型模型;而IT 部门通过理解业务部门的描述,在数据库端进行设置数据统计模型,却对报表本身所代表的价值很难理解。说起来有点深奥,其实并不复杂。

(2). 关于CUBE 运算

    OLAP 最基本的概念只有三个: 多维观察、数据钻取、CUBE 运算。

    OLAP 分析所需的原始数据量是非常庞大的。一个分析模型,往往会涉及数百万、数千万条数据,甚至更多;而分析模型中包含多个维数据,这些维又可以由浏览者作任意的提取组合。这样的结果就是大量的实时运算导致时间的延滞。我们可以设想,一个1000 万条记录的分析模型,如果一次提取4 个维度进行组合分析,那么实际的运算次数将达到41000 次方的数量。这样的运算量将导致数十分钟乃至更长的等待时间。如果用户对维组合次序进行调整,或增加、或减少某些维度的话,又将是一个重新的计算过程。从上面的分析中,我们可以得出结论,如果不能解决OLAP 运算效率问题的话,OLAP 将是一个毫无实用价值的概念。那么,一个成熟产品是如何解决这个问题的呢?这涉及到OLAP 中一个非常重要的技术 —— 数据CUBE 预运算。

(3).CUBE 预运算

    一个OLAP 模型中,度量数据和维数据我们应该事先确定,一旦两者确定下来,我们可以对数据进行预先的处理。在正式发布之前,将数据根据维进行最大限度的聚类运算,运算中会考虑到各种维组合情况,运算结果将生成一个数据CUBE ,并保存在服务器上。这样,当最终用户在调阅这个分析模型的时候,就可以直接使用这个CUBE ,在此基础上根据用户的维选择和维组合进行复运算,从而达到实时响应的效果。

 

4.NOSQL 们背后的共有原则

(1). 假设失效是必然发生的

    与我们先前通过昂贵硬件之类的手段尽力去避免失效的手段不同,NOSQL 实现都建立在硬盘、机器和网络都会失效这些假设之上。我们需要认定,我们不能彻底阻止这些时效,相反我们需要让我们的系统能够在即使非常极端的条件下也能应付这些失效。Amaz on S3 就是这种设计的一个好例子。你可以在我最近的文章 WhyExisting Databases (RAC) are So Breakable! 中找到进一步描述。哪里,我介绍了一些来自 Jason McHugh 的讲演的面向失效的架构设计的内容(Jason 是在Amaz onS3 相关工作的高级工程师)

http://cryolite.iteye.com/blog/550311

http://natishalom.typepad.com/nati_shaloms_blog/2009/11/why-existing-databases-rac-are-so-breakable.html

http://qconsf.com/sf2009/speaker/Jason+McHugh

(2). 对数据进行分区

    通过对数据进行分区,我们最小化了失效带来的影响,也将读写操作的负载分布到了不同的机器上。如果一个节点失效了,只有该节点上存储的数据受到影响,而不是全部数据。

(3). 保存同一数据的多个副本

    大部分NOSQL 实现都基于数据副本的热备份来保证连续的高可用性。一些实现提供了API ,可以控制副本的复制。也就是说,当你存储一个对象的时候,你可以在对象级指定你希望保存的副本数。在GigaSpaces ,我们还可以立即复制一个新的副本到其他节点,甚至在必要时启动一台新机器。这让我们不比在每个节点上保存太多的数据副本,从而降低总存储量以节约成本。你还可以控制副本复制是同步还是异步的,或者两者兼有。这决定了你的集群的一致性、可用性与性能三者。对于同步复制,可以牺牲性能保障一致性和可用性( 写操作之后的任意读操作都可以保证得到相同版本的数据,即使是发生失效也会如此) 。而最为常见的 GigaSpaces 的配置是同步副本到被分界点,异步存储到后端存储。

(4). 动态伸缩

    要掌控不断增长的数据,大部分NOSQL 实现提供了不停机或完全重新分区的扩展集群的方法。一个已知的处理这个问题的算法称为一致哈希。有很多种不同算法可以实现一致哈希。一个算法会在节点加入或失效时通知某一分区的邻居。仅有这些节点受到这一变化的影响,而不是整个集群。有一个协议用于掌控需要在原有集群和新节点之间重新分布的数据的变换区间。另一个( 简单很多) 的算法使用逻辑分区。在逻辑分区中,分区的数量是固定的,但分区在机器上的分布式动态的。于是,例如有两台机器和1000 个逻辑分区,那么每500 个逻辑分区会放在一台机器上。当我们加入了第三台机器的时候,就成了每333 个分区放在一台机器上了。因为逻辑分区是轻量级的( 基于内存中的哈希表) ,分布这些逻辑分区非常容易。

    第二种方法的优势在于它是可预测并且一致的,而使用一致哈希方法,分区之间的重新分布可能并不平稳,当一个新节点加入网络时可能会消耗更长时间。一个用户在这时寻找正在转移的数据会得到一个异常。逻辑分区方法的缺点是可伸缩性受限于逻辑分区的数量。更进一步的关于这一问题的讨论,建议阅读Ricky Ho 的文章 NOSQL Patterns

(5). 查询支持

    在这个方面,不同的实现有相当本质的区别。不同实现的一个共性在于哈希表中的 key/value 匹配。一些实现提供了更高级的查询支持,比如面向文档的方法,其中数据以 blob 的方式存储,关联一个键值对属性列表。这种模型是一种无预定义结构的(schema-less) 存储,给一个文档增加或删除属性非常容易,无需考虑文档结构的演进。而GigaSpaces 支持很多SQL 操作。如果SQL 查询没有指出特定的简直,那么这个查询就会被并行地map 到所有的节点去,由客户端完成结果的汇聚。所有这些都是发生在幕后的,用户代码无需关注这些。

(6). 使用Map/Reduce 处理汇聚

    Map/Reduce 是一个经常被用来进行复杂分析的模型,经常会和Hadoop 联系在一起。map/reduce 常常被看作是并行汇聚查询的一个模式。大部分NOSQL 实现并不提供map/reduce 的内建支持,需要一个外部的框架来处理这些查询。对于 GigaSpaces 来说,我们在SQL 查询中隐含了对map/reduce 的支持,同时也显式地提供了一个称为executors API 来支持 map/reduce 。在质疑模型中,你可以将代码发送到数据所在地地方,并在该节点上直接运行复杂的查询。

这方面的更多细节,建议阅读Ricky Ho 的文章 Query Processing for NOSQL DB

(7). 基于磁盘的和内存中的实现

    NOSQL 实现分为基于文件的方法和内存中的方法。有些实现提供了混合模型,将内存和磁盘结合使用。两类方法的最主要区别在于每GB 成本和读写性能。最近,斯坦福的一项称为"The Case for RAMCloud" 的调查,对磁盘和内存两种方法给出了一些性能和成本方面的有趣的比较。总体上说,成本也是性能的一个函数。对于较低性能的实现,磁盘方案的成本远低于基于内存的方法,而对于高性能需求的场合,内存方案则更加廉价。

    内存云的显而易见的缺点就是单位容量的高成本和高能耗。对于这些指标,内存云会比纯粹的磁盘系统差50100 倍,比使用闪存的系统差5-10 倍。内存云同时还比基于磁盘和闪存的系统需要更多的机房面积。这样,如果一个应用需要存储大量的廉价数据,不需要高速访问,那么,内存云将不是最佳选择。然而,对于高吞吐量需求的应用,内存云将更有竞争力。当使用每次操作的成本和能量作为衡量因素的时候,内存云的效率是传统硬盘系统的1001000 倍,是闪存系统的 5-10 倍。因此,对于高吞吐量需求的系统来说,内存云不仅提供了高性能,也提供了高能源效率。同时,如果使用DRAM 芯片提供的低功耗模式,也可以降低内存云的功耗,特别是在系统空闲的时候。此外,内存云还有一些缺点,一些内存云无法支持需要将数据在多个数据中心之间进行数据复制。对于这些环境,更新的时延将主要取决于数据中心间数据传输的时间消耗,这就丧失了内存云的时延方面的优势。此外,跨数据中心的数据复制会让内存云数据一致性更能难保证。不过,内存云仍然可以在跨数据中心的情况下提供低时延的读访问。

(8). 仅仅是炒作?

    近来我见到的最多的问题就是"NOSQL 是不是就是炒作?""NOSQL 会不会取代现在的数据库?"

    我的回答是 NOSQL 并非始于今日。很多NOSQL 实现都已经存在了十多年了,有很多成功案例。我相信有很多原因让它们在如今比以往更受欢迎了。首先是由于社会化网络和云计算的发展,一些原先只有很高端的组织才会面临的问题,如今已经成为普遍问题了。其次,已有的方法已经被发现无法跟随需求一起扩展了。并且,成本的压力让很多组织需要去寻找更高性价比的方案,并且研究证实基于普通廉价硬件的分布式存储解决方案甚至比现在的高端数据库更加可靠。( 进一步阅读) 所有这些导致了对这类" 可伸缩性优先数据库" 的需求。

    这里,我引用AWS 团队的接触工程师、VPJames Hamilton 在他的文章One Siz e Does Not Fit All 中的一段话:

" 伸缩性优先应用是那些必须具备无限可伸缩性的应用,能够不受限制的扩展比更丰富的功能更加重要。这些应用包括很多需要高可伸缩性的网站,如 FacebookMySpaceGmailYahoo 以及 Amaz on.com 。有些站点实际上使用了关系型数据库,而大部分实际上并未使用。这些服务的共性在于可扩展性比功能公众要,他们无法跑在一个单一的RDBMS 上。"

    总结一下我认为,现有的SQL 数据库可能不会很快淡出历史舞台,但同时它们也不能解决世上的所有问题。NOSQL 这个名词现在也变成了Not Only SQL ,这个变化表达了我的观点。

 

 

引用

http://www.jdon.com/jivejdon/thread/37999

http://queue.acm.org/detail.cfm?id=1413264

http://www.dbanotes.net/arch/five-minute_rule.html

http://www.infoq.com/cn/news/2009/09/Do-Not-Delete-Data

http://www.infoq.com/cn/news/2010/02/ec2-oversubscribed

http://timyang.net/architecture/consistent-hashing-practice

http://en.wikipedia.org/wiki/Gossip_protocol

http://horicky.blogspot.com/2009/11/nosql-patterns.html

http://snarfed.org/space/transactions_across_datacenters_io.html

http://research.microsoft.com/en-us/um/people/lamport/pubs/lamport-paxos.pdf

http://en.wikipedia.org/wiki/Distributed_hash_table

http://hi.baidu.com/knuthocean/blog/item/cca1e711221dcfcca6ef3f1d.html

http://z h.wikipedia.org/wiki/MapReduce

http://labs.google.com/papers/mapreduce.html

http://nosql-database.org/

http://www.rackspacecloud.com/blog/2009/11/09/nosql-ecosystem/

http://www.infoq.com/cn/news/2008/02/ruby-mapreduce-skynet

http://s3.amaz onaws.com/AllThingsDistributed/sosp/amaz on-dynamo-sosp2007.pdf

http://labs.google.com/papers/bigtable.html

http://www.allthingsdistributed.com/2008/12/eventually_consistent.html

http://www.rackspacecloud.com/blog/2009/11/09/nosql-ecosystem/

http://timyang.net/tech/twitter-operations/

http://blog.s135.com/read.php?394

http://www.programmer.com.cn/1760/

 

 

猜你喜欢

转载自dongbao100.iteye.com/blog/1730559