游戏服务器使用MongoDB作为数据库缓存同步redis,还有必要使用Redis缓存吗

花了两天时间看完nodeclub的源代码,感觉用了MongoDB,就没有必要用redis了。 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
MongoDB本身会把一些数据加载到内存。然后再加个redis,显然对内存开销挺大的。redis和MySQL等才比较搭配。
nodeclub主要消耗性能的地方是在渲染html方面。应该建立一个有限容量缓存器,缓存渲染成功的一些静态网页。
还有一个刷新问题,如果浏览器过度在玩刷新,这个对服务器请求比较大,应该进行一些限制。
是吧,我也一直这么觉得
mongodb 确实会把数据加载到内存,不过你看各种测速结果,都不会告诉你 mongodb 跟 redis 是做同一层面的事情的。mongodb 跟 mysql 才是同一层面的东西。mysql innodb 也会把数据缓存到内存中。
mongodb 跟 redis 速度差很多。这不在于数据在内存还是硬盘,还在于他们查询和插入时候要经历的步骤,以及数据按什么方式存储在内存中。
nodeclub 类似的产品,作为教学目的用用 mongodb 没关系,实际的开发中,类似的产品用 mysql 更合适。一些统计需求用 mongodb 做起来很蛋疼,不能关联查询也很蛋疼。
渲染 html 这块的话,我确实想过好好做一下,当时的思考在这里: 。后来由于懒,没有怎么做。其实html渲染消耗性能的话,对于服务器来说,多加几个 cpu 就好了。不过对于用户体验来说,会增加不少的渲染时间。我们现在首页在 200ms 的 rt,帖子页一般在 100ms 这样。其实还是比较挫的。
服务器请求这块的话,没有像 v2ex 做得那么细致,其实 cnode 一直是比较脆弱的。很多类似的事情,增加了代码的复杂度,对于新手看代码阻碍很大,并且在开源的情况下,
我也拿不准自己能做出一个透明却有效的防恶意刷帖机制。
对于 3、4 点,不得不承认,一半是懒,一半是不想增加代码复杂度。
很赞,很牛,很无私。楷模。
第二点是有点带有主观情绪的,除了事务还是事务,这已经不再那么难于处理了,另外,mongodb的查询还是可以的,如果要多表查询,也是有很多办法的。其实最恶心的是大家不习惯面向key做设计,没架构经验会被玩死
我支持alsotang的观点,nosql技术不能说不好,但处理复杂查询上还有点缺陷的。我个人觉得,nosql技术有点像以前Java中的hibernate,用的时候很爽,优化的时候想死。再说,面向关系的数据库设计是经过时间验证的,面向key的设计,还需要时间来验证。
最近我看到很多公司的代码,mongodb、mysql、redis 同时使用,这些开发者有时都搞不清这个数据应该放那儿。在技术栈不成熟的情况下,尽量少用新技术,拿不准的事情不要做。
拿hibernate举例容易被喷,优化的时候想死只能说明你对hibernate不够理解。和说mongdob不好查询是一样的,不要直接在生产的数据上直接做关联,都是key会非常难受,你可以加一层,相关数据汇总,变成大的宽表就好了,或者更负责的上es类的。
大家的舒适区都在rdbms上,所以有这个感觉是正常的,mysql如果没有dba优化也挺难的
最后一个:混用多种的时候,对开发的要求会非常高,这种正确的做法是封装成服务让开发调用,而不是尽量少用新技术,拿不准的事情不要做。公司里只要有一个人能搞定,其实就够了
如果用rdbms,当项目非常大的时候,你的er模型和范式都是无法遵守的,一样会造成查询的问题,比如很多公司禁止用join。。。先去哭一会
拿什么举例都会被喷的,这是一种造句方式;XXXX不好,是因为你对XXXX不够深入不够了解。其实你想说我和我想表达的都一样的东西,每个技术都是有自己的适用范围的,超出范围了就有瓶颈。我也不反对新技术,我是从项目角度去看这个问题。
现在这个浮燥的时代,每个领导都想三天造飞机,五天造火箭。我们搞技术的,就算设计得再完美,老板一催,就开始乱写,完成任务是第一嘛。在面向领导的开发中,那有时间去研究这些细节。所以还不如搞一些成熟的技术,至少犯的错误不会离谱。我就是这个意思。呵呵
1.5M - -。
这就是我为什么用它- -。
哈哈,把境界放高点,如果完全面向领导干技术和当公务员就没啥区别了
争论更多的是起点不同,如果2个你都熟悉,争论才有意义。技术发展这么快,以一个积极的态度面对,才能乐此不疲的
看看大神之间的对话也是蛮有收获的
你这样强行装一波,我感到很吃力
不错,学习可以激进点。项目,我个人还是保守点。
mongodb和mysql的&表&结构设计理念是完全不同的.
比如我设计一个单据流程,里面涉及原型单,审核规则,审核结果,审核意见.如果是关系型数据库,那肯定是各自一张表,join查询,操作也是事务加锁
但在mongo里面,我是把他们放在一个collection里面,因为我认为这几个单据组合起来,才是一个完整的审核流程,而操作一个单个collection,也不存在什么join 事务了.写起代码来,简直不要太方便.
除了流量多点,几乎没什么影响.
看你的痛点是什么了。redis可以用来写队列,缓存自动过期什么的,mongodb实现就很尴尬了。而我早就放弃mongodb,回到mysql了。没办法,符合实际项目需求的才是好东西
这两个不是一个东西吧 -。 -
redis 做缓存做队列的
mongodb 做数据库的
两者的目标都不一致吧…
用 mongodb 来做这个场景,我听你说着都怕。
统计报表怎么跑出来的?mongodb mapreduce?
充气,爆炸- -
mongodb可以用populate做关联查询啊,如果同时要使用aggregate的话,就只能先用aggregate,再populate
mongodb的aggregate不比sql语义差, 甚至某些方面更强. 只是性能方面会有一些差距.
populate是mongoose的, mongoose的实现性能差一些, 是取到文档, 再去取关联的. aggregate是一下取出来.
对,aggregate 是 mongodb 的,populate 是 mongoose 的。
mongodb的aggregate+mapreduce已经足够强大,如与spark集成应对大数据分析也能胜任。另外redis和mongo也是两个层面上的东西。主要还是要看理解程度加怎么用
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的[原]分享一下我和MongoDB与Redis那些事
发布时间: 17:35:29
缘起:来自于我在近期一个项目上遇到的问题,在Segmentfault上发表了提问
知识背景:
  对不是很熟悉MongoDB和Redis的同学做一下介绍。
& & & & & & 1.MongoDB数组查询:MongoDB自带List,可以存放类似这样的结构 List = [1, 2, 3, 4, 5, 6, 7, 8, 9].
& & & & & & & &如果我们有一个 l = [2, 3, 8], 则可以进行这样的查询:spce =&{ 'List' : { '$in' : &l }, 这里spce就是一个查询条件,代表 l 是 List的一个子集。
& & & & & & 2.Redis队列: Redis提供基本的List(普通链表),set(集合),Zset(有序集合) 类型的结构,将List的 lpush, rpop操作运用起来,可以做一个普通的队列,运用Zset 可以做一个带权值的最小堆排序的队列(可以看做优先级)。
整体架构如下图所示:
生产者产生任务,通过LVS与RPC服务器将任务记录到MongoDB,消费者同样通过RPC服务获取任务,这是个很简单的架构,一般服务可能去掉集群都是这样的。
整个业务架构需要一个前提,任务不能丢失,也就是说任务即使失败也需要重新加入到队列,至少若干次后任然失败也要知道为什么失败(非记录日志形式)。
很多人问为什么不直接用RabbitMQ或者Redis,因为这类消息队列无法做到管理任务超时等情况,因为业务需要,也需要做一些简单的查询,这类队列是不支持某些稍复杂的查询的,而且一开始我们的任务量估计在5KW/Day这样,担心Redis扛不住,后来我发现这是个错误的假设。
问题内容如下:
问题背景: 近期在重构公司内部一个重要的任务系统,由于原来的任务系统使用了MongoDB来保存任务,客户端从MongoDB来取,至于为什么用MongoDB,是一个历史问题,也是因为如果使用到MongoDB的数组查询可以减少任务数量很多次,假设这样的情况,一个md5(看做一条记录的唯一标识)需要针对N种情况做任务处理,如果用到MongoDB的数组,只需要将一个md5作为一条任务,其中包含一个长度为N的待处理任务列表,可以使用到MongoDB的数组(只有N个子任务都处理完后整个任务才算处理完毕),这样整个任务系统的数量级就变为原来的 1/N(如果需要用到普通的关系型数据库,可能需要创建 m*n 个任务,这样算下来我们的任务数量将可能达到一个很大的值,主要是因为处理任务的进程由于某些不确定因素无法控制,所以比较慢)
细节描述: 1.当MongoDB的任务数量增多的时候,数组查询相当的慢(已经做索引),任务数达到5K就已经不能容忍了,和我们每天的任务数不在一个数量级。
& & & & & & & & 2.任务处理每个md5对应的N个子任务必须要全部完成才从MongoDB中删除
& & & & & & & & 3.任务有相应的优先级(保证高优先级优先处理),任务在超时后可以重置。
改进方案如下: 由于原有代码的耦合,不能完全抛弃MongoDB,所以决定加一个Redis缓存。一个md5对应的N个子任务分发到N个Redis队列中(拆分子任务)。一个单独的进程从MongoDB中向Redis中将任务同步,客户端不再从MongoDB取任务。这样做的好处是抛弃了原有的MongoDB的数组查询,同步进程从MongoDB中取任务是按照任务的优先级偏移(已做索引)来取,所以速度比数组查询要快。这样客户端向Redis的N个队列中取子任务,把任务结果返回原来的MongoDB任务记录中(根据md5返回子任务)。
改进过程遇到的问题: 由于任务处理端向MongoDB返回时候会有一个update操作,如果N个子任务都完成,就将任务从MongoDB中删除。这样的一个问题就是,经过测试后发现MongoDB在高并发写的情况下性能很低下,整个任务系统任务处理速度最大为200/s(16核, 16G, CentOS, 内核2.6.32-358.6.3.el6.x86_64),原因大致为在频繁写情况下,MongoDB的性能会由于锁表操作急剧下降(锁表时间可以达到60%-70%,熟悉MongoDB的人都知道这是多么恐怖的数字)。
具体问题: (Think out of the Box)能否提出一个好的解决方案,能够保存任务状态(子任务状态),速度至少超过MongoDB的?
提出这个问题后,很感谢官方将问题发到微博首页,有一个回答我觉得可以采纳:
初步的思考了一下,仅供参考:
首先,提一下索引,相信这个你应该加了索引。
有个问题确认一下,mongodb最新版本中的锁粒度还是Database级别吧,不知道你用的哪个版本,还没到锁表(Collection)这个粒度,所以写并发大的情况下比较糟糕,不过应该性能也不至于糟到像你描述的那样啊?不解,建议考虑任务分库的可能性?
能否考虑把子任务的状态和主任务的状态分开保存。子任务的状态,可以放到redis,主任务只负责自己本身的状态,这样每个主任务更新频率降为1/N,可大大减少mongodb中主任务表的压力。
子任务完成或超时后,可否考虑后台异步单线程顺序同步mongodb的主任务状态?
上面这个Answer可以考虑,但是在做同步过程中发现很多问题。
在开发过程中发现,由单一进程从MongoDB向Redis同步数据,可以采取两种可参考的方案:
& & & & & & 1.模拟MongoDB replication机制,一个进程模拟slave向master请求oplog,然后自己解析数据格式存放到Redis.
& & & & & & 2.一个进程从MongoDB中按照优先级取数据然后同步到Redis.
两种参考方案各有优劣,我最终选择了第二种。
& & & & & & 第一种方案
& & & & & & & & & 优点:
& & & & & & & & & & & 1.主MongoDB查询压力变小
& & & & & & & & & & & 2.以后业务扩展很方便(可以运用到查询缓存啊,读写分离什么的)
& & & & & & & & &&缺点:
& & & & & & & & & & & 1.可参考文档较少,需要模拟MongoDB replication的机制较为复杂
& & & & & & & & & & & 2.同步实时性无法估计确切时间
& & & & & & 第二种方案:
& & & & & & & & & 优点:
& & & & & & & & & & & 1.编码相对简单,按照优先级做索引后查询不影响原有逻辑
& & & & & & & & & & & 2.开发较为灵活(似乎和第一点是一样的)
& & & & & & & & & 缺点:
& & & & & & & & & & & 1.(项目完成后测试不理想,具体原因会做说明)
& & & & & & & & & & & 2.同步进程单点,如果进程卡死或者机器崩溃会造成系统卡死
方案确定:由单一进程从MongoDB同步任务到Redis.
架构变迁到这样:
加上Redis,做到MongoDB的读写分离,单一进程从MongoDB及时把任务同步到Redis中。
看起来很完美,但是上线后出现了各种各样的问题,列举一下:
1.Redis队列长度为多少合适?
2.同步进程根据优先级从MongoDB向Redis同步过程中,一次取多少任务合适?太大导致很多无谓的开销,太小又会频繁操作MongoDB
3.当某一个子任务处理较慢的时候,会导致MongoDB的前面优先级较高的任务没有结束,而优先级较低的确得不到处理,造成消费者空闲
最终方案:
在生产者产生一个任务的同时,向Redis同步任务,Redis sort set(有序集合,保证优先级顺序不变),消费者通过RPC调用时候,RPC服务器从Redis中取出任务,然后结束任务后从MongoDB中删除。
测试结果,Redis插入效率。Redis-benchmark 并发150,32byte一个任务,一共100W个,插入效率7.3W(不使用持久化)
在这之前我们的担心都是没必要的,Redis的性能非常的好。
目前此套系统可以胜任每天5KW量的任务,我相信可以更多。后面有文章可能会讲到Redis的事务操作
来源:/Bozh/p/3408765.html游戏服务器使用MongoDB作为数据库,还有必要使用Redis缓存吗? - 知乎231被浏览35729分享邀请回答该回答已被折叠 折叠原因:算法识别自动折叠0添加评论分享收藏感谢收起一聚教程网:一个值得你收藏的教程网站
redis和mongodb数据库对比
时间: 00:00:00
编辑:简简单单
来源:转载
redis是一个key-value型,信息以键对应值的关系存储在内存中,比memcache较大的优势就在于其数据结构的多样性。说它不算一个真正意义上的数据库,因为redis是主要把数据存储在内存中(当然可以把其存储至硬盘上,这也是写shell的必要条件之一),其“缓存”的性质远大于其“数据存储”的性质,其中数据的正删改查也只是像变量操作一样简单。而mongodb却是一个“存储数据”的系统,增删改查数据的时候有“与或非”条件,查询数据的方式也能像SQL数据库一样灵活,这是redis所不具备的。所以在我的项目中,redis作为session、任务队列的存储器,而mongodb作为数据(包括用户信息等)的存储器。进入正题,昨天看到freebuf上已经说了redis可能造成的安全问题,提到了写文件,那么我在这里把方法说明一下吧。redis安装完成以后有自己的命令行,也就是redis-cli,其中包含的命令可以在:http://redis.io/commands 进行查阅。各个客户端基本也就是依照这个命令去增删改查。之前说了redis的数据主要保存在内存中,当与memcache不同之处在于,我们可以随时执行“save”命令将当前redis的数据保存到硬盘上,另外redis也会根据配置自动存储数据到硬盘上。这不得不说到redis的持久化运作方案 http://redis.io/topics/persistence ,其中说到的一个RDB,一个AOF。RDB更像一个数据库备份文件,而AOF是一个log日志文件。我们可以设置让redis再指定时间、指定更改次数时进行备份,生成RDB文件;而设置AOF,可以在操作或时间过程后将“日志”写入一个文件的最末,当操作越来越多,则AOF文件越来越大。二者是相辅相成的,通过二者的配合我们能够稳定地持久地将数据存储于服务器上。利用redis写webshell而我们就是利用这些储存数据的操作,来进行任意文件写入。redis的配置中,有几个关键项目:dir,指定的是redis的“工作路径”,之后生成的RDB和AOF文件都会存储在这里。dbfilename,RDB文件名,默认为“dump.rdb”appendonly,是否开启AOFappendfilename,AOF文件名,默认为“appendonly.aof”appendfsync,AOF备份方式:always、everysec、no经过我的研究发现,我们可以将dir设置为一个目录a,而dbfilename为文件名b,再执行save或bgsave,则我们就可以写入一个路径为a/b的任意文件:当我们获得了一个redis控制台,我们可以调用config set/get等命令对redis的部分配置进行修改。而恰好的是,我们可以通过config set来更改dir和dbfilename。也就是说我们可以不用修改redis.conf,也不用重启redis服务就可以写入任意文件:config set dir /home/wwwroot/default/config set dbfilename redis.phpset webshell “&?php phpinfo(); ?&“save当我们随便set一个变量webshell的值为”&?php phpinfo(); ?&”后,即可对服务器进行getshell。可见已写入:导出的RDB实际上是一个二进制文件,但因为其中包含&?php phpinfo(); ?&,所以被解析了:在前图中,我们可以看到其实还生成了一个appendonly.aof,这个文件名能不能自定义呢?可惜的是,appendfilename的值并不能使用config set命令定义:但仅有的一个dbfilename已经足够了。所以,以后如果扫到redis未授权访问,先别急着提交乌云。看看服务器有没有web服务,如果有,不妨试试能不能拿下webshell。Mongodb与Redis应用指标对比MongoDB和Redis都是NoSQL,采用结构型数据存储。二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式。指标&MongoDB(v2.4.9)&Redis(v2.4.17)&比较说明实现语言&C++C/C++-协议BSON、自定义二进制类Telnet-性能依赖内存,TPS较高依赖内存,TPS非常高Redis优于MongoDB可操作性丰富的数据表达、索引;最类似于关系数据库,支持丰富的查询语言数据丰富,较少的IOMongoDB优于Redis内存及存储适合大数据量存储,依赖系统虚拟内存管理,采用镜像文件存储;内存占有率比较高,官方建议独立部署在64位系统(32位有最大2.5G文件限制,64位没有改限制)Redis2.0后增加虚拟内存特性,突破物理内存限制;数据可以设置时效性,类似于memcache不同的应用角度看,各有优势可用性支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制;不支持自动sharding,需要依赖程序设定一致hash机制MongoDB优于Redis;单点问题上,MongoDB应用简单,相对用户透明,Redis比较复杂,需要客户端主动解决。(MongoDB
一般会使用replica sets和sharding功能结合,replica
sets侧重高可用性及高可靠性,而sharding侧重于性能、易扩展)可靠性从1.8版本后,采用binlog方式(MySQL同样采用该方式)支持持久化,增加可靠性依赖快照进行持久化;AOF增强可靠性;增强可靠性的同时,影响访问性能MongoDB优于Redis一致性不支持事物,靠客户端自身保证支持事物,比较弱,仅能保证事物中的操作按顺序执行Redis优于MongoDB数据分析内置数据分析功能(mapreduce)不支持MongoDB优于Redis应用场景海量数据的访问效率提升较小数据量的性能及运算MongoDB优于RedisRedis、Memcached与 MongoDB三者的区别如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。2 Redis支持数据的备份,即master-slave模式的数据备份。3 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别(我个人是这么认为的)。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个操作,直到子线程完成swap操作后才可以进行修改。可以参考使用Redis特有内存模型前后的情况对比:VM off: 300k keys, 4096 bytes values: 1.3G usedVM on: 300k keys, 4096 bytes values: 73M usedVM off: 1 million keys, 256 bytes values: 430.12M usedVM on: 1 million keys, 256 bytes values: 160.09M usedVM on: 1 million keys, values as large as you want, still: 160.09M used 当从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。redis、memcache、mongoDB 对比从以下几个维度,对redis、memcache、mongoDB 做了对比,欢迎拍砖1、性能都比较高,性能对我们来说应该都不是瓶颈总体来讲,TPS方面redis和memcache差不多,要大于mongodb2、操作的便利性memcache数据结构单一redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数mongodb支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富3、内存空间的大小和数据量的大小redis在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似memcache)memcache可以修改最大可用内存,采用LRU算法mongoDB适合大数据量的存储,依赖VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起4、可用性(单点问题)对于单点问题,redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制。5、可靠性(持久化)对于数据持久化和数据恢复,redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响memcache不支持,通常用在做缓存,提升性能;MongoDB从1.8版本开始采用binlog方式支持持久化的可靠性6、数据一致性(事务支持)Memcache 在并发场景下,用cas保证一致性redis事务支持比较弱,只能保证事务中的每个操作连续执行mongoDB不支持事务7、数据分析mongoDB内置了数据分析的功能(mapreduce),其他不支持8、应用场景redis:数据量较小的更性能操作和运算上memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding)MongoDB:主要解决海量数据的访问效率问题一、问题:
& & 数据库表数据量极大(千万条),要求让服务器更加快速地响应用户的需求。
二、解决方案:
& & &1.通过高速服务器Cache缓存数据库数据
& & &2.内存数据库
& (这里仅从数据缓存方面考虑,当然,后期可以采用Hadoop+HBase+Hive等分布式存储分析平台)
三、主流解Cache和数据库对比:
& & &上述技术基本上代表了当今在数据存储方面所有的实现方案,其中主要涉及到了普通关系型数据库(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作为高速运行的分布式缓存服务器,具有以下的特点:&
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的代理&。
3.0以后的版本:相较于Memcached只能采用客户端实现分布式存储,Redis则在服务器端构建分布式存储。Redis&Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,各个节点地位一致,具有线性可伸缩的功能。如图给出Redis&Cluster的分布式存储架构,其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis&Cluster将整个key的数值域分成16384个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis&Cluster支持的最大节点数就是16384
五、综合结论
&应该说Memcached和Redis都能很好的满足解决我们的问题,它们性能都很高,总的来说,可以把Redis理解为是对Memcached的拓展,是更加重量级的实现,提供了更多更强大的功能。具体来说:
1.性能上:
& & &性能上都很出色,具体到细节,由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比
Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起&Memcached,还是稍有逊色。
2.内存空间和数据量大小:
& & &MemCached可以修改最大内存,采用LRU算法。Redis增加了VM的特性,突破了物理内存的限制。
3.操作便利上:
& & &MemCached数据结构单一,仅用来缓存数据,而Redis支持更加丰富的数据类型,也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。
4.可靠性上:
& & &MemCached不支持数据持久化,断电或重启后数据消失,但其稳定性是有保证的。Redis支持数据持久化和数据恢复,允许单点故障,但是同时也会付出性能的代价。
5.应用场景:
& & &Memcached:动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)。
& & &Redis:适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。
六、需要慎重考虑的部分
1.Memcached单个key-value大小有限,一个value最大只支持1MB,而Redis最大支持512MB
2.Memcached只是个内存缓存,对可靠性无要求;而Redis更倾向于内存数据库,因此对对可靠性方面要求比较高
3.从本质上讲,Memcached只是一个单一key-value内存Cache;而Redis则是一个数据结构内存数据库,支持五种数据类型,因此Redis除单纯缓存作用外,还可以处理一些简单的逻辑运算,Redis不仅可以缓存,而且还可以作为数据库用
4.新版本(3.0)的Redis是指集群分布式,也就是说集群本身均衡客户端请求,各个节点可以交流,可拓展行、可维护性更强大。
本文已收录于以下专栏:
相关文章推荐
(一)索引的作用
索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上就已经...
MySQL 百万级分页优化(Mysql千万级快速分页)
以下分享一点我的经验 
一般刚开始学SQL的时候,会这样写 
复制代码代码如下:
SELECT * ...
在数据分析领域,数据库是我们的好帮手。不仅可以接受我们的查询时间,还可以在这基础上做进一步分析。所以,我们必然要在数据库插入数据。在实际应用中,我们经常遇到千万级,甚至更大的数据量。如果没有一个快速的...
从以下几个维度,对 redis、memcache、mongoDB 做了对比。
都比较高,性能对我们来说应该都不是瓶颈。
总体来讲,TPS 方面 redis 和 memcache 差不多...
近期都在谈微服务,本人也正在做相关的工作,应领导要求做了一个微服务的分享,本篇文章主要来源于分享的PPT。本篇文章先简单介绍了互联网架构的演变,进而介绍了服务化,最后再介绍微服务,微服务是服务治理的升...
由于担心项目性能问题,最初的数据库设计就一直有缓存服务器,用的最多的还是mongodb,今天,我就简单谈谈mongodb在项目中的使用。
其实,我使用mongodb最多的是用于查询,确实,作为nos...
英文原文:How to use MongoDB as
a pure in-memory DB (Redis style)
转载自    http://www.oschina.net/transl...
关于使用servlet实现用户登录初探
这个一个页面模拟的cookie
如果你要实现登录,当用户输入用户名密码时,到控制层用 
Cookie cookie = new Cookie(&user&,name+&-&+passwar...
mongodb 对内存的严重占用以及解决方法【转载】 
刚开始使用mongodb的时候,不太注意mongodb的内存使用,但通过查资料发现mongodb对内存的占用是巨大的,在本地测试服务器中,...
他的最新文章
讲师:AI100
讲师:谢梁
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 redis缓存数据库 的文章

 

随机推荐