NoSQL 架构实践(三)——以 NoSQL 为缓存

  • 孙立

2011 年 3 月 29 日

话题:Java.NETRubyDevOps语言 & 开发AI

在《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 协议或自定义的协议来使用。

持久化模式

虽然基于内存的缓存服务器具有高性能,低延迟的特点,但是内存成本高、内存数据易失却不容忽视。几十 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。

参考链接:

Java.NETRubyDevOps语言 & 开发AI