Redis和Memcached到底有什么区别?
前言
我们都知道,Redis和Memcached都是内存数据库,它们的访问速度非常之快。但我们在开发过程中,这两个内存数据库,我们到底要如何选择呢?它们的优劣都有哪些?为什么现在看Redis要比Memcached更火一些?
这篇文章,我们就从各个方面来对比这两个内存数据库的差异,方便你在使用时,做出最符合业务需要的选择。
要分析它们的区别,主要从以下几个方面对比:
- 线程模型
- 数据结构
- 淘汰策略
- 管道与事物
- 持久化
- 高可用
- 集群化
线程模型
要说性能,必须要分析它们的服务模型。
Memcached处理请求采用多线程模型,并且基于IO多路复用技术,主线程接收到请求后,分发给子线程处理。
这样做好的好处是,当某个请求处理比较耗时,不会影响到其他请求的处理。
当然,缺点是CPU的多线程切换必然存在性能损耗,同时,多线程在访问共享资源时必然要加锁,也会在一定程度上降低性能。
Redis同样采用IO多路复用技术,但它处理请求采用是单线程模型,从接收请求到处理数据都在一个线程中完成。
这意味着使用Redis,一旦某个请求处理耗时比较长,那么整个Redis就会阻塞住,直到这个请求处理完成后返回,才能处理下一个请求,使用Redis时一定要避免复杂的耗时操作。
单线程的好处是,少了CPU的上下文切换损耗,没有了多线程访问资源的锁竞争,但缺点是无法利用CPU多核的性能。
由于Redis是内存数据库,它的访问速度非常地快,所以它的性能瓶颈不在于CPU,而在于内存和网络带宽,这也是作者采用单线程模型的主要原因。同时,单线程对于程序开发非常友好,调试起来也很方便。开发多线程程序必然会增加一定的调试难度。
因此,当我们的业务使用key的数据比较大时,Memcached的访问性能要比Redis好一些。如果key的数据比较小,两者差别并不大。
严格来说,Redis的单线程指的是处理请求的线程,它本身还有其他线程在工作,例如有其他线程用来异步处理耗时的任务。
Redis6.0又进一步完善了多线程,在接收请求和发送请求时使用多线,进一步提高了处理性能。
数据结构
Memcached支持的数据结构很单一,仅支持string类型的操作。并且对于value的大小限制必须在1MB以下,过期时间不能超过30天。
而Redis支持的数据结构非常丰富,除了常用的数据类型string、list、hash、set、zset之外,还可以使用geo、hyperLogLog数据类型。
使用Memcached时,我们只能把数据序列化后写入到Memcached中。然后再从Memcached中读取数据,再反序列化为我们需要的格式,只能“整存整取”。
而Redis对于不同的数据结构可以采用不同的操作方法,非常灵活。
- list:可以方便的构建一个链表,或者当作队列使用
- hash:灵活地操作我们需要的字段,进行“整存零取”、“零存整取”以及“零存零取”
- set:构建一个不重复的集合,并方便地进行差集、并集运算
- zset:构建一个排行榜,或带有权重的列表
- geo:用于地图相关的业务,标识两个地点的坐标,以及计算它们的距离
- hyperLogLog:使用非常少的内存计算UV
总之,Redis正是因为提供了这么丰富的数据结构,近几年在内存数据库领域大放异彩,为我们的业务开发提供了极大的便利。
淘汰策略
Memcached必须设置整个实例的内存上限,数据达到上限后触发LRU淘汰机制,优先淘汰不常用使用的数据。
但它的数据淘汰机制存在一些问题:刚写入的数据可能会被优先淘汰掉,这个问题主要是它本身内存管理设计机制导致的。
Redis没有限制必须设置内存上限,如果内存足够使用,Redis可以使用足够大的内存。
同时Redis提供了多种淘汰策略:
- volatile-lru:从过期key中按LRU机制淘汰
- allkeys-lru:在所有key中按LRU机制淘汰
- volatile-random:在过期key中随机淘汰key
- allkeys-random:在所有key中随机淘汰key
- volatile-ttl:优先淘汰最近要过期的key
- volatile-lfu:在所有key中按LFU机制淘汰
- allkeys-lfu:在过期key中按LFU机制淘汰
我们可以针对业务场景,使用不同的数据淘汰策略。
管道与事物
Redis还支持管道功能,客户端一次性打包发送多条命令到服务端,服务端依次处理客户端发来的命令。这样可以减少来回往来的网络IO次数,提供高访问性能。
另外它还支持事物,这里所说的事物并不是MySQL那样严格的事物模型,这种事物模型是Redis特有的。
一般事物会配合管道一块使用,客户端一次性打包发送多条命令到服务端,并且标识这些命令必须严格按顺序执行,不能被其他客户端打断。同时执行事务之前,客户端可以告诉服务端某个key稍后会进行相关操作,如果这个客户端在操作这个key之前,有其他客户端对这个key进行更改,那么当前客户端在执行这些命令时会放弃整个事务操作,保证一致性。
持久化
Memcached不支持数据的持久化,如果Memcached服务宕机,那么这个节点的数据将全部丢失。
Redis支持将数据持久化磁盘上,提供RDB和AOF两种方式:
- RDB:将整个实例中的数据快照到磁盘上,全量持久化
- AOF:把每一个写命令持久到磁盘,增量持久化
Redis使用这两种方式相互配合,完成数据完整性保障,最大程度降低服务宕机导致的数据丢失问题。
高可用
Memcached没有主从复制架构,只能单节点部署,如果节点宕机,那么该节点数据全部丢失。业务需要对这种情况做兼容处理,当某个节点不可用时,把数据写入到其他节点以降低对业务的影响。
Redis拥有主从复制架构,两个节点组成主从架构,从可以实时同步主的数据,提高整个Redis服务的可用性。
同时Redis还提供了哨兵节点,在主节点宕机时,主动把从节点提升为主节点,继续提供服务。
主从两个节点还可以提供读写分离功能,进一步提高程序访问的性能。
集群化
Memcached和Redis都是由多个节点组成集群对外提供服务,但他们的机制也有所不同。
Memcached的集群化是在客户端采用一致性哈希算法向指定节点发送数据,当一个节点宕机时,其他节点会分担这个节点的请求。
而Redis集群化采用的是每个节点维护一部分虚拟槽位,通过key的哈希计算,将key映射到具体的虚拟槽位上,这个槽位再映射到具体的Redis节点。
同时每个Redis节点都包含至少一个从节点,组成主从架构,进一步提高每个节点的高可用能力。
当增加或下线节点时,需要手动触发数据迁移,重新进行哈希槽位映射。
Redis官方的集群化解决方案为Redis cluster,它采用无中心化的设计。另外也有第三方的采用中心化设计proxy方式的集群化解决方案,例如Codis、Twemproxy。
后面我会专门针对Redis集群化写一些文章详细介绍其内部的原理。
总结
从以上几个方面进行对比分析,总结如下表。
# | Memcached | Redis |
---|---|---|
线程模型 | 多线程 | 单线程 |
数据结构 | 仅支持string、value最大1M、过期时间不能超过30天 | string、list、hash、set、zset、geo、hyperLogLog |
淘汰策略 | LRU | LRU、LFU、随机等多种策略 |
管道与事物 | 不支持 | 支持 |
持久化 | 不支持 | 支持 |
高可用 | 不支持 | 主从复制+哨兵 |
集群化 | 客户端一致性哈希算法 | 主从复制+哨兵+固定哈希槽位 |
整体来说,Redis提供了非常丰富的功能,而且性能基本上与Memcached相差无几,这也是它最近这几年占领内存数据库鳌头的原因。
如果你的业务需要各种数据结构给予支撑,同时要求数据的高可用保障,那么选择Redis是比较合适的。
如果你的业务非常简单,只是简单的set/get,并且对于内存使用并不高,那么使用简单的Memcached足够。
- 本文作者: Kaito
- 本文链接: http://kaito-kidd.com/2020/06/28/redis-vs-memcached/
Redis和Memcached到底有什么区别?的更多相关文章
- redis和memcached的优缺点及区别
1. 使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,li ...
- C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别
C#语法——泛型的多种应用 本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...
- Redis与Memcached的区别
传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量 ...
- Redis和Memcached的区别详解
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/119.html?1455855360 Redis的作者Salvatore ...
- Redis和Memcached的区别
From: https://www.biaodianfu.com/redis-vs-memcached.html Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储 ...
- 白话Redis与Memcached区别
如果简单地比较Redis与Memcached的区别,外在的区别是: 1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储. 2 Redis ...
- 也谈谈 Redis 和 Memcached 的区别
本文作者: 伯乐在线 - 朱小厮 . 说到redis就会联想到memcached,反之亦然.了解过两者的同学有那么个大致的印象: redis与memcached相比,比仅支持简单的key-value数 ...
- 【转载】Redis与Memcached的区别
传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量 ...
- (转)Redis与Memcached的区别
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储. 2 Redis支持 ...
随机推荐
- Lua中的元表(metatable)、元方法(metamethod)详解
在第一次看见这两样东西的时候,可能会觉得它很深奥,但其实很好理解,虽然实际上它可能真的很深奥.(小若:停!滚粗.) 1.知道为什么1 + 1 = 2吗? 为什么在Lua中,1+1会等于2呢?(小若:难 ...
- sizeof()用法汇总-(转自风雷)
sizeof()功能:计算数据空间的字节数 1.与strlen()比较 strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素. ...
- 企业定制CRM系统的5步流程
由于所处的行业不同,不同的企业对CRM系统的需求也不同.除了行业通用的功能之外,每个企业都有自己独特的功能需求.为了让CRM系统跟上这种需求的变化,CRM厂商通常也会提供CRM系统定制开发功能来满足不 ...
- 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析
最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...
- 数据流分析软件SQLFlow的工作原理
SQLFlow是一个可视化的在线处理SQL对象依赖关系的工具,只需要上传你的SQL脚本,它可以自动分析SQL里的数据对象,包括database.schema.table.view.column.pro ...
- volatile 关键字笔记
你应该知道的 volatile 关键字 当一个变量被 volatile 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据. ...
- Tensorflow 2.0 搭建神经网络(局部)
前向传播 tensorflow.keras 搭建网络时,内部的网络可以直接完成所有层的前向计算.全连接Dense() 层,最后一层的神经元的个数需要和最后一层线性函数 w x + b 的维度对应上,中 ...
- 改进遗传算法之CHC算法简要介绍
简要介绍: CHC算法是Eshelman于1991年提出的一种改进的遗传算法的缩称,第一个C代表跨世代精英选择(Cross generational elitist selection)策略, H代表 ...
- Mobileye 自动驾驶策略(二)
Mobileye 自动驾驶策略(二) 与多方都成功进行了合作,其中比较大型的合作包括法雷奥.百度和中国 ITS. 法雷奥是最近的的 Tier 1 合作伙伴,法雷奥和 Mobileye 签署协议,表示未 ...
- PyTorch神经网络集成技术
PyTorch神经网络集成技术 create_python_neuropod 将任意python代码打包为一个neurood包. create_python_neuropod( neuropod_pa ...