存放缓存的三种⽅式Redis、Memcache和MongoDB的区别>>Memcached
Memcached的优点:
Memcached可以利⽤多核优势,单实例吞吐量极⾼,可以达到⼏⼗万QPS(取决于key、value的字节⼤⼩以及服务器硬件性能,⽇常环境中QPS⾼峰⼤约在4-6w左右)。适⽤于最⼤程度扛量。
⽀持直接配置为session handle。
Memcached的局限性:
只⽀持简单的key/value数据结构,不像Redis可以⽀持丰富的数据类型。
⽆法进⾏持久化,数据不能备份,只能⽤于缓存使⽤,且重启后数据全部丢失。
⽆法进⾏数据同步,不能将MC中的数据迁移到其他MC实例中。
Memcached内存分配采⽤Slab Allocation机制管理内存,value⼤⼩分布差异较⼤时会造成内存利⽤率降低,并引发低利⽤率时依然出现踢出等问题。需要⽤户注重value设计。
>>Redis
Redis的优点:
⽀持多种数据结构,如 string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基数估算)
⽀持持久化操作,可以进⾏aof及rdb数据持久化到磁盘,从⽽进⾏数据备份或数据恢复等操作,较好的防⽌数据丢失的⼿段。
⽀持通过Replication进⾏数据复制,通过master-slave机制,可以实时进⾏数据的同步复制,⽀持多级复制和增量复制,master-slave机制是Redis进⾏HA的重要⼿段。
单线程请求,所有命令串⾏执⾏,并发情况下不需要考虑数据⼀致性问题。
⽀持pub/sub消息订阅机制,可以⽤来进⾏消息订阅与通知。
⽀持简单的事务需求,但业界使⽤场景很少,并不成熟。
Redis的局限性:
Redis只能使⽤单线程,性能受限于CPU性能,故单实例CPU最⾼才可能达到5-6wQPS每秒(取决于数据结构,数据⼤⼩以及服务器硬件性能,⽇常环境中QPS⾼峰⼤约在1-2w左右)。
⽀持简单的事务需求,但业界使⽤场景很少,并不成熟,既是优点也是缺点。
Redis在string类型上会消耗较多内存,可以使⽤dict(hash表)压缩存储以降低内存耗⽤。
Mc和Redis都是Key-Value类型,不适合在不同数据集之间建⽴关系,也不适合进⾏查询搜索。⽐如redis的keys pattern这种匹配操作,对redis的性能是灾难。
>>mongoDB
mongoDB 是⼀种⽂档性的数据库。先解释⼀下⽂档的数据库,即可以存放xml、json、bson类型系那个的数据。
这些数据具备⾃述性(self-describing),呈现分层的树状数据结构。redis可以⽤hash存放简单关系型数据。
mongoDB 存放json格式数据。
适合场景:事件记录、内容管理或者博客平台,⽐如评论系统。
mongodb与mysql不同,mysql的每⼀次更新操作都会直接写⼊硬盘,但是mongo不会,做为内存型数据库,数据操作会先写⼊内存,然后再会持久化到硬盘中去,那么mongo是如何持久化的呢
mongodb在启动时,专门初始化⼀个线程不断循环(除⾮应⽤crash掉),⽤于在⼀定时间周期内来从defer队列中获取要持久化的数据并写⼊到磁盘的journal(⽇志)和mongofile(数据)处,当然因为它不是在⽤户添加记录时就写到磁盘上,所以按mongodb开发者说,它不会造成性能上的损耗,因为看过代码发现,当进⾏CUD操作时,记录(Record类型)都被放⼊到defer队列中以供延时批量(groupcommit)提交写⼊,但相信其中时间周期参数是个要认真考量的参数,系统为90毫秒,如果该值更低的话,可能会造成频繁磁盘操作,过⾼⼜会造成系统宕机时数据丢失过。
2.什么是NoSQL数据库?NoSQL和RDBMS有什么区别?在哪些情况下使⽤和不使⽤NoSQL数据库?
NoSQL是⾮关系型数据库,NoSQL = Not Only SQL。
关系型数据库采⽤的结构化的数据,NoSQL采⽤的是键值对的⽅式存储数据。
在处理⾮结构化/半结构化的⼤数据时;在⽔平⽅向上进⾏扩展时;随时应对动态增加的数据项时可以优先考虑使⽤NoSQL数据库。
在考虑数据库的成熟度;⽀持;分析和商业智能;管理及专业性等问题时,应优先考虑关系型数据库。
3.MySQL和MongoDB之间最基本的区别是什么?
关系型数据库与⾮关系型数据库的区别,即数据存储结构的不同。
4.MongoDB的特点是什么?
(1)⾯向⽂档(2)⾼性能(3)⾼可⽤(4)易扩展(5)丰富的查询语⾔
5.MongoDB⽀持存储过程吗?如果⽀持的话,怎么⽤?
MongoDB⽀持存储过程,它是javascript写的,保存在db.system.js表中。
6.如何理解MongoDB中的GridFS机制,MongoDB为何使⽤GridFS来存储⽂件?
GridFS是⼀种将⼤型⽂件存储在MongoDB中的⽂件规范。使⽤GridFS可以将⼤⽂件分隔成多个⼩⽂档存放,这样我们能够有效的保存⼤⽂档,⽽且解决了BSON对象有限制的问题。
7.为什么MongoDB的数据⽂件很⼤?
MongoDB采⽤的预分配空间的⽅式来防⽌⽂件碎⽚。
8.当更新⼀个正在被迁移的块(Chunk)上的⽂档时会发⽣什么?
更新操作会⽴即发⽣在旧的块(Chunk)上,然后更改才会在所有权转移前复制到新的分⽚上。
9.MongoDB在A:{B,C}上建⽴索引,查询A:{B,C}和A:{C,B}都会使⽤索引吗?
不会,只会在A:{B,C}上使⽤索引。
10.如果⼀个分⽚(Shard)停⽌或很慢的时候,发起⼀个查询会怎样?
如果⼀个分⽚停⽌了,除⾮查询设置了“Partial”选项,否则查询会返回⼀个错误。如果⼀个分⽚响应很慢,MongoDB会等待它的响应。>>Redis、Memcache和MongoDB的区别
从以下⼏个维度,对redis、memcache、mongoDB 做了对⽐,
1、性能
都⽐较⾼,性能对我们来说应该都不是瓶颈
总体来讲,TPS⽅⾯redis和memcache差不多,要⼤于mongodb
2、操作的便利性
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:数据量较⼩的更性能操作和运算上
【Redis应⽤场景】
1、热点数据的缓存
由于redis访问速度块、⽀持的数据类型⽐较丰富,所以redis很适合⽤来存储热点数据,另外结合expir
e,我们可以设置过期时间然后再进⾏缓存更新操作,这个功能最为常见,我们⼏乎所有的项⽬都有所运⽤。
2、限时业务的运⽤
redis中可以使⽤expire命令设置⼀个键的⽣存时间,到时间后redis会删除它。利⽤这⼀特性可以运⽤在限时的优惠活动信息、⼿机验证码等业务场景。
3、计数器相关问题
redis由于incrby命令可以实现原⼦性的递增,所以可以运⽤于⾼并发的秒杀活动、分布式序列号的⽣成、具体业务还体现在⽐如限制⼀个⼿机号发多少条短信、⼀个接⼝⼀分钟限制多少请求、⼀个接⼝⼀天限制调⽤多少次等等。
4、排⾏榜相关问题
关系型数据库在排⾏榜⽅⾯查询速度普遍偏慢,所以可以借助redis的SortedSet进⾏热点数据的排序。
在奶茶活动中,我们需要展⽰各个部门的点赞排⾏榜,所以我针对每个部门做了⼀个SortedSet,然后以⽤户的openid作为上⾯的username,以⽤户的点赞数作为上⾯的score, 然后针对每个⽤户做⼀个ha
sh,通过zrangebyscore就可以按照点赞数获取排⾏榜,然后再根据username 获取⽤户的hash信息,这个当时在实际运⽤中性能体验也蛮不错的。
5、分布式锁
这个主要利⽤redis的setnx命令进⾏,setnx:"set if not exists"就是如果不存在则成功设置缓存同时返回1,否则返回0 ,这个特性在俞你奔远⽅的后台中有所运⽤,因为我们服务器是集的,定时任务可能在两台机器上都会运⾏,所以在定时任务中⾸先通过setnx设置⼀个lock,如果成功设置则执⾏,如果没有成功设置,则表明该定时任务已执⾏。当然结合具体业务,我们可以给这个lock加⼀个过期时间,⽐如说30分钟执⾏⼀次的定时任务,那么这个过期时间设置为⼩于30分钟的⼀个时间就可以,这个与定时任务的周期以及定时任务执⾏消耗时间相关。
当然我们可以将这个特性运⽤于其他需要分布式锁的场景中,结合过期时间主要是防⽌死锁的出现。
6、延时操作
这个⽬前我做过相关测试,但是还没有运⽤到我们的实际项⽬中,下⾯我举个该特性的应⽤场景。⽐如在订单⽣产后我们占⽤了库存,10分钟后去检验⽤户是够真正购买,如果没有购买将该单据设置⽆效,同时还原库存。由于redis⾃2.8.0之后版本提供Keyspace Notifications 功能,允许客户订阅Pub/S
ub频道,以便以某种⽅式接收影响Redis数据集的事件。所以我们对于上⾯的需求就可以⽤以下解决⽅案,我们在订单⽣产时,设置⼀个key,同时设置10分钟后过期,我们在后台实现⼀个,监听key的实效,监听到key失效时将后续逻辑加上。当然我们也可以利⽤rabbitmq、activemq等消息中间件的延迟队列服务实现该需求。
7、分页、模糊搜索
redis的set集合中提供了⼀个zrangebylex⽅法,语法如下:
ZRANGEBYLEX key min max [LIMIT offset count]
通过ZRANGEBYLEX zset - + LIMIT 0 10 可以进⾏分页数据查询,其中- +表⽰获取全部数据
zrangebylex key min max 这个就可以返回字典区间的数据,利⽤这个特性可以进⾏模糊查询功能,这个也是⽬前我在redis中发现的唯⼀⼀个⽀持对存储内容进⾏模糊查询的特性。
前⼏天我通过这个特性,对学校数据进⾏了模拟测试,学校数据60万左右,响应时间在700ms左右,⽐mysql的like查询稍微快⼀点,但是由于它可以避免⼤量的数据库io操作,所以总体还是⽐直接mysql查询更利于系统的性能保障。
redis是nosql数据库吗8、点赞、好友等相互关系的存储
Redis set对外提供的功能与list类似是⼀个列表的功能,特殊之处在于set是可以⾃动排重的,当你需要存储⼀个列表数据,⼜不希望出现重复数据时,set是⼀个很好的选择,并且set提供了判断某个成员是否在⼀个set集合内的重要接⼝,这个也是list所不能提供的。⼜或者在微博应⽤中,每个⽤户关注的⼈存在⼀个集合中,就很容易实现求两个⼈的共同好友功能。
这个在奶茶活动中有运⽤,就是利⽤set存储⽤户之间的点赞关联的,另外在点赞前判断是否点赞过就利⽤了sismember⽅法,当时这个接⼝的响应时间控制在10毫秒内,⼗分⾼效。
9、队列
由于redis有list push和list pop这样的命令,所以能够很⽅便的执⾏队列操作。
redis已经逐渐取代了memcached,成为分布式场景⼴泛使⽤的缓存⽅案。
memcache:⽤于在动态系统中减少数据库负载,提升性能;做缓存,提⾼性能(适合读多写少,对于数据量⽐较⼤,可以采⽤sharding)MongoDB:主要⽬标是在键/值存储⽅式(提供了⾼性能和⾼度伸缩性)和传统的RDBMS 系统(具有丰富的功能)之间架起⼀座桥梁,它集两者的优势于⼀⾝。根据官⽅⽹站的描述,Mongo 适⽤于以下场景。
【MongoDB应⽤场景】
1、⽹站数据:Mongo ⾮常适合实时的插⼊,更新与查询,并具备⽹站实时数据存储所需的复制及⾼度伸缩性。
2、缓存:由于性能很⾼,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载。
3、⼤尺⼨、低价值的数据:使⽤传统的关系型数据库存储⼀些数据时可能会⽐较昂贵,在此之前,很多时候程序员往往会选择传统的⽂件进⾏存储。
4、⾼伸缩性的场景:Mongo ⾮常适合由数⼗或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置⽀持。
5、⽤于对象及JSON 数据的存储:Mongo 的BSON 数据格式⾮常适合⽂档化格式的存储及查询。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。