redis\memcahce\mongodb\leveldb总结

本文对比分析了Redis、Memcache、MongoDB和LevelDb四种NoSQL数据库的特点,涵盖了数据存储方式、内存管理、集群能力、分布式锁机制及应用场景等方面,为开发者提供了全面的选择依据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 redismemcachemongodbleveldb
简要介绍Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。
Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,
但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。
对此有2种解决方法:
1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。 
2.服务器角度,利用setnx实现锁。
Memcached最大的好处就是它带来了极佳的水平可扩展性,特别是在一个巨大的系统中。由于客户端自己做了一次哈希,那么我们很容易增加大量memcached到集群中。memcached之间没有相互通信,因此不会增加 memcached的负载;没有多播协议,不会网络通信量爆炸(implode)。memcached的集群很好用。内存不够了?增加几台 memcached吧;CPU不够用了?再增加几台吧;有多余的内存?在增加几台吧,不要浪费了。介于关系型和非关系型之间的一个产品MongoDB 数据结构比较单一,但是支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富。 首先,LevelDb是一个持久化存储的KV系统,和Redis这种内存型的KV系统不同,LevelDb不会像Redis一样狂吃内存,而是将大部分数据存储到磁盘上。
 其次,LevleDb在存储数据时,是根据记录的key值有序存储的,就是说相邻的key值在存储文件中是依次顺序存储的,而应用可以自定义key大小比较函数,LevleDb会按照用户定义的比较函数依序存储这些记录。
 再次,像大多数KV系统一样,LevelDb的操作接口很简单,基本操作包括写记录,读记录以及删除记录。也支持针对多条操作的原子批量操作。
 LevelDb支持数据快照(snapshot)功能,使得读取操作不受写操作影响,可以在读操作过程中始终看到一致的数据。
  LevelDb还支持数据压缩等操作,这对于减小存储空间以及增快IO效率都有直接的帮助
数据类型String、Hash、List、Set、Sorted Set(Zset);key-valuemongodb是文档型的非关系型数据库,MongoDB更类似MySQL,支持字段索引、游标操作,其优势在于查询功能比较强大,擅长查询JSON数据,能存储海量数据    SSTable中的某个文件属于特定层级,而且其存储的记录是key有序的,那么必然有文件中的最小key和最大key,这是非常重要的信息,LevelDb应该记下这些信息。Manifest就是干这个的,它记载了SSTable各个文件的管理信息,比如属于哪个Level,文件名称叫啥,最小key和最大key各自是多少。
可靠性:数据持久化和数据恢复支持持久化(RDB、AOF)不支持持久化  
可用性(单点问题)一主多从或一主一从,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题;
所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。
一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡
利用magent做一主多从或一主一从;Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题mongoDB支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制 
数据一致性(事物支持)事务支持比较弱,只能保证事务中的每个操作连续执行并发场景下,用cas(compare and swap)保证一致性,不支持事务不支持事务 
数据存储内存数据库内存数据库将热点数据放入内存,其他数据存在磁盘采用binlog方式支持持久化的可靠性;通过mmap的方式映射到内存某个区域内 
内存管理机制Slab Allocation机制:按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。主要的cache机制是LRU(最近最少使用Least Recently Used)算法+超时失效。可用于缓存、消息、按key设置过期时间,过期后将会自动删除使用zmalloc 构成LevelDb静态结构的包括六个主要部分:内存中的MemTable和Immutable MemTable以及磁盘上的几种主要文件:Current文件,Manifest文件,log文件以及SSTable文件。
集群在服务器端构建分布式存储,Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能;在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。哨兵机制(sentinel),来监控各个节点之间的状态。Redis集群通常具有高可用、可扩展性、分布式、容错特性本身并不支持分布式,在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储MongoDB 集群技术比较成熟, 内置 GridFS分布式文件系统支持大容量的存储,.内置 ShardingLog文件用于系统崩溃恢复而不丢失数据,假如没有Log文件,因为写入的记录刚开始是保存在内存中的,此时如果系统崩溃,内存中的数据还没有来得及Dump到磁盘,所以会丢失数据(Redis就存在这个问题)。为了避免这种情况,LevelDb在写入内存前先将操作记录到Log文件中,然后再记入内存中,这样即使系统崩溃,也可以从Log文件中恢复内存中的Memtable,不会造成数据的丢失。
分布式存储1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
4. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
6. no-enviction(驱逐):禁止驱逐数据
服务器端并不支持分布式,而是在客户端程序中设置分布式。
如果有多个memcache服务器,那么他们之间并不互相通信,数据也无法同步。所以在很多语言对memcache操作的类库中都可以配置,然后根据相应的路由算法决定将数据存储在哪个服务器中。
MongoDB数据库分布式存储也叫分片管理。是将数据库里面存储的数据分散存储在不同的机器上面。MongoDB分片的基本思想就是将集合切分成小块。这些块分散到若干片里面,每个片只负责总数据的一部分。应用程序不必知道哪片对应哪些数据,甚至不需要知道数据已经被拆分了,所以在分片之前要运行一个路由进程,该进程名为mongos。monogs用来发送请求。当Memtable插入的数据占用内存到了一个界限后,需要将内存的记录导出到外存文件中,LevleDb会生成新的Log文件和Memtable,原先的Memtable就成为Immutable Memtable,这个Memtable的内容是不可更改的,只能读不能写入或者删除。新到来的数据被记入新的Log文件和Memtable,LevelDb后台调度会将Immutable Memtable的数据导出到磁盘,形成一个新的SSTable文件。SSTable就是由内存中的数据不断导出并进行Compaction操作后形成的,而且SSTable的所有文件是一种层级结构,第一层为Level 0,第二层为Level 1,依次类推,层级逐渐增高,这也是为何称之为LevelDb的原因。
分布式锁用setnx命令。key是锁的唯一标识,按业务来决定命名,value为当前线程的线程IDload db之前先add一个mutex key, mutex key add成功之后再去做加载db, 如果add失败则sleep之后重试读取原cache数据。为了防止死锁,mutex key也需要设置过期时间Mongodb使用读写锁来允许很多用户同时去读一个资源,比如数据库或者集合。读采用的是共享锁,写采用的是排它锁。    SSTable中的文件是Key有序的,需要注意的一点是:Level 0的SSTable文件(后缀为.sst)和其它Level的文件相比有特殊性:这个层级内的.sst文件,两个文件可能存在key重叠,对于其它Level的SSTable文件来说,则不会出现同一层级内.sst文件的key重叠现象以保证它们的key值是不会重叠的。这点需要特别注意,后面您会看到很多操作的差异都是由于这个原因造成的。
线程单线程操作支持多核多线程,基于libevent的事件处理      SSTable中的某个文件属于特定层级,而且其存储的记录是key有序的,那么必然有文件中的最小key和最大key,这是非常重要的信息,LevelDb应该记下这些信息。Manifest就是干这个的,它记载了SSTable各个文件的管理信息,比如属于哪个Level,文件名称叫啥,最小key和最大key各自是多少。
应用场景Redis除了作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统(如新浪微博的计数和微博发布部分系统,对数据安全性、读写要求都很高)。适用于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等;动态系统中减轻数据库负载,提升性能;做缓存,适合多读少写,大数据量的情况(如人人网大量查询用户信息、好友信息、文章信息等)多写少读,保证海量数据存储时,保证查询性能;用类json格式存储LevelDb的写操作要大大快于读操作,而顺序读写操作则大大快于随机读写操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值