从上面的示例代码可以看出,使用起来是非常简单的,甚至比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实时的复制数据到其他系统中。
内存模式
说起内存模式缓存,我们自然就会想起大名鼎鼎的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协议或自定义的协议来使用。
持久化模式
虽然基于内存的缓存服务器具有高性能,低延迟的特点,但是内存成本高、内存数据易失却不容忽视。几十GB内存的服务器,在很多公司看来,还比较奢侈。所以,我们应该根据应用的特点,尽量的提高内存的利用率,降低成本。
大部分互联网应用的特点都是数据访问有热点,也就是说,只有一部分数据是被频繁访问的。如果全部都cache到内存中,无疑是对内存的浪费。
这时,我们可以利用NoSQL来做数据的缓存。其实NoSQL数据库内部也是通过内存缓存来提高性能的,通过一些比较好的算法,把热点数据进行内存cache,非热点数据存储到磁盘以节省内存占用。由于其数据库结构的简单,从磁盘获取一次数 据也比从数据库一次耗时的查询划算很多。用NoSQL数据库做缓存服务器不但具有不错的性能。而且还能够Cache比内存大的数据。
使用NoSQL来做缓存,由于其不受内存大小的限制,我们可以把一些不常访问、不怎么更新的数据也缓存起来。比如论坛、新闻的老数据、数据列表的靠后的页面,虽然用户访问不多,但是搜索引擎爬虫会访问,也可能导致系统负载上升。
如果NoSQL持久化缓存也使用类似基于内存的memcached设置过期时间的方式,那么持久化缓存就失去了意义。所以用NoSQL做缓存的过期策略最好不使用时间过期,而是数据是否被更新过,如果数据没有更新,那么就永久不过期。下面我们用代码(php)演示一种实现这种策略的方法:
场景:新闻站点的评论系统。用户对新闻页面的url进行评论,然后根据url进行查询展示。
我把上面代码演示的缓存使用方式称为基于版本的缓存。这种方式同样适用于基于内存的Memcached。它能实现缓存数据的实时性,让用户感觉不到延迟。只要用户一发表评论,该新闻的评论缓存就会失效。用户很少去评论一些过时的新闻,那么缓存就一直存在于NoSQL中,避免了爬虫访问过时新闻的评论数据而冲击数据库。
总结
目前国内的新浪微博已经在大量的使用Redis缓存数据,赶集网也在大量的使用Redis。Redis作为一些List,Hashes等数据结构的缓存,非常适合。
把NoSQL当持久化Cache使用的模式,在很多大数据量、有热点、查询非热点数据比较消耗资源的场景下比较有用。
NoSQL架构实践总结
到这里,关于NoSQL架构实践的三篇文章就结束了。NoSQL架构并不局限于我介绍的三种模式,他们之间也可以进行组合,应该根据你具体的应用场景灵活使用。不管是什么模式,都是为了解决我们的问题而出现的,所以在系统架构的时候,要问下自己,我为什么要用NoSQL;在对NoSQL架构模式选型的时候,要问下自己,我为什么要这么用NoSQL。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!