收藏 分销(赏)

NoSQL架构实践.doc

上传人:二*** 文档编号:4766104 上传时间:2024-10-12 格式:DOC 页数:31 大小:324KB 下载积分:5 金币
下载 相关 举报
NoSQL架构实践.doc_第1页
第1页 / 共31页
本文档共31页,全文阅读请下载到手机保存,查看更方便
资源描述
NoSQL开篇——为什么要使用NoSQL 【编者按】NoSQL在2010年风生水起,大大小小的Web站点在追求高性能高可靠性方面,不由自主都选择了NoSQL技术作为优先考虑的方面。今年伊始,InfoQ中文站有幸邀请到凤凰网的孙立先生,为大家分享他之于NoSQL方面的经验和体会。 非常荣幸能受邀在InfoQ开辟这样一个关于NoSQL的专栏,InfoQ是我非常尊重的一家技术媒体,同时我也希望借助InfoQ,在国内推动 NoSQL的发展,希望跟我一样有兴趣的朋友加入进来。这次的NoSQL专栏系列将先整体介绍NoSQL,然后介绍如何把NoSQL运用到自己的项目中合 适的场景中,还会适当地分析一些成功案例,希望有成功使用NoSQL经验的朋友给我提供一些线索和信息。 NoSQL概念 随着web2.0的快速发展,非关系型、分布式数据存储得到了快速的发展,它们不保证关系数据的ACID特性。NoSQL概念在2009年被提了出来。NoSQL最常见的解释是“non-relational”,“Not Only SQL”也被很多人接受。(“NoSQL”一词最早于1998年被用于一个轻量级的关系数据库的名字。) NoSQL被我们用得最多的当数key-value存储,当然还有其他的文档型的、列存储、图型数据库、xml数据库等。在NoSQL概念提出之前,这些数据库就被用于各种系统当中,但是却很少用于web互联网应用。比如cdb、qdbm、bdb数据库。 传统关系数据库的瓶颈 传统的关系数据库具有不错的性能,高稳定型,久经历史考验,而且使用简单,功能强大,同时也积累了大量的成功案例。在互联网领域,MySQL成为了绝对靠前的王者,毫不夸张的说,MySQL为互联网的发展做出了卓越的贡献。 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付。在那个时候,更多的都是静态网页,动态交互类型的网站不多。 到了最近10年,网站开始快速发展。火爆的论坛、博客、sns、微博逐渐引领web领域的潮流。在初期,论坛的流量其实也不大,如果你接触网络比较早,你可能还记得那个时候还有文本型存储的论坛程序,可以想象一般的论坛的流量有多大。 Memcached+MySQL 后来,随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性 能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。开始比较流行的是通过文件缓存来缓解数据库压力,但是当访问量继续增大 的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带了了比较高的IO压力。在这个时候,Memcached就自然的成为一个非常时尚的技 术产品。 Memcached作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展 了根据hash算法来进行多台Memcached缓存服务的扩展,然后又出现了一致性hash来解决增加或减少缓存服务器导致重新hash带来的大量缓存 失效的弊端。当时,如果你去面试,你说你有Memcached经验,肯定会加分的。 Mysql主从读写分离 由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了。 分表分库 随着web2.0的继续高速发展,在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出 现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替 MyISAM。同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题。这个时候,分表分库成了一个热门技术,是面试的热门问题也是业界讨论的热门 技术问题。也就在这个时候,MySQL推出了还不太稳定的表分区,这也给技术实力一般的公司带来了希望。虽然MySQL推出了MySQL Cluster集群,但是由于在互联网几乎没有成功案例,性能也不能满足互联网的要求,只是在高可靠性上提供了非常大的保证。 MySQL的扩展性瓶颈 在互联网,大部分的MySQL都应该是IO密集型的,事实上,如果你的MySQL是个CPU密集型的话,那么很可能你的MySQL设计得有性能问 题,需要优化了。大数据量高并发环境下的MySQL应用开发越来越复杂,也越来越具有技术挑战性。分表分库的规则把握都是需要经验的。虽然有像淘宝这样技 术实力强大的公司开发了透明的中间件层来屏蔽开发者的复杂性,但是避免不了整个架构的复杂性。分库分表的子库到一定阶段又面临扩展问题。还有就是需求的变 更,可能又需要一种新的分库方式。 MySQL数据库也经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库。比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,MySQL将变得非常的小。 关系数据库很强大,但是它并不能很好的应付所有的应用场景。MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。 NOSQL的优势 易扩展 NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。 大数据量,高性能 NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用 Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的 Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了。 灵活的数据模型 NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的web2.0时代尤其明显。 高可用 NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。 总结 NoSQL数据库的出现,弥补了关系数据(比如MySQL)在某些方面的不足,在某些方面能极大的节省开发成本和维护成本。 MySQL和NoSQL都有各自的特点和使用的应用场景,两者的紧密结合将会给web2.0的数据库发展带来新的思路。让关系数据库关注在关系上,NoSQL关注在存储上。 参考阅读 1. NoSQL:http://nosql-database.org/ 2. NoSQL在wiki上的介绍:http://en.wikipedia.org/wiki/NoSQL 3. NoSQL相关博客: 4. NoSQL相关博客: 5. 新浪微博NoSQL微群: 关于作者 孙立,目前在凤凰网负责底层组的研发工作。曾就职于搜狐和ku6。多年互联网从业经验和程序开发,对分布式搜索引擎的开发,高并发,大数据量网站系 统架构优化,高可用性,可伸缩性,分布式系统缓存,数据库分表分库(sharding)等有丰富的经验,并且对运维监控和自动化运维控制有经验。开源项目 phplock,phpbuffer的作者。近期开发了一个NOSQL数据库存储INetDB,是NoSQL数据库爱好者。他的新浪微博是: 关系数据库还是NoSQL数据库 上一篇简单的说明了为什么要使用NoSQL。接下来我们看下如何把NoSQL引入到我们的项目中,我们到底要不要把NoSQL引入到项目中。 在过去,我们只需要学习和使用一种数据库技术,就能做几乎所有的数据库应用开发。因为成熟稳定的关系数据库产品并不是很多,而供你选择的免费版本就 更加少了,所以互联网领域基本上都选择了免费的MySQL数据库。在高速发展的WEB2.0时代,我们发现关系数据库在性能、扩展性、数据的快速备份和恢 复、满足需求的易用性上并不总是能很好的满足我们的需要,我们越来越趋向于根据业务场景选择合适的数据库,以及进行多种数据库的融合运用。几年前的一篇文 章《One Size Fits All - An Idea Whose Time Has Come and Gone》就已经阐述了这个观点。 当我们在讨论是否要使用NoSQL的时候,你还需要理解NoSQL也是分很多种类的,在NoSQL百花齐放的今天,NoSQL的正确选择比选择关系数据库还具有挑战性。虽然NoSQL的使用很简单,但是选择却是个麻烦事,这也正是很多人在观望的一个原因。 NoSQL的分类 NoSQL仅仅是一个概念,NoSQL数据库根据数据的存储模型和特点分为很多种类。 类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 文档存储 MongoDB CouchDB 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。 key-value存储 Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能) 图存储 Neo4J FlockDB 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 对象存储 db4o Versant 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 xml数据库 Berkeley DB XML BaseX 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。 以上NoSQL数据库类型的划分并不是绝对,只是从存储模型上来进行的大体划分。它们之间没有绝对的分界,也有交差的情况,比如Tokyo Cabinet / Tyrant的Table类型存储,就可以理解为是文档型存储,Berkeley DB XML数据库是基于Berkeley DB之上开发的。 NoSQL还是关系数据库 虽然09年出现了比较激进的文章《关系数据库已死》,但是我们心里都清楚,关系数据库其实还活得好好的,你还不能不用关系数据库。但是也说明了一个事实,关系数据库在处理WEB2.0数据的时候,的确已经出现了瓶颈。 那么我们到底是用NoSQL还是关系数据库呢?我想我们没有必要来进行一个绝对的回答。我们需要根据我们的应用场景来决定我们到底用什么。 如果关系数据库在你的应用场景中,完全能够很好的工作,而你又是非常善于使用和维护关系数据库的,那么我觉得你完全没有必要迁移到NoSQL上面, 除非你是个喜欢折腾的人。如果你是在金融,电信等以数据为王的关键领域,目前使用的是Oracle数据库来提供高可靠性的,除非遇到特别大的瓶颈,不然也 别贸然尝试NoSQL。 然而,在WEB2.0的网站中,关系数据库大部分都出现了瓶颈。在磁盘IO、数据库可扩展上都花费了开发人员相当多的精力来优化,比如做分表分库 (database sharding)、主从复制、异构复制等等,然而,这些工作需要的技术能力越来越高,也越来越具有挑战性。如果你正在经历这些场合,那么我觉得你应该尝 试一下NoSQL了。 选择合适的NoSQL 如此多类型的NoSQL,而每种类型的NoSQL又有很多,到底选择什么类型的NoSQL来作为我们的存储呢?这并不是一个很好回答的问题,影响我们选择的因素有很多,而选择也可能有多种,随着业务场景,需求的变更可能选择又会变化。我们常常需要根据如下情况考虑: 1. 数据结构特点。包括结构化、半结构化、字段是否可能变更、是否有大文本字段、数据字段是否可能变化。 2. 写入特点。包括insert比例、update比例、是否经常更新数据的某一个小字段、原子更新需求。 3. 查询特点。包括查询的条件、查询热点的范围。比如用户信息的查询,可能就是随机的,而新闻的查询就是按照时间,越新的越频繁。 NoSQL和关系数据库结合 其实NoSQL数据库仅仅是关系数据库在某些方面(性能,扩展)的一个弥补,单从功能上讲,NoSQL的几乎所有的功能,在关系数据库上都能够满足,所以选择NoSQL的原因并不在功能上。 所以,我们一般会把NoSQL和关系数据库进行结合使用,各取所长,需要使用关系特性的时候我们使用关系数据库,需要使用NoSQL特性的时候我们使用NoSQL数据库,各得其所。 举个简单的例子吧,比如用户评论的存储,评论大概有主键id、评论的对象aid、评论内容content、用户uid等字段。我们能确定的是评论内 容content肯定不会在数据库中用where content=’’查询,评论内容也是一个大文本字段。那么我们可以把 主键id、评论对象aid、用户id存储在数据库,评论内容存储在NoSQL,这样数据库就节省了存储content占用的磁盘空间,从而节省大量IO, 对content也更容易做Cache。 //从MySQL中查询出评论主键id列表 commentIds=DB.query("SELECT id FROM comments where aid='评论对象id' LIMIT 0,20"); //根据主键id列表,从NoSQL取回评论实体数据 CommentsList=NoSQL.get(commentIds); NoSQL代替MySQL 在某些应用场合,比如一些配置的关系键值映射存储、用户名和密码的存储、Session会话存储等等,用NoSQL完全可以替代MySQL存储。不但具有更高的性能,而且开发也更加方便。 NoSQL作为缓存服务器 MySQL+Memcached的架构中,我们处处都要精心设计我们的缓存,包括过期时间的设计、缓存的实时性设计、缓存内存大小评估、缓存命中率等等。 NoSQL数据库一般都具有非常高的性能,在大多数场景下面,你不必再考虑在代码层为NoSQL构建一层Memcached缓存。NoSQL数据本身在Cache上已经做了相当多的优化工作。 Memcached这类内存缓存服务器缓存的数据大小受限于内存大小,如果用NoSQL来代替Memcached来缓存数据库的话,就可以不再受限于内存大小。虽然可能有少量的磁盘IO读写,可能比Memcached慢一点,但是完全可以用来缓存数据库的查询操作。 规避风险 由于NoSQL是一个比较新的东西,特别是我们选择的NoSQL数据库还不是非常成熟的产品,所以我们可能会遇到未知的风险。为了得到NoSQL的好处,又要考虑规避风险,鱼与熊掌如何兼得? 现在业内很多公司的做法就是数据的备份。在往NoSQL里面存储数据的时候还会往MySQL里面存储一份。NoSQL数据库本身也需要进行备份(冷 备和热备)。或者可以考虑使用两种NoSQL数据库,出现问题后可以进行切换(避免出现digg使用Cassandra的悲剧)。 总结 本文只是简单的从MySQL和NoSQL的角度分析如何选择,以及进行融合使用。其实在选择NoSQL的时候,你可能还会碰到关于CAP原则,最终一致性,BASE思想的考虑。因为使用MySQL架构的时候,你也会碰到上面的问题,所以这里没有阐述。 NoSQL架构实践—以NoSQL为辅 前面《为什么要使用NoSQL》和《关系数据库还是NoSQL数据库》两 篇从大体上介绍了为什么要用NoSQL,何时该用NoSQL。经常有朋友遇到困惑,看到NoSQL的介绍,觉得很好,但是却不知道如何正式用到自己的项目 中。很大的原因就是思维固定在MySQL中了,他们问得最多的问题就是用了NoSQL,我如何做关系查询。那么接下来,我们看下怎么样在我们的系统中使用 NoSQL。 怎么样把NoSQL引入到我们的系统架构设计中,需要根据我们系统的业务场景来分析,什么样类型的数据适合存储在NoSQL数据库中,什么样类型的 数据必须使用关系数据库存储。明确引入的NoSQL数据库带给系统的作用,它能解决什么问题,以及可能带来的新的问题。下面我们分析几种常见的NoSQL 架构。 (一)NoSQL作为镜像 不改变原有的以MySQL作为存储的架构,使用NoSQL作为辅助镜像存储,用NoSQL的优势辅助提升性能。 图 1 -NoSQL为镜像(代码完成模式 ) //写入数据的示例伪代码 //data为我们要存储的数据对象 data.title=”title”; data.name=”name”; data.time=”2009-12-01 10:10:01”; data.from=”1”; id=DB.Insert(data);//写入MySQL数据库 NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库 如果有数据一致性要求,可以像如下的方式使用 //写入数据的示例伪代码 //data为我们要存储的数据对象 bool status=false; DB.startTransaction();//开始事务 id=DB.Insert(data);//写入MySQL数据库 if(id>0){ status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库 } if(id>0 && status==true){ DB.commit();//提交事务 }else{ DB.rollback();//不成功,进行回滚 } 上面的代码看起来可能觉得有点麻烦,但是只需要在DB类或者ORM层做一个统一的封装,就能实现重用了,其他代码都不用做任何的修改。 这种架构在原有基于MySQL数据库的架构上增加了一层辅助的NoSQL存储,代码量不大,技术难度小,却在可扩展性和性能上起到了非常大的作用。 只需要程序在写入MySQL数据库后,同时写入到NoSQL数据库,让MySQL和NoSQL拥有相同的镜像数据,在某些可以根据主键查询的地方,使用高 效的NoSQL数据库查询,这样就节省了MySQL的查询,用NoSQL的高性能来抵挡这些查询。 图 2 -NoSQL为镜像(同步模式) 这种不通过程序代码,而是通过MySQL把数据同步到NoSQL中,这种模式是上面一种的变体,是一种对写入透明但是具有更高技术难度一种模式。这 种模式适用于现有的比较复杂的老系统,通过修改代码不易实现,可能引起新的问题。同时也适用于需要把数据同步到多种类型的存储中。 MySQL到NoSQL同步的实现可以使用MySQL UDF函数,MySQL binlog的解析来实现。可以利用现有的开源项目来实现,比如: · MySQL memcached UDFs:从通过UDF操作Memcached协议。 · 国内张宴开源的mysql-udf-http:通过UDF操作http协议。 有了这两个MySQL UDF函数库,我们就能通过MySQL透明的处理Memcached或者Http协议,这样只要有兼容Memcached或者Http协议的NoSQL数据库,那么我们就能通过MySQL去操作以进行同步数据。再结合lib_mysqludf_json,通过UDF和MySQL触发器功能的结合,就可以实现数据的自动同步。 (二)MySQL和NoSQL组合 MySQL中只存储需要查询的小字段,NoSQL存储所有数据。 图 3 -MySQL和NoSQL组合 //写入数据的示例伪代码 //data为我们要存储的数据对象 data.title=”title”; data.name=”name”; data.time=”2009-12-01 10:10:01”; data.from=”1”; bool status=false; DB.startTransaction();//开始事务 id=DB.Insert(“INSERT INTO table (from) VALUES(data.from)”);//写入MySQL数据库,只写from需要where查询的字段 if(id>0){ status=NoSQL.Add(id,data);//以写入MySQL产生的自增id为主键写入NoSQL数据库 } if(id>0 && status==true){ DB.commit();//提交事务 }else{ DB.rollback();//不成功,进行回滚 } 把需要查询的字段,一般都是数字,时间等类型的小字段存储于MySQL中,根据查询建立相应的索引,其他不需要的字段,包括大文本字段都存储在NoSQL中。在查询的时候,我们先从MySQL中查询出数据的主键,然后从NoSQL中直接取出对应的数据即可。 这种架构模式把MySQL和NoSQL的作用进行了融合,各司其职,让MySQL专门负责处理擅长的关系存储,NoSQL作为数据的存储。它有以下优点: · 节省MySQL的IO开销。由于MySQL只存储需要查询的小字段,不再负责存储大文本字段,这样就可以节省MySQL存储的空间开销,从而节省MySQL的磁盘IO。我们曾经通过这种优化,把MySQL一个40G的表缩减到几百M。 · 提高MySQl Query Cache缓存命中率。我们知道query cache缓存失效是表级的,在MySQL表一旦被更新就会失效,经过这种字段的分离,更新的字段如果不是存储在MySQL中,那么对query cache就没有任何影响。而NoSQL的Cache往往都是行级别的,只对更新的记录的缓存失效。 · 提升MySQL主从同步效率。由于MySQL存储空间的减小,同步的数据记录也减小了,而部分数据的更新落在NoSQL而不是MySQL,这样也减少了MySQL数据需要同步的次数。 · 提高MySQL数据备份和恢复的速度。由于MySQL数据库存储的数据的减小,很容易看到数据备份和恢复的速度也将极大的提高。 · 比以前更容易扩展。NoSQL天生就容易扩展。经过这种优化,MySQL性能也得到提高。 比如手机凤凰网就是这种架构 总结 以NoSQL为辅的架构还是以MySQL架构的思想为中心,只是在以前的架构上辅助增加了NoSQL来提高其性能和可扩展性。这种架构实现起来比较 容易,却能取得不错的效果。如果正想在项目中引入NoSQL,或者你的以MySQL架构的系统目前正出现相关的瓶颈,希望本文可以为你带来帮助。 NoSQL架构实践—以NoSQL为主 前面一篇《NoSQL架构实践—以NoSQL为辅》主要介绍了以NoSQL为辅助的架构,这种架构实施起来比较简单,易于理解,由于其中也使用了传统的关系数据库,让开发者更容易控制NoSQL带来的风险。接下来我们继续深入下去,换另外一个角度,“以NoSQL为主”来架构系统。 (三)纯NoSQL架构 只使用NoSQL作为数据存储。 图 4-纯NoSQL架构 在一些数据结构、查询关系非常简单的系统中,我们可以只使用NoSQL即可以解决存储问题。这样不但可以提高性能,还非常易于扩展。手机凤凰网的前端展示系统就使用了这种方案。 在一些数据库结构经常变化,数据结构不定的系统中,就非常适合使用NoSQL来存储。比如监控系统中的监控信息的存储,可能每种类型的监控信息都不太一样。这样可以避免经常对MySQL进行表结构调整,增加字段带来的性能问题。 这种架构的缺点就是数据直接存储在NoSQL中,不能做关系数据库的复杂查询,如果由于需求变更,需要进行某些查询,可能无法满足,所以采用这种架构的时候需要确认未来是否会进行复杂关系查询以及如何应对。 非常幸运的是,有些NoSQL数据库已经具有部分关系数据库的关系查询特性,他们的功能介于key-value和关系数据库之间,却具有key-value数据库的性能,基本能满足绝大部分web 2.0网站的查询需求。比如: MongoDB就带有关系查询的功能,能解决常用的关系查询,所以也是一种非常不错的选择。下面是一些MongoDB的资料: · 《视觉中国的NoSQL之路:从MySQL到MongoDB》 · 《Choosing a non-relational database; why we migrated from MySQL to MongoDB》 · 最近的一次Mongo Beijing 开发者聚会也有一部分资料。 虽然Foursquare使用MongoDB的宕机事件的出现使人对MongoDB的自动Shard提出了质疑,但是毫无疑问,MongoDB在NoSQL中,是一个优秀的数据库,其单机性能和功能确实是非常吸引人的。由于上面的例子有详细的介绍,本文就不做MongoDB的使用介绍。 Tokyo Tyrant数据库带有一个名为table的存储类型,可以对存储的数据进行关系查询和检索。一个table库类似于MySQL中的一个表。下面我们看一个小演示: 我们要存储一批用户信息,用户信息包含用户名(name),年龄(age),email,最后访问时间(lastvisit),地区(area)。下面为写入的演示代码: <?php $tt = new TokyoTyrantTable ( "127.0.0.1", 1978 ); $tt->vanish ();//清空 $id = $tt->genUid ();//获取一个自增id //put方法提供数据写入。 put ( string $key , array $columns ); $tt->put ( $id, array ("id" => $id, "name" => "zhangsan", "age" => 27, "email" => "zhangsan@", "lastvisit" =>strtotime ( "2011-3-5 12:30:00" ), "area" => "北京" ) ); $id = $tt->genUid (); $tt->put ( $id, array ("id" => $id, "name" => "lisi", "age" => 25, "email" => "lisi@", "lastvisit" => strtotime( "2011-3-3 14:40:44" ), "area" => "北京" ) ); $id = $tt->genUid (); $tt->put ( $id, array ("id" => $id, "name" => "laowang", "age" => 37, "email" => "laowang@", "lastvisit" =>strtotime ( "2011-3-5 08:30:12" ), "area" => "成都" ) ); $id = $tt->genUid (); $tt->put ( $id, array ("id" => $id, "name" => "tom", "age" => 21, "email" => "tom@", "lastvisit" =>strtotime ( "2010-12-10 13:12:13" ), "area" => "天津" ) ); $id = $tt->genUid (); $tt->put ( $id, array ("id" => $id, "name" => "jack", "age" => 21, "email" => "jack@", "lastvisit" =>strtotime ( "2011-02-24 20:12:55" ), "area" => "天津" ) ); //循环打印数据库的所有数据库 $it = $tt->getIterator (); foreach ( $it as $k => $v ) { print_r ( $v ); } ?> 比如我们需要查询年龄为21岁的所有用户: <?php $tt = new TokyoTyrantTable ( "127.0.0.1", 1978 ); $query = $tt->getQuery (); //查询年龄为21岁的用户 $query->addCond ( “age”, TokyoTyrant::RDBQC_NUMEQ, “21” ); print_r ( $query->search () ); ?> 查询所有在2011年3月5日之后登陆的用户: <?php $tt = new TokyoTyrantTable ( "127.0.0.1", 1978 ); $query = $tt->getQuery (); $query->addCond ( “lastvisit”, TokyoTyrant::RDBQC_NUMGE, strtotime ( "2011-3-5 00:00:00" ) ); print_r ( $query->search () ); ?> 从上面的示例代码可以看出,使用起来是非常简单的,甚至比SQL语句还要简单。Tokyo Tyrant的表类型存储还提供了给字段建立普通索引和倒排全文索引,大大增强了其检索功能和检索的性能。 所以,完全用NoSQL来构建部分系统,是完全可能的。配合部分带有关系查询功能的NoSQL,在开发上比MySQL数据库更加快速和高效。 (四)以NoSQL为数据源的架构 数据直接写入NoSQL,再通过NoSQL同步协议复制到其他存储。根据应用的逻辑来决定去相应的存储获取数据。 图 5 -以NoSQL为数据源 纯NoSQL的架构虽然结构简单,易于开发,但是在应付需求的变更、稳定性和可靠性上,总是给开发人员一种风险难于控制的感觉。为了降低风险,系统的功能不局限在NoSQL的简单功能上,我们可以使用以NoSQL为数据源的架构。 在这种架构中,应用程序只负责把数据直接写入到NoSQL数据库就OK,然后通过NoSQL的复制协议,把NoSQL数据的每次写入,更新,删除操 作都复制到MySQL数据库中。同 时,也可以通过复制协议把数据同步复制到全文检索实现强大的检索功能。在海量数据下面,我们也可以根据不同的规则,把数据同步复制到设计好的分表分库的 MySQL中。这种架构: · 非常灵活。可以非常方便的在线上系统运行过程中进行数据的调整,比如调整分库分表的规则、要添加一种新的存储类型等等。 · 操作简单。只需要写入NoSQL数据库源,应用程序就不用管了。需要增加存储类型或者调整存储规则的时候,只需要增加同步的数据存储,调整同步规则即可,无需更改应用程序的代码。 · 性能高。数据的写入和更新直接操作NoSQL,实现了写的高性能。而通过同步协议,把数据复制到各种适合查询类型的存储中(按照业务逻辑 区分不同的存储),能实现查询的高性能,不像以前MySQL一种数据库就全包了。或者就一个表负责跟这个表相关的所有的查询,现在可以把一个表的数据复制 到各种存储,让各种存储用自己的长处来对外服务。 · 易扩展。开发人员只需要关心写入NoSQL数据库。数据的扩展可以方便的在后端由复制协议根据规则来完成。 这种架构需要考虑数据复制的延迟问题,这跟使用MySQL的master-salve模式的延迟问题是一样的,解决方法也一样。 在这种以NoSQL为数据源的架构中,最核心的就是NoSQL数据库的复制功能的实现。而当前的几乎所有的NoSQL都没有提供比较易于使用的复制 接口来完成这种架构,对NoSQL进行复制协议的二次开发,需要更高的技术水平,所以这种架构看起来很好,但是却不是非常容易实现的。我的开源项目PHPBuffer中有个实现TokyoTyrant复制的例子,虽然是PHP版本的,但是很容易就可以翻译成其他语言。通过这个例子的代码,可以实现从Tokyo Tyrant实时的复制数据到其他系统中。 总结 以NoSQL为主的架构应该算是对NoSQL的一种深度应用,整个系统的架构以及代码都不是很复杂,但是却需要一定的NoSQL使用经验才行。 参考链接: · 新浪微博NoSQL微群: · 我的新浪微博: · Tokyo Cabinet官方站点: NoSQL架构实践—以NoSQL为缓存 在《NoSQL架构实践》系列的前面两篇文章中,介绍了《以NoSQL为主》和《以NoSQL为辅》的架构。由于NoSQL数据库天生具有高性能、易扩展的特点,所以我们常常结合关系数据库,存储一些高性能的、海量的数据。从另外一个角度看,根据NoSQL的高性能特点,它同样适合用于缓存数据。用NoSQL缓存数据可以分为内存模式和磁盘持久化模式。 内存模式 说起内存模式缓存,我们自然就会想起大名鼎鼎的Memcached。在互联网发展过程中,Memcached曾经解救了数据库的大部分压力,做出了巨大的贡献,直到今天,它依然是缓存服务器的首选。Memcached的常见使用方式类似下面的代码: Memcached提供了相当高的读写性能,一般情况下,都足够应付应用的性能要求。但是基于内存的Memcached缓存的总数据大小受限于内存的大小。 当前如日中天、讨论得异常火热的NoSQL数据库Redis又为我们提供了功能更 加强大的内存存储功能。跟Memcached比,Redis的一个key的可以存储多种数据结构Strings、Hashes、Lists、Sets、 Sorted sets。Redis不但功能强大,而且它的性能完全超越大名鼎鼎的Memcached。Redis支持List、hashes等多种数据结构的功能,提 供了更加易于使用的api和操作性能,比如对缓存的list数据的修改。 同样,其他一些NoSQL数据库也提供了内存存储的功能,所以也适合用来做内存缓存。比如Tokyo Tyrant就提供了内存hash数据库、内存tree数据库功能,内存tree数据可根据key的顺序进行遍历。你可以通过使用其提供的兼容Memcached协议或自定义的协议来使用。 持久化模式 虽然基于内存的缓存服务器具有高性能,低延迟的特点,但是内存成
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服