互联网每天产生数以亿计的数据,这些数据如何能够被正确地存储、解析、利用,是摆在每个数据公司面前的挑战。传统的关系型数据库,对于处理大规模的数据显得力不从心,由此以NoSQL为代表的分布式存储应运而生。
NoSQL,泛指非关系型的数据库。NoSQL数据库的产生旨在解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用的难题。
本章介绍分布式存储。
分布式存储系统,是将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器的空间有限成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负载,利用位置服务器定位存储信息,它不但提升了系统的可靠性、可用性和存取效率,还易于扩展。
分布式存储系统在实现时往往需要考虑以下因素。
1.一致性
分布式存储系统需要使用多台服务器共同存储数据,而随着服务器数量的增加,服务器出现故障的概率也在不断增大。为了保证在有服务器出现故障的情况下系统仍然可用,一般做法是把一个数据分成多份存储在不同的服务器中。但是由于故障和并行存储等情况的存在,同一个数据的多个副本之间可能存在不一致的情况。这里称保证多个副本的数据完全一致的性质为一致性。
2.可用性
分布式存储系统需要多台服务器同时工作。当服务器数量增多时,其中的一些服务器出现故障是在所难免的。我们希望这样的情况不会对整个系统造成太大的影响。在系统中的一部分节点出现故障之后,系统的整体运行不影响客户端的读/写请求称为可用性。
3.分区容错性
分布式存储系统中的多台服务器通过网络进行连接。但是我们无法保证网络是一直通畅的,分布式系统需要具有一定的容错性来处理网络故障带来的问题。一个令人满意的情况是,当一个网络因为故障而分解为多个部分的时候,分布式存储系统仍然能够工作。
传统的关系型数据库,在部署上往往采用单机部署的方式,这在容错性方面存在限制。而且,关系型数据库对于大数据处理能力较弱,无法应对海量数据的应用场景。
以NoSQL为代表的分布式存储正在着力于解决上述问题。以下场景非常适合使用NoSQL。
·分布式部署。主流的NoSQL都支持分布式存储,这非常适合对容错性要求比较高的业务场景。
·海量数据存储。当数据量达到TB规模以上时,无论是MySQL还是Oracle,传统的关系型数据库,都已经无法支撑数据的及时处理,此时宜选用NoSQL。
·高性能。分布式存储产品,充分利用多处理器和多核计算机的性能,并考虑在分布于多个数据中心的大量此类服务器上运行。它可以一致而且无缝地扩展到数百台机器,因此,即便在高负载的场景下,依然拥有良好表现。
是否使用分布式存储,需要根据自己的项目情况来斟酌。一是要看自己应用的数量量规模,看是否达到了TB级别以上;二是要看业务对于应用的容错、可扩展性、性能等方面的考量。同时,使用分布式存储相比于传统的关系型数据库而言,需要一定的学习成本,所以,在技术选型时,也需要综合考虑企业自身的人力资源情况。
分布式存储技术在业界已经非常成熟。Bigtable是Google三宝之一,在Google自己的产品和项目上都有着广泛的应用。Apache HBase、Apache Cassandra都是开源的分布式存储技术,可以实现与ApacheHadoop、Apache Spark等计算平台无缝集成。Memcached、Redis是常用的分布式缓存方案,适用于高性能的缓存数据存取。MongoDB是一个介于关系型数据库和非关系型数据库之间,是非关系型数据库当中功能最丰富、最像关系型数据库的产品,因此理论上可以直接作为关系型数据库的替代。
接下来将会对这些技术做详细的介绍。
Bigtable是非关系型数据库,是一个稀疏的、分布式的、持久化存储的多维度排序Map。Bigtable设计目的是快速且可靠地处理PB级别的数据,并且能够部署到上千台机器上。
Bigtable已经实现了4个目标:适用性广泛、可扩展、高性能和高可用性。
Bigtable已经在超过60个Google的产品和项目上得到了应用,包括Google Analytics、GoogleFinance、Orkut、Personalized Search、Writely和GoogleEarth等。这些产品对Bigtable提出了不同的需求,有的需要高吞吐量的批处理(从URL到网页到卫星图像),有的则需要及时响应数据给最终用户(从后端的批量处理到实时数据服务)。它们使用的Bigtable集群的配置也有很大的差异,有的集群只有几台服务器,而有的则需要上千台服务器、存储几百TB的数据。尽管应用需求差异很大,但是,针对Google的这些产品,Bigtable还是成功地提供了一个灵活的、高性能的解决方案。
1.Bigtable简介
在很多方面,Bigtable和传统的数据库很类似,也使用了很多数据库的实现策略,拥有并行数据库和内存数据库所具备的可扩展性和高性能,同时Bigtable提供了一个和这些系统完全不同的接口。
Bigtable不支持完整的关系数据模型,与之相反,Bigtable为客户提供了简单的数据模型,利用这个模型,客户可以动态控制数据的分布和格式,用户也可以自己考虑如何实现底层存储数据的位置相关性。数据的下标是row和column的名字,名字可以是任意的字符串。
Bigtable将存储的数据都视为字符串,但是Bigtable本身不去解析这些字符串,客户程序通常会在把各种结构化或者半结构化的数据串行化到这些字符串里。通过仔细选择数据的模式,客户可以控制数据的位置相关性。最后,可以通过Bigtable的模式参数来控制数据是存放在内存中还是硬盘上。
Bigtable技术本身是闭源的,Cloud Bigtable是Google提供的大数据存储云服务。业界相关的Bigtable模型的开源实现有Apache HBase(该技术会在后面讲述)。
Bigtable具备以下特点。
·适合大规模海量数据(PB级数据)。
·分布式、并发数据处理,效率极高。
·易于扩展,支持动态伸缩。
·适用于廉价计算机设备。
Bigtable也有以下的局限性。
·适合读操作,不适合写操作。
·不适用于传统关系型数据库。
2.Bigtable的数据模型
Bigtable是一个稀疏的、分布式的、持久化存储的多维度排序Map。Map在编程语言中是一种非常常见的数据结构,由key和value组成。Map的索引是由row key(行键)、column key(列键)以及timestamp(时间戳)来确定的。Map中的每个value都是一个未经解析的byte数组。映射关系如下。
(row:string,column:string,time:int64)->string
为了更加形象地解释Bigtable的数据模型,我们先举个具体的例子,从这个例子可以看出当初Bigtable的设计者是如何设计这个模型的。假设我们想要存储海量的网页及相关信息,我们姑且称这个特殊的表为Webtable。在Webtable里,我们使用URL作为row key,使用网页的某些属性作为column名,网页的内容存在“contents:”列中,并用获取该网页的timestamp作为标识,如图14-1所示。
图14-1 Webtable示例
图14-1所示是一个Webtable的部分片段,用于存储Web页面。row名是一个反向URL。contents column族存放的是网页的内容,anchorcolumn族存放引用该网页的锚链接文本。CNN的主页被Sports Illustrater和MY-look的主页引用,因此该row包含了名为“anchor:cnnsi.com”和“anchor:my.look.ca”的column。每个anchor链接只有一个版本(时间戳标识了列的版本,t9和t8分别标识了两个anchor链接的版本)。而contents column则有3个版本,分别由时间戳t3、t5和t6标识。
·行(Row):表中的row key可以是任意的字符串(目前支持最大64kB的字符串,但是对大多数用户,10~100bytes就足够了)。对同一个row key的读或者写操作都是原子的(不管读或者写这一row里多少个不同column),这个设计决策能够使用户很容易地理解程序在对同一个row进行并发更新操作时的行为。
·列族(Column Family):column key组成的集合叫作“columnfamily(列族)”,column family是访问控制的基本单位。存放在同一column family下的所有数据通常都属于同一个类型(我们可以把同一个column family下的数据压缩在一起)。column family在使用之前必须先创建,然后才能在column family中任何的column key下存放数据。
column family创建后,其中的任何一个column key下都可以存放数据。
一张表中的column family不能太多(最多几百个),并且column family在运行期间很少改变。与之相对应的,一张表可以有无限多个column。
column key的命名语法为family:qualifier。column family的名字必须是可输出显示的字符串,而限定符的名字可以是任意的字符串。比如,Webtable有个column family叫language,language用来存放撰写网页的语言。我们在language中只使用一个column key,用来存放每个网页的语言标识ID。Webtable中另一个有用的column family是anchor。这个column family的每一个column key代表一个anchor链接,如图14-1所示。
这个column family的qualifier(限定符)是引用该网页的站点名。这个column family的每列的数据项存放的是链接文本。访问控制、磁盘和内存的使用统计都是在column family层面进行的。在Webtable的例子中,上述的控制权限能帮助我们管理不同类型的应用:我们允许一些应用可以添加新的基本数据,一些应用可以读取基本数据并创建继承的columnfamily,一些应用则只允许浏览数据(甚至可能因为隐私不能浏览所有数据)。
·时间戳(Timestamp):在Bigtable中,表的每一个数据项都可以包含同一份数据的不同版本,不同版本的数据通过timestamp来索引。
Bigtable的timestamp类型是64位整型。Bigtable可以给timestamp赋值,用来表示精确到毫秒的“实时”时间。用户程序也可以给timestamp赋值。如果应用程序需要避免数据版本冲突,那么它必须自己生成具有唯一性的timestamp。数据项中,不同版本的数据按照timestamp倒序排序,即最新的数据排在最前面。为了减轻多个版本数据的管理负担,每一个column family都配有两个设置参数,Bigtable通过这两个参数可以对废弃版本的数据自动进行垃圾收集。用户可以指定只保存最后n个版本的数据,或者只保存“足够新”的版本的数据,比如,只保存最近7天的内容写入的数据。在Webtable的例子里,“contents:”列存储的时间信息是Web爬虫抓取一个页面的时间。上面提及的垃圾收集机制可以让我们只保留最近3个版本的网页数据。
Apache HBase(以下简称HBase)是一个分布式的、面向列的开源数据库。正如14.3.1小节所提到的,该技术来源于Google的Bigtable。就像Bigtable利用了GFS所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系型数据库,第一,它是一个适合于非结构化数据存储的数据库;第二,它是基于列的而不是基于行的模式。
HBase由Powerset在2007年创建,最初是Hadoop项目的一部分,在2010年演变成Apache的顶级项目。
1.HBase的简介
HBase(Hadoop Database)是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC上搭建起大规模结构化存储集群。
HBase是Google Bigtable的开源实现,类似Google Bigtable利用GFS作为其文件存储系统,HBase利用Hadoop HDFS作为其文件存储系统;
Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用Chubby作为协同服务,HBase利用ZooKeeper作为对应。
HBase是一种NoSQL数据库。从技术上来说,HBase更像是“DataStore(数据存储)”,因为HBase缺少很多RDBMS的特性,如列类型、第二索引、触发器、高级查询语言等。
然而,HBase有许多特征同时支持线性化和模块化扩充。HBase集群通过增加RegionServer来进行扩展,而且只需要将它放到普通的服务器中。例如,如果集群从10个扩充到20个RegionServer,存储空间和处理容量都同时翻倍。RDBMS也能进行扩充,但仅针对某个点——特别是对一个单独数据库服务器的大小——同时,为了更好的性能,需要依赖特殊的硬件和存储设备,而HBase并不需要这些。
2.HBase的特性
·强一致性读写:HBase不是“Eventual Consistentcy(最终一致性)”数据存储,这让它很适合高速计数聚合类任务。
·自动分片(Automatic sharding):HBase表通过region分布在集群中,数据增长时,region会自动分割并重新分布。
·RegionServer自动故障转移。
·Hadoop/HDFS集成:HBase支持开箱即用的HDFS作为它的分布式文件系统。
·MapReduce:HBase通过MapReduce支持大并发处理。·Java客户端API:HBase支持易于使用的Java API进行编程访问。
·Thrift/REST API:HBase也支持Thrift和REST作为非Java前端的访问。
·Block Cache和Bloom Filter:对于大容量查询优化,HBase支持Block Cache和Bloom Filter。
·运维管理:HBase支持JMX提供内置网页用于运维。
3.HBase的应用场景
HBase不适合所有场景。
·首先,确信有足够多数据,如果有上亿或上千亿行数据,HBase是很好的备选。如果只有上千或上百万行,则传统的RDBMS可能是更好的选择。因为所有数据如果只需要在一两个节点进行存储,会导致集群其他节点的闲置。
·其次,确信可以不依赖所有RDBMS的额外特性。例如,列数据类型、第二索引、事务、高级查询语言等。
·最后,确保有足够的硬件。因为HDFS在小于5个数据节点时,基本上体现不出它的优势。虽然HBase能在单独的笔记本上运行良好,但这应仅当成是开发阶段的配置。
4.HBase的优缺点
HBase的优点如下。
·列可以动态增加,并且列为空就不存储数据,节省存储空间。
·HBase可以自动切分数据,使得数据存储自动具有水平扩展功能。
·HBase可以提供高并发读写操作的支持。
·与Hadoop MapReduce相结合有利于数据分析。
·容错性。
·版权免费。·非常灵活的模式设计(或者说没有固定模式的限制)。
·可以和Hive集成,使用类SQL查询。
·自动故障转移。
·客户端接口易于使用。
·行级别原子性,即PUT操作一定是完全成功或者完全失败。
HBase的缺点如下。
·不能支持条件查询,只支持按照row key来查询。
·容易产生单点故障(在只使用一个HMaster的时候)。
·不支持事务。
·JOIN不是数据库层支持的,而需要用MapReduce。
·只能在单个row key上索引和排序。
·没有内置的身份和权限认证。
3.HBase与Hadoop/HDFS的差异
HDFS是分布式文件系统,适合保存大文件。官方宣称它并非普通用途的文件系统,不提供文件的个别记录的快速查询。HBase基于HDFS,并能够提供大表记录的快速查找和更新。HBase内部将数据放到索引好的“StoreFiles”存储文件中,以便提供高速查询,而存储文件位于HDFS中。
Apache Cassandra(以下简称Cassandra)是一个开源的、分布式、去中心化、弹性可扩展、高可用性、容错、一致性可调、面向行的数据库,它基于Amazon Dynamo的分布式设计和Google Bigtable的数据模型。它最初由Facebook创建,用于存储收件箱等简单格式的数据,于2008年开源。此后,由于Cassandra良好的可扩展性,被Twitter等知名网站所采纳,成为一种流行的分布式结构化数据存储方案。
1.Cassandra的简介
Cassandra是Facebook于2008年7月在Google Code上开源的项目,最早是由Amazon前雇员和一位Microsoft的工程师写成的。这个系统受到Amazon Dynamo的巨大影响Cassandra实现了Dynamo风格的副本复制模型和没有单点失效的架构,增加了更加强大的column family数据模型。
2009年1月,Cassandra被接纳为Apache基金会的孵化器项目,并于2010年3月成为顶级项目。此时,很多知名公司包括Facebook、Rackspace、Twitter等都成为Cassandra的用户。
伴随着业界对于Cassandra商业化、产品化的需求,在2010年4月Apache Cassandra项目主席Jonathan Ellis及其同事Matt Pfeil成立了一家服务公司,称为DataStax(原先的名字为Riptano)。DataStax雇用了多名Cassandra贡献者,成为领导和支持Cassandra项目的主力。2015年11月,Cassandra发布了3.0版本,其底层的存储引擎已被重写,支持全局索引,支持Java 8,并将基于Thrift命令行的界面移除了。
2.Cassandra的特性
Cassandra具有以下特性。
·分布式与去中心化:Cassandra是分布式的,这意味着它可以运行在多台机器上,并呈现给用户一个一致的整体。对于很多存储系统(如MySQL、Bigtable、HBase等),一旦开始扩展它,就需要把某些节点设为主节点,其他则作为从节点。但Cassandra是去中心的,也就是说每个节点都是一样的,没有节点会承担特殊的管理任务。与主从模式(master-slave)相反,Cassandra的协议是P2P的,并使用gossip来维护存活或死亡节点的列表。去中心化这一事实意味着Cassandra不会存在单点失效。Cassandra集群中的所有节点的功能都完全一样,所以不存在一个特殊的主机作为主节点来承担协调任务。有时这被叫作“serversymmetry(服务器对称)”。综上所述,因为Cassandra是分布式、去中心化的,它不会有单点失效的问题,所以支持高可用性。
·弹性可扩展:可扩展性是指系统架构可以让系统提供更多的服务而不降低使用性能的特性。最简单的达到可扩展性的手段,就是给现有的机器增加硬件的容量、内存来进行垂直扩展。而水平扩展则需要增加更多机器,每台机器提供全部或部分数据,这样所有主机都不必负担全部业务请求。但软件自己需要有内部机制来保证集群中节点间的数据同步。弹性可扩展是指水平扩展的特性,即集群可以在不间断的情况下,方便扩展或缩减服务的规模。这样,用户就不需要重新启动进程,不必修改应用的查询,也无须自己手工重新均衡数据分布。在Cassandra里,只要加入新的计算机,Cassandra就会自动发现它并让它开始工作。
·高可用与容错:系统的可用性是由满足请求的能力来度量的。但计算机可能会有各种各样的故障,从硬件器件故障到网络中断都有可能。所以它们一般都有硬件冗余,并在发生故障事件的情况下会自动响应并进行热切换。从软件的层次来说,设置多个数据中心,就是“软件冗余”,它能保障在灾难发生时,故障中断的功能在剩余系统上能够进行恢复。Cassandra就是高可用的。用户可以在不中断系统的情况下替换故障节点,还可以把数据分布到多个数据中心里,从而提供更好的本地访问性能,并且在某一数据中心发生火灾、洪水等不可抗灾难的时候防止系统彻底瘫痪。
·可调一致性(Tuneable Consistency):一致性的基本含义是读操作一定会返回最新写入的结果。扩展数据存储系统就意味着我们不得不在数据一致性、节点可用性和分区容错性之间做某些折中(即CAP理论)。Cassandra常被称为是“最终一致性”的,简单地说,Cassandra牺牲了一点一致性来换取了完全的可用性。但是Cassandra实际更应该表述为“可调一致性”,它允许用户方便地选定需要的一致性水平与可用性水平,在二者之间找到平衡点。客户端可以控制在更新到达多少个副本之前,必须阻塞系统。通过设置replication factor(副本因子)来调节与之相对的一致性级别。通过replication factor,用户可以决定准备牺牲多少性能来换取一致性。replication factor是用户要求更新在集群中传播到的节点数(注意,更新包括所有增加、删除和更新操作)。客户端每次操作还必须设置一个consistency level(一致性级别)参数,这个参数决定了多少个副本写入成功才可以认定写操作是成功的,或者读取过程中读到多少个副本正确就可以认定是读成功的。这里,Cassandra把决定一致性程度的权利留给了用户自己。所以,如果需要,用户可以设定consistency level和replication factor相等,从而达到一个较高的一致性水平,不过这样就必须付出同步阻塞操作的代价,只有所有节点都被更新完成才能成功返回一次更新。而实际上,Cassandra一般都不会这么用,原因显而易见(这样就丧失了可用性,影响性能,而且这不是用户选择Cassandra的初衷)。而如果一个客户端设置consistency level低于replication factor,即使有节点宕机了,仍然可以写成功。
·面向行(Row-Oriented):Cassandra不是真正意义上的“Column-Oriented(面向列)”的数据库,而是“Row-Oriented”的,它的数据结构不是关系型的,而是一个多维稀疏哈希表。“稀疏”意味着任何一行都可能会有一列或者几列,但每行都不一定(像关系模型那样)和其他行有一样的列。每行都有一个唯一的键值,用于进行数据访问。所以,更确切地说,应该把Cassandra看作一个有索引的、Row-Oriented的存储系统。Cassandra的数据存储结构基本可以看作一个多维哈希表。这意味着不必事先精确地决定具体数据结构或是记录应该包含哪些具体字段,因而特别适合处于草创阶段、还在不断增加或修改服务特性的应用,而且也特别适合应用在敏捷开发项目中,不必进行长达数月的预先分析。对于使用Cassandra的应用,如果业务发生变化了,只需要在运行中增加或删除某些字段,不会造成服务中断。当然,这不是说不需要考虑数据,相反,Cassandra需要我们换个角度看数据。在RDBMS里,首先得设计一个完整的数据模型,然后考虑查询方式,而在Cassandra里,可以首先思考如何查询数据,然后提供这些数据就可以了。
·灵活的模式(Flexible Schema):早期版本的Cassandra忠实于Bigtable的设计,采用的是“schema-free(无模式)”的数据模型,新的column可以被动态定义。schema-free模式的数据库在处理大数据时有非常强的可扩展和高性能的优势。但这种模式的主要缺点是在确定数据的含义和数据的格式时存在难点,而这限制了执行复杂查询的能力。
CQL(Cassandra Query Language)正是为了解决这一问题而产生的。
CQL提供了一种通过类似于SQL(Structured Query Language)的语法来定义的模式。起初,CQL是基于Apache Thrift项目的schema-free接口来提供额外的Cassandra接口的。在这个过渡阶段,模式是可选的,可以通过CQL来定义,也可以通过Thrift API来实现在添加新的column时动态扩展。自Cassandra 3.0以来,将不推荐采用通过基于Thrift API来实现动态创建column的方式。Cassandra的底层存储已重新实现,并与CQL更紧密地结合起来。Cassandra并不限制动态扩展模式,但它的工作方式已经显著不同了。CQL的集合,如list、set,特别是map提供在无结构化的格式里面添加内容的能力,从而能扩展现有的模式。CQL还提供了改变列的类型的能力,以支持JSON格式的文本的存储。因此,Cassandra支持“灵活的模式”。
·高性能:Cassandra在设计之初就特别考虑了要充分利用多处理器和多核计算机的性能,并考虑在分布于多个数据中心的大量这类服务器上运行。它可以一致而且无缝地扩展到数百台机器。Cassandra已经显示出了高负载下的良好表现,在一个非常普通的工作站上,Cassandra也可以提供非常高的写吞吐量。而如果增加更多的服务器,你还可以继续保持Cassandra所有的特性而无须牺牲性能。
Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached是基于一个存储key-value的哈希表,其守护进程是用C编写的,但是客户端可以用任何语言来编写,并通过Memcached协议与守护进程通信。
1.Memcached的简介
Memcached是免费、开源、高性能、分布式的内存对象缓存系统,通用性强,主要用于减轻数据库负载,加快动态Web应用程序。
Memcached是基于内存的key-value模型,可以用于存储来自数据库调用、API调用或网页渲染后的任意小块数据(字符串、对象)。
Memcached是简单而强大的。其简单的设计加强了快速部署,易于开发,解决了大量数据高速缓存的很多问题。它的API可用于最流行的语言。Memcached最初是由Brad Fitzpatrick在2003年为LiveJournal所开发的,今天它已经广泛用于LiveJournal等各大网站,成为大规模互联网架构的重要组成部分。
Memcached作为高速运行的分布式缓存服务器,具有以下特点。
·协议简单。
·基于libevent的事件处理。
·内置内存存储方式。
·Memcached不互相通信的分布式。
Memcached主要由以下4个部分组成。
·客户端软件:能够获取可用的Memcached服务器的列表。
·基于客户端的散列算法:它会根据“key”来选择服务器。
·服务器软件:存储key-value到内部哈希表。·最近最少使用算法(Least Recently Used,LRU):决定何时要清除掉旧数据(如果内存不足的话),或重复使用内存。
2.Memcached的架构
Memcached拥有非常精简的架构设计理念,它可以按需来更好地利用内存。为了方便理解其工作原理,我们举个例子,假设我们有两个部署方案,如图14-2所示。
·图14-2上方所示的部署方案(非Memcached方案)中的每个节点是完全独立的。
·图14-2下方所示的部署方案(Memcached方案)中的每个节点可以利用来自其他节点的内存。
图14-2上方所示的方案是比较常见的部署策略,但是你会发现,它在某种意义上是一种浪费,因为,所需缓存的总量只是Web应用的实际容量的一小部分,而且还需要努力保持所有这些节点上的缓存是一致的。
图14-2 Memcached的工作原理
而在图14-2下方所示的Memcached方案中可以看到,所有的服务器都在使用相同的虚拟内存池。这意味着在整个集群里面,同一个数据总是从相同的位置中存储和检索的。
此外,Memcached方案也能适应应用程序数据不断增长的需求。在这个示例中,虽然只是简单地用两台Web服务器作为演示,但如果有50台Web服务器,在图14-2上方所示的方案中,仍然只能使用到64MB的可用缓存,但在Memcached方案中,却能使用到3.2GB的可用缓存。
当然,在实际应用中,一般不会将Web服务器作为缓存。许多用户都会在使用Memcached时,搭建专门的Memcached服务器作为缓存。
Memcached主要包括以下核心设计理念。
·简单的key-value存储:Memcached服务器并不关心数据是什么样子。数据由一个key、过期时间、可选的标志以及原始数据组成。无须关心数据结构的问题,只需要按预先的序列上传数据。可以使用某些命令(incr/decr)来实现以简单的方式对基础数据进行操作。
·逻辑一半在客户端,一半在服务器:Memcached的实现,一部分在客户端,另一部分在服务器。用户知道如何选择所要读取或写入的服务器,如何在无法连接到服务器时做出反应。这些服务器知道如何存储和获取数据。它们还管理着可以被清除或重用的内存。
·各个服务器之间是无连接的:Memcached服务器之间并不知道对方的存在,它们之间不会有回应,不会同步数据,不会广播消息,也不会互相复制数据。添加服务器就能够增加可用的存储,简化了缓存失效机制,由客户端来直接删除或覆盖它在服务器上所拥有的数据。
·O(1):所有的命令都被设计为尽可能快和对锁友好。这提高了所有用例的确定性查询的速度。在慢的机器中应在1ms内能够执行完查询。高端服务器可以拥有每秒百万次的吞吐量。·“遗忘”功能:Memcached在默认情况下,采用了“Least RecentlyUsed(最近最少使用)”的缓存机制,数据会在指定时间后过期。这两者都是很多问题的“优雅”的解决方案,既限制了陈旧未使用的数据,也能保证缓存了经常使用的数据。垃圾回收器无须“pauses(暂停)”等待,以确保低延迟和懒加载空闲的空间。
·缓存失效:无须广播服务器的变化到所有可用的主机上,作为替代者,客户端可以直接解决服务器保存的数据失效的问题。
Redis是一个key-value模型的内存数据存储系统。和Memcached类似,但它支持存储的value类型相对更多,包括支持string(字符串)、hash(哈希类型)list(链表)、set(集合)和sorted set(有序集合)的range query(范围查询),以及位图、hyperloglogs、空间索引等的radius query(半径查询)。内置复制、Lua脚本、LRU回收、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。Redis是完全开源免费的、遵守BSD的协议。
Redis是一个高性能的key-value数据库。Redis的出现,很大程度弥补了Memcached这类key-value存储的不足,在部分场合可以对关系型数据库起到很好的补充作用。它提供了ActionScript、Bash、C、C#、C++、Clojure、Common Lisp、Crystal、D、Dart、Delphi、Elixir、emacs lisp、Erlang、Fancy、gawk、GNU Prolog、Go、Haskell、Haxe、Io、Java、Julia、Lasso、Lua、Matlab、mruby、Nim、Node.js、Objective-C、OCaml、Pascal、Perl、PHP、Pure Data、Python、R、Racket、Rebol、Ruby、Rust、Scala、Scheme、Smalltalk、Swift、Tcl、VB、VCL等众多客户端,使用很方便。Redis支持主从同步。可以从主服务器向任意数量的从服务器上同步数据,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制,内存可以有意无意地对数据进行写操作。由于完全实现了发布/订阅机制,从数据库在任何地方进行数据同步时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
用户可以在Redis数据类型上执行原子操作,比如,追加字符串,增加哈希表中的某个值,在列表中增加一个元素,计算集合的交集、并集或差集,获取一个有序集合中最大排名的元素,等等。
为了获取其卓越的性能,Redis在内存数据集合上工作。是否工作在内存这取决于用户,如果用户想持久化其数据,可以通过偶尔转储内存数据集到磁盘上或在一个日志文件中写入每条操作命令来实现。如果用户仅需要一个内存数据库,那么持久化操作可以被选择性禁用。
Redis是用ANSI C编写的,在大多数POSIX系统中工作——如Linux、*BSD、OS X等——而无须添加其他额外的依赖。Linux和OS X系统是Redis的开发和测试最常用的两个操作系统,所以建议使用Linux来部署Redis。Redis可以工作在像SmartOS那样的Solaris派生的系统上,但支持是有限的。官方没有对Windows构建的支持,但Microsoft开发和维护了Redis的Win-64的接口。
Redis具有以下特点。
·事务。
·发布/订阅。
·Lua脚本。
·key有生命时间限制。
·按照LRU机制来清除旧数据。
·自动故障转移。
与Redis或者HBase等不同,MongoDB是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富、最像关系型数据库的,旨在为Web应用提供可扩展的高性能数据存储解决方案。它支持的数据结构非常松散,是类似JSON的BSON格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是其支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系型数据库表单查询的绝大部分功能,而且还支持对数据建立索引。
MongoDB Server是用C++编写的、开源的、面向文档的数据库(Document Database),它的特点是高性能、高可用性,以及可以实现自动化扩展,存储数据非常方便。其主要功能特性如下。
·MongoDB将数据存储为一个文档,数据结构由field-value(字段-值)对组成。
·MongoDB文档类似于JSON对象,字段的值可以包含其他文档、数组及文档数组。
MongoDB的文档结构如图14-3所示。
图14-3 MongoDB的文档结构
使用文档的优点有以下3点。
·文档(即对象)在许多编程语言里可以对应于原生数据类型。
·嵌入式文档和数组可以减少昂贵的连接操作。
·动态模式支持流畅的多态性。
MongoDB的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性如下所述。
1.高性能
MongoDB中提供了以下高性能的数据持久化。
·对于嵌入式数据模型的支持,减少了数据库系统的I/O活动。
·支持索引,用于快速查询。其索引对象可以是嵌入文档或数组的key。
2.丰富的查询语言
MongoDB支持以下查询语言。
·读取和写入。
·数据聚合。
·文本搜索和地理空间查询。
3.高可用
MongoDB的复制设备被称为replica set,提供了以下功能。
·自动故障转移。
·数据冗余。
replica set是一组保存相同数据集合的MongoDB服务器,提供了数据冗余并增强了数据的可用性。
4.横向扩展
MongoDB提供水平横向扩展并作为其核心功能部分。
·将数据分片到一组计算机集群上。
·标签意识分片(Tag Aware Sharding)允许将数据传到特定的碎片,比如在分片时考虑碎片的地理分布。
5.支持多个存储引擎
MongoDB支持以下存储引擎。
·WiredTiger Storage Engine。
·MMAPv1 Storage Engine。
此外,MongoDB中提供插件式存储引擎的API,允许第三方来开发MongoDB的存储引擎。
资源获取:
大家 点赞、收藏、关注、评论啦 、 查看 微信公众号获取联系方式
精彩专栏推荐订阅:在 下方专栏
每天学四小时:Java+Spring+JVM+分布式高并发,架构师指日可待