一、问题:
数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求。
二、解决方案:
1、通过高速服务器Cache缓存数据库数据
2、内存数据库
(这里仅从数据缓存方面考虑,当然,后期可以采用Hadoop+HBase+Hive等分布式存储分析平台)
三、主流解Cache和数据库对比:
名称 | 类型 | 数据存储选项 | 查询类型 | 附加功能 |
---|---|---|---|---|
Redis | 内存中的非关系数据库 | string、list、set、hashe、sorted set | 用于常见访问模式的每个数据类型的命令,包括批量操作和部分跨操作支持。 | 发布/订阅,主/从复制,磁盘持久性,脚本(存储过程) |
memcached | 内存缓存键-值 | 键到值的映射 | 用于创建、读取、更新删除和其他一些命令 | 多线程服务器的额外性能 |
MySQL | 关系数据库 | 数据库表的行,视图的表,空间和第三方扩展。 | SELECT,INSERT,UPDATE,DELETE,函数,存储过程 | ACID兼容(与InnoDB),主/从和主/主复制。 |
PostgreSQL | 关系数据库 | 数据库表的行,视图的表,空间和第三方扩展,可定制的类型。 | SELECT,INSERT,UPDATE,DELETE,内置函数、自定义存储过程 | ACID兼容,主/从复制,多主复制(第三方) |
MongoDB | 磁盘上的非关系文档存储 | 无模式BSON文档表数据库。 | 命令创建、读取、更新、删除条件查询,等等 | 支持使用映射-规约模式操作,主/从复制、分片、空间索引 |
上述技术基本上代表了当今在数据存储方面所有的实现方案,其中主要涉及到了
- 普通关系型数据库(MySQL/PostgreSQL),
- NoSQL数据库(MongoDB),
- 内存数据库(Redis),
- 内存Cache(Memcached),
我们现在需要的是对大数据表仍保持高效的查询速度,普通关系型数据库是无法满足的。
而MongoDB其实只是一种非关系型数据库,其优势在于可以存储海量数据,具备强大的查询功能,因此不宜用于缓存数据的场景。
从以上各数据可知,对于我们产品最可行的技术方案有两种:
1、Memcached 内存Key-Value Cache
2、Redis 内存数据库
四、下面重点分析Memcached和Redis两种方案:
4.1 Memcached介绍
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度,现在已被LiveJournal、hatena、Facebook、Vox、LiveJournal等公司所使用。
4.2 Memcached工作方式分析
许多Web应用都将数据保存到 RDBMS中,应用服务器从中读取数据并在浏览器中显示。 但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、 网站显示延迟等重大影响。Memcached是高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web等应用的速度、 提高可扩展性。下图展示了memcache与数据库端协同工作情况:
其中的过程是这样的:
1.检查用户请求的数据是缓存中是否有存在,如果有存在的话,只需要直接把请求的数据返回,无需查询数据库。
2.如果请求的数据在缓存中找不到,这时候再去查询数据库。返回请求数据的同时,把数据存储到缓存中一份。
3.保持缓存的“新鲜性”,每当数据发生变化的时候(比如,数据有被修改,或被删除的情况下),要同步的更新缓存信息,确保用户不会在缓存取到旧的数据。-
Memcached作为高速运行的分布式缓存服务器,具有以下的特点:
- 协议简单
- 基于libevent的事件处理
- 内置内存存储方式
- memcached不互相通信的分布式
4.3 如何实现分布式可拓展性?
Memcached的分布式不是在服务器端实现的,而是在客户端应用中实现的,即通过内置算法制定目标数据的节点,如下图所示:
4.4 Redis 介绍
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、 list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步,当前 Redis的应用已经非常广泛,国内像新浪、淘宝,国外像 Flickr、Github等均在使用Redis的缓存服务。
4.5 Redis 工作方式分析
- Redis作为一个高性能的key-value数据库具有以下特征:
- 多样的数据模型
- 持久化
- 主从同步
Redis支持丰富的数据类型,最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。Redis通常将数据存储于内存中,或被配置为使用虚拟内存。Redis有一个很重要的特点就是它可以实现持久化数据,通过两种方式可以实现数据持久化:使用RDB快照的方式,将内存中的数据不断写入磁盘;或使用类似MySQL的AOF日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。 Redis支持将数据同步到多台从数据库上,这种特性对提高读取性能非常有益。
4.6 Redis如何实现分布式可拓展性?
2.8以前的版本:与Memcached一致,可以在客户端实现,也可以使用代理,twitter已开发出用于Redis和Memcached的代理Twemproxy 。
3.0 以后的版本:相较于Memcached只能采用客户端实现分布式存储,Redis则在服务器端构建分布式存储。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,各个节点地位一致,具有线性可伸缩的功能。如图给出Redis Cluster的分布式存储架构,其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个 key的数值域分成16384个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是16384
五、综合结论
应该说Memcached和Redis都能很好的满足解决我们的问题,它们性能都很高,总的来说,可以把Redis理解为是对Memcached的拓展,是更加重量级的实现,提供了更多更强大的功能。具体来说:
性能上:
性能上都很出色,具体到细节,由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色。内存空间和数据量大小:
MemCached可以修改最大内存,采用LRU算法。Redis增加了VM的特性,突破了物理内存的限制。操作便利上:
MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。可靠性上:
MemCached不支持数据持久化,断电或重启后数据消失,但其稳定性是有保证的。Redis支持数据持久化和数据恢复,允许单点故障,但是同时也会付出性能的代价。-
应用场景:
- Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
- Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
六、需要慎重考虑的部分
- Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
- Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
- 从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
- 新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
以上转载自《memcache和redis原理对比》https://www.kancloud.cn/mayan0718/php/555555。
七,redis和memcached的使用场景和优缺点
说到缓存技术,只要有一定经验的开发人员,肯定会想到redis和memcached这两个。并且在BAT里,redis已经逐渐取代了memcached,成为分布式场景广泛使用的缓存方案。接下来,我们就分析下,redis是如何取代memcached,成为开发者的宠儿的。
7.1 支持的存储类型不同
虽然redis和memcached都是内存型数据库,并且memcached不仅能够存储string类型,还能够存储图片、文件、视频等格式的文件。然而对于更多的使用内存数据库做缓存以及分布式方案的程序开发者来说,memcached提供的string类型存储的应用场景非常有限,而存储图片视频的功能又十分鸡肋(许多公司的用户场景是没这方面需求)。相比之下,redis提供set,hash,list等多种类型的存储结构,非常适合分布式缓存的实现。
7.2 数据落盘
memcached 数据不可恢复,虽然大多数人使用缓存以及分布式方案都不会要求数据持久化,但是谁也不能保证不出现万一的情况。一旦发生稳定性问题,memcached挂掉后,数据是不可恢复的,而redis除了支持在配置里打开数据落盘(RDB),还能通过aof来找回数据。
7.3 内存空间与数据量
memcached可以修改最大内存,使用的是LRU算法,而redis目前底层使用了自己的VM,引入了新的特性突破了物理内存的限制。个人认为在这方面依然是redis更加优秀一些。
备注:value值-redis最大可以达到1GB,而memcache只有1MB;
7.4 使用场景
(1)、会话缓存(Session Cache)
最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。
(2)、全页缓存(FPC)
除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。
再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。
此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。
(3)、队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。
(4),排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:
当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:
ZRANGE user_scores 0 10 WITHSCORES
Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。
(5)、发布/订阅
最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。
(6)、其他
但是如果是对缓存的数据格式有更多的要求,且对安全性也有很高的要求的话,建议还是使用redis,这也是redis目前正在逐渐代替memcached的根本原因。