Redis 和 Memcached 各有什么优缺点,主要的应用场景是什么样的

Redis 和 Memcached 各有什么优缺点,主要的应用场景是什么样的,第1张

Redis的作者Salvatore Sanfilippo曾经对这两种基于内存数据存储系统进行过比较:

1、Redis支持服务器端的数据 *** 作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据 *** 作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的 *** 作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和 *** 作,那么Redis会是不错的选择。

2、内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。

3、性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。

具体为什么会出现上面的结论,以下为收集到的资料:

1、数据类型支持不同

与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多。最为常用的数据类型主要由五种:String、Hash、List、Set和Sorted Set。Redis内部使用一个redisObject对象来表示所有的key和value。redisObject最主要的信息如图所示:

type代表一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:”123″ “456”这样的字符串。只有打开了Redis的虚拟内存功能,vm字段字段才会真正的分配内存,该功能默认是关闭状态的。

1)String

常用命令:set/get/decr/incr/mget等;

应用场景:String是最常用的一种数据类型,普通的key/value存储都可以归为此类;

实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr、decr等 *** 作时会转成数值型进行计算,此时redisObject的encoding字段为int。

2)Hash

常用命令:hget/hset/hgetall等

应用场景:我们要存储一个用户信息对象数据,其中包括用户ID、用户姓名、年龄和生日,通过用户ID我们希望获取该用户的姓名或者年龄或者生日;

实现方式:Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。如图所示,Key是用户ID, value是一个Map。这个Map的key是成员的属性名,value是属性值。这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以 *** 作对应属性数据。当前HashMap的实现有两种方式:当HashMap的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,这时对应的value的redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

3)List

常用命令:lpush/rpush/lpop/rpop/lrange等;

应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现;

实现方式:Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便 *** 作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

4)Set

常用命令:sadd/spop/smembers/sunion等;

应用场景:Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的;

实现方式:set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

5)Sorted Set

常用命令:zadd/zrange/zrem/zcard等;

应用场景:Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

2、内存管理机制不同

在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。当物理内存用完时,Redis可以将一些很久没用到的value交换到磁盘。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的 *** 作,Redis根据“swappability = agelog(size_in_memory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap *** 作的。同时由于Redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap *** 作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个 *** 作,直到子线程完成swap *** 作后才可以进行修改。当从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行批量 *** 作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发 *** 作,减少阻塞的时间。

对于像Redis和Memcached这种基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键因素。传统C语言中的malloc/free函数是最常用的分配和释放内存的方法,但是这种方法存在着很大的缺陷:首先,对于开发人员来说不匹配的malloc和free容易造成内存泄露;其次频繁调用会造成大量内存碎片无法回收重新利用,降低内存利用率;最后作为系统调用,其系统开销远远大于一般函数调用。所以,为了提高内存的管理效率,高效的内存管理方案都不会直接使用malloc/free调用。Redis和Memcached均使用了自身设计的内存管理机制,但是实现方法存在很大的差异,下面将会对两者的内存管理机制分别进行介绍。

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。Slab Allocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在Slab Allocation系统里,而Memcached的其它内存请求则通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响Slab Allocation的原理相当简单。 如图所示,它首先从 *** 作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制。假定图中Growth Factor的取值为125,如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推。

当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。从以上过程我们可以看出Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图 所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。

Redis的内存管理主要通过源码中zmalloch和zmallocc两个文件来实现的。Redis为了方便内存的管理,在分配一块内存之后,会将这块内存的大小存入内存块的头部。如图所示,real_ptr是redis调用malloc后返回的指针。redis将内存块的大小size存入头部,size所占据的内存大小是已知的,为size_t类型的长度,然后返回ret_ptr。当需要释放内存的时候,ret_ptr被传给内存管理程序。通过ret_ptr,程序可以很容易的算出real_ptr的值,然后将real_ptr传给free释放内存。

Redis通过定义一个数组来记录所有的内存分配情况,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。zmallocc中有一个静态变量used_memory用来记录当前分配的内存总大小。所以,总的来看,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方法来说,要简单很多。

3、数据持久化支持

Redis虽然是基于内存的存储系统,但是它本身是支持内存数据的持久化的,而且提供两种主要的持久化策略:RDB快照和AOF日志。而memcached是不支持数据持久化 *** 作的。

1)RDB快照

Redis支持将当前数据的快照存成一个数据文件的持久化机制,即RDB快照。但是一个持续写入的数据库如何生成快照呢?Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件。我们可以通过Redis的save指令来配置RDB快照生成的时机,比如配置10分钟就生成快照,也可以配置有1000次写入就生成快照,也可以多个规则一起实施。这些规则的定义就在Redis的配置文件中,你也可以通过Redis的CONFIG SET命令在Redis运行时设置规则,不需要重启Redis。

Redis的RDB文件不会坏掉,因为其写 *** 作是在一个新进程中进行的,当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件,这样在任何时候出现故障,Redis的RDB文件都总是可用的。同时,Redis的RDB文件也是Redis主从同步内部实现中的一环。RDB有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。在某些业务下,这是可以忍受的。

2)AOF日志

AOF日志的全称是append only file,它是一个追加写入的日志文件。与一般数据库的binlog不同的是,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。只有那些会导致数据发生修改的命令才会追加到AOF文件。每一条修改数据的命令都生成一条日志,AOF文件会越来越大,所以Redis又提供了一个功能,叫做AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一条记录的 *** 作只会有一次,而不像一份老文件那样,可能记录了对同一个值的多次 *** 作。其生成过程和RDB类似,也是fork一个进程,直接遍历数据,写入新的AOF临时文件。在写入新文件的过程中,所有的写 *** 作日志还是会写到原来老的AOF文件中,同时还会记录在内存缓冲区中。当重完 *** 作完成后,会将所有缓冲区中的日志一次性写入到临时文件中。然后调用原子性的rename命令用新的AOF文件取代老的AOF文件。

AOF是一个写文件 *** 作,其目的是将 *** 作日志写到磁盘上,所以它也同样会遇到我们上面说的写 *** 作的流程。在Redis中对AOF调用write写入后,通过appendfsync选项来控制调用fsync将其写到磁盘上的时间,下面appendfsync的三个设置项,安全强度逐渐变强。

appendfsync no 当设置appendfsync为no的时候,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于 *** 作系统的调试了。对大多数Linux *** 作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。

appendfsync everysec 当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。但是当这一次的fsync调用时长超过1秒时。Redis会采取延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时文件描述符会被阻塞,所以当前的写 *** 作就会阻塞。所以结论就是,在绝大多数情况下,Redis会每隔一秒进行一次fsync。在最坏的情况下,两秒钟会进行一次fsync *** 作。这一 *** 作在大多数数据库系统中被称为group commit,就是组合多次写 *** 作的数据,一次性将日志写到磁盘。

appednfsync always 当设置appendfsync为always时,每一次写 *** 作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响。

对于一般性的业务需求,建议使用RDB的方式进行持久化,原因是RDB的开销并相比AOF日志要低很多,对于那些无法忍数据丢失的应用,建议使用AOF日志。

4、集群管理的不同

Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。

Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。下图给出了Memcached的分布式存储实现架构。当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法计算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,然后直接向该节点发送查询请求以获取数据。

相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。最新版本的Redis已经支持了分布式存储功能。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。下图给出Redis Cluster的分布式存储架构,其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成4096个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。这样在整个集群中,任意两个节点的宕机都不会导致数据的不可用。当Master节点退出后,集群会自动选择一个Slave节点成为新的Master节点。

1、数组:存放在内存中,存取速度快,但不能持久保存

2、文件:存放在磁盘等存储介质中,存取速度较内存慢,但能持久保存

3数据库:数据以特定的文件格式保存,主要特点是数据搜索很方便快捷。

现在大数据是一个十分火热的技术,这也使得很多人都开始关注大数据的任何动态,因为大数据在某种程度上来说能够影响我们的生活。在这篇文章中我们就给大家介绍一下大数据的分布式数据库的发展趋势,希望这篇文章能够帮助大家更好理解大数据的分布式数据库的发展趋势。

其实不论是Hadoop还是分布式数据库,技术体系上两者都已经向着计算存储层分离的方式演进。对于Hadoop来说这一趋势非常明显,HDFS存储与YARN调度计算的分离,使得计算与存储均可以按需横向扩展。而分布式数据库近年来也在遵循类似的趋势,很多数据库已经将底层存储与上层的SQL引擎进行剥离。传统的XML数据库、OO数据库、与pre-RDBMS正在消亡;新兴领域文档类数据库、图数据库、Table-Style数据库与Multi-Model数据库正在扩大自身影响;传统关系型数据库、列存储数据库、内存分析型数据库正在考虑转型。可以看到,从技术完整性与成熟度来看,Hadoop确实还处于相对早期的形态。直到今天,很多技术在很多企业应用中需要大量的手工调优才能够勉强运行。同时,Hadoop的主要应用场景一直以来面向批处理分析型业务,传统数据库在线联机处理部分不是其主要的发展方向。同时Hadoop技术由于开源生态体系过于庞大,同时参与改造的厂商太多,使得用户很难完全熟悉整个体系,这一方面大大增加了开发的复杂度,提升了用户使用的难度,另一方面则是各个厂商之间维护不同版本,使得产品的发展方向可能与开源版本差别逐渐加大。

而分布式数据库领域经历了几十年的磨练,传统RDBMS的MPP技术早已经炉火纯青,在分类众多的分布式数据库中,其主要发展方向基本可以分为“分布式联机数据库”与“分布式分析型数据库”两种。对比Hadoop与分布式数据库可以看出,Hadoop的产品发展方向定位,与分布式数据库中列存储数据库相当重叠而在高并发联机交易场景,在Hadoop中除了HBase能够勉强沾边以外,分布式数据库则占据绝对的优势。目前,从Hadoop行业的发展来看,很多厂商而是将其定位改变为数据科学与机器学习服务商。因此,从商业模式上看以Hadoop分销的商业模式基本已经宣告结束,用户已经体验到维护整个Hadoop平台的困难而不愿被强迫购买整个平台。大量用户更愿意把原来Hadoop的部件拆开灵活使用,为使用场景和结果买单,而非平台本身买单。另外一个细分市场——非结构化小文件存储,一直以来都是对象存储、块存储,与分布式文件系统的主战场。如今,一些新一代数据库也开始进入该领域,可以预见在未来的几年中,小型非结构化文件存储也可能成为具备多模数据处理能力的分布式数据库的战场之一。

我们在这篇文章中给大家介绍了很多有关大数据分布数据库的发展前景,通过这篇文章我们不难发现数据库的发展是一个极其重要的内容,只有搭建分布式数据库,大数据才能够更好地为我们服务。

说下常见的关系数据库:

1oracle,豪无争议处于霸主地位,特点是体系健全,处理效率高,安全可靠;面对不同的应用场景,拥有针对性的解决方案,有小企业应用的单实例数据库,高可靠性应用的RAC方案,主备方式的DATAGuard方案,数据同步的goldengate。

2mysql,开源软件,优势是开源带来的群策群力能量,它的灵活性以及轻量级管理使他获得广泛的应用。但是目前mysql已经被oracle公司收购,是否影响它的开源特征值得关注。

3sqlserver,微软公司的产品,只能应用于windows环境,服务于中小应用中,优势是方便windows用户的界面 *** 作。

最后,提下IBM公司的DB数据库,因为安全,很早就已经广泛应用于银行金融界。

因为互联网、大数据的广泛应用,衍生了很多特定领域范畴的非关系型数据库,例如键值型数据库hbase,内存型的mongdb等。这些nosql级的数据库,与传统关系数据库形成互补,有利支撑了互联网的快速发展。

MySQL的优点:

1. 它使用的核心线程是完全多线程,支持多处理器。

2. 有多种列类型:1、2、3、4、和8字节长度自有符号/无符号整数、FLOAT、DOUBLE、CHAR、VARCHAR、TEXT、BLOB、DATE、TIME、DATETIME、 TIMESTAMP、YEAR、和ENUM类型。

3. 它通过一个高度优化的类库实现SQL函数库并像他们能达到的一样快速,通常在查询初始化后不该有任何内存分配。没有内存漏洞。

4. 全面支持SQL的GROUP BY和ORDER BY子句,支持聚合函数(COUNT()、COUNT(DISTINCT)、AVG()、STD()、SUM()、MAX()和MIN())。你可以在同一查询中混来自不同数据库的表。

5. 支持ANSI SQL的LEFT 0UTER JOIN和ODBC。

6. 所有列都有缺省值。你可以用INSERT插入一个表列的子集,那些没用明确给定值的列设置为他们的决省值。

7. MySQL可以工作在不同的平台上。支持C、C++、Java、Perl、PHP、Python和TCL API。

数据库共有3种类型,为关系数据库、非关系型数据库和键值数据库。

1、关系数据库

MySQL、MariaDB(MySQL的代替品,英文维基百科从MySQL转向MariaDB)、Percona Server(MySQL的代替品·)、PostgreSQL、Microsoft Access、Microsoft SQL Server、Google Fusion Tables、FileMaker、Oracle数据库、Sybase、dBASE、Clipper、FoxPro、foshub。

几乎所有的数据库管理系统都配备了一个开放式数据库连接(ODBC)驱动程序,令各个数据库之间得以互相集成。

2、非关系型数据库(NoSQL)

BigTable(Google)、Cassandra、MongoDB、CouchDB。

3、键值(key-value)数据库

Apache Cassandra(为Facebook所使用):高度可扩展、Dynamo、LevelDB(Google)。

扩展资料:

数据库模型:对象模型、层次模型(轻量级数据访问协议)、网状模型(大型数据储存)、关系模型、面向对象模型、半结构化模型、平面模型(表格模型,一般在形式上是一个二维数组。如表格模型数据Excel)。

数据库的架构可以大致区分为三个概括层次:内层、概念层和外层。

参考资料来源:百度百科—数据库

以上就是关于Redis 和 Memcached 各有什么优缺点,主要的应用场景是什么样的全部的内容,包括:Redis 和 Memcached 各有什么优缺点,主要的应用场景是什么样的、编程时存储数据时可以用到 数组 / 文件 / SQL数据库 ,他们各自的优点和缺点是什么 简略点、大数据的分布式数据库的发展趋势如何(分布式数据库的优点)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9630421.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存