Redis、Memcached应用场景对比
环境
Redis官方网站: Redis - The Real-time Data Platform
Redis社区版本下载地址:Install Redis | Docs
Memcached官方网站:memcached - a distributed memory object caching system
Memcached下载地址:memcached - a distributed memory object caching system
Redis与Memcached应用场景对比
一、核心特性对比
对比维度 | Redis | Memcached |
---|---|---|
数据结构支持 | 支持字符串、哈希、列表、集合、有序集合等复杂数据结构,适合多样化数据操作 | 仅支持简单键值对存储,适用于单一数据模型场景 |
持久化能力 | 支持RDB快照和AOF日志持久化,数据可恢复 | 无持久化机制,宕机后数据丢失 |
内存管理 | 通过VM机制突破物理内存限制,支持大容量数据存储 | 使用固定内存分配(slab机制),适合中小规模数据缓存 |
性能表现 | 单核处理,小数据(<100KB)性能更优;支持复杂操作但高并发写入效率略低 | 多线程架构,大数据(>100KB)处理性能更高,适合纯缓存场景 |
扩展性 | 支持主从复制、集群模式,适合高可用场景 | 依赖第三方工具(如magent)实现分布式,扩展性较弱 |
二、典型应用场景对比
-
Redis适用场景
- 会话存储(Session Cache):通过持久化能力保障会话数据安全,支持高可靠性业务
- 实时排行榜/计数器:利用有序集合(Sorted Set)实现动态排序,适用于电商、社交等场景
- 消息队列:通过List、Pub/Sub等特性支持异步任务处理和事件驱动架构
- 复杂业务逻辑:结合Lua脚本和事务机制,满足数据一致性要求高的场景(如秒杀库存扣减)
-
Memcached适用场景
- 高频读取缓存:如静态页面缓存、数据库查询结果缓存,减轻数据库压力
- 临时数据存储:用户会话临时信息、非关键性数据(如页面片段缓存),无需持久化保障
- 大规模数据缓存:单Value值≤1MB时,多线程架构可高效处理高并发请求
三、选型建议
-
选择Redis的条件:
- 需要复杂数据结构或持久化能力
- 业务涉及实时数据处理或强一致性要求
- 系统需支持高可用集群和横向扩展
-
选择Memcached的条件:
- 仅需简单键值缓存且数据量较小
- 高并发大体积数据(>100KB)处理需求优先
- 轻量级部署,无需额外运维复杂度
综合建议:若业务场景以高性能缓存为主且无复杂数据处理需求,优先选择Memcached;若需支持多样化数据操作、持久化及高可用,Redis是更优选择
附件一:Redis组件POM依赖
Redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.4.4</version>
</dependency>
或者
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
附件二:Memcache组件POM依赖
memcache
<dependency>
<groupId>net.spy</groupId>
<artifactId>spymemcached</artifactId>
<version>2.12.3</version>
</dependency>
附件三:Redis基本操作
基础命令
1.ping(心跳检查)
ping //输入ping 命令,看到PONG响应,说明客户端与Redis的连接正常。
2.get/set(读写键值)
set name xiaoHong //set key value 会将指定 key-value写入到DB。
get name //get key 则会读取指定key的value值。
3.select(切换数据库)
select 1 //select db 索引来切换 DB。redis默认有 16 个数据库。默认使用的是 0 号 DB。
4.dbsize(查看key数量)
dbsize //命令可以查看当前数据库中 key 的数量。
5.flushdb(删除当前库中所有数据)
flushdb //删除当前库中所有数据,不影响其他DB。
6.flushall(删除所有DB中的数据)
flushall //清除redis所有DB中的数据
二、Key 操作命令
1.keys(正则匹配键名)
keys * //匹配所有的key
keys a* //匹配以a开头的key
//KEYS pattern 查找所有符合正则 pattern 的 key
//KEYS 速度非常快,但在一个大的数据库中使用它可能会阻塞当前服务器的服务。生产环境中一般不使用该命令,使用scan命令代替。
2.exists(检查key是否存在)
exists key //若 key 存在,返回 1 ,否则返回 0 。
3.del(删除指定一个或多个key)
del key1 key2 key3 //返回被删除 key 的数量,不存在的 key 会被忽略。
4.rename(修改key名)
rename key newKey //将key改名为newkey。
//当 key 和 newkey 相同,或 key 不存在时,会返回一个错误。
//当 newkey 已经存在时,RENAME 将覆盖旧值。
5.move(移动key数据库DB)
MOVE key db //将当前数据库的 key 移动到指定数据库 db 当中。
//如果当前数据库和目标数据库有相同名字的 key,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。
//移动成功返回 1 ,失败则返回 0 。
6.type(获取key储存的值类型)
type key //返回 key 所储存的值的类型
//有六种 none (key 不存在)、string (字符串)、list (列表)、set (集合)、zset (有序集)、hash (哈希表)
7.expire/pexpire(设置key有效期)
expire key seconds //为 key 设置过期时间。当 key 过期时(生存时间为 0),它会被自动删除。
//expire 的时间单位为秒,pexpire 的时间单位为毫秒。
//过期时间设置成功返回 1,key 不存在时返回 0 。rename 操作不会改变 key的过期时间。
8.ttl/pttl(获取key剩余生存时间)
ttl key //time to live,返回给定 key 的剩余生存时间。
// key 不存在时,返回 -2 。
// key 存在但没有设置时间时,返回 -1 。
// 返回 key 剩余生存时间。ttl 返回的时间单位为秒,pttl 返回的时间单位为毫秒。
9.persist(去除key的生存时间)
persist key //当生存时间移除成功返回 1;若 key 不存在或 key 没有设置生存时间,则返回 0。
10.randomkey(随机返回一个 key)
randomkey //当数据库不为空时,随机返回一个 key(不删除)。当数据库为空时,返回 nil。
11.scan(遍历数据库键)
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type] //SCAN 命令是一个基于游标 cursor 的迭代器
//cursor:本次迭代开始的游标。
//pattern:本次迭代要匹配的 key 的模式。
//count:本次迭代要从数据集里返回多少元素,默认值为 10 。
//type:本次迭代要返回的value 的类型,默认为所有类型。
//SCAN 命令被调用之后,会返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标,第二个元素则是一个数组, 数组中包含了所有被迭代的元素。
//用户在下次迭代时使用这个新游标作为 SCAN 命令的游标参数,以此来延续之前的迭代过程。
//当 SCAN 命令的游标参数被设置为 0 时,服务器将开始一次新的迭代。如果新游标返回 0表示迭代已结束。
//当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。
//由于 scan 命令每次执行都只会返回少量元素,所以该命令可以用于生产环境,而不会出现像 KEYS 命令带来的服务器阻塞问题。
hscan key cursor [MATCH pattern] [COUNT count] //遍历当前 db 中指定 Hash 表的所有 field-value 对
sscan key cursor [MATCH pattern] [COUNT count] //遍历当前 db 中指定 set 集合的所有元素
zscan key cursor [MATCH pattern] [COUNT count] //遍历当前 db 中指定有序集合的所有元素(数值与元素值)
附件四:Memcache基本操作
存储数据
Memcached提供了多种命令用于存储数据项,包括 set、add 和 replace。以下是这些命令的详细介绍:
set 命令
set 命令用于在缓存中存储一个数据项。如果键已经存在,则覆盖其现有值。
set <key> <flags> <exptime> <bytes> [noreply]\r\n
<value>\r\n
参数说明:
<key>:数据项的键。
<flags>:用户自定义的标志位,通常为0。
<exptime>:过期时间,单位为秒。
<bytes>:数据项的字节数。
[noreply]:可选参数,表示不需要服务器返回响应。
示例代码:
import memcache
# 连接Memcached服务器
mc = memcache.Client(['127.0.0.1:11211'])
# 存储数据
mc.set('key1', 'value1', time=60)
print("Set key1 to value1")
add 命令
add 命令用于在缓存中添加一个新的数据项。如果键已经存在,则不做任何操作。
add <key> <flags> <exptime> <bytes> [noreply]\r\n
<value>\r\n
示例代码:
# 添加数据
mc.add('key2', 'value2', time=60)
print("Added key2 with value2")
replace 命令
replace 命令用于替换缓存中已有的一个数据项。如果键不存在,则不做任何操作。
replace <key> <flags> <exptime> <bytes> [noreply]\r\n
<value>\r\n
示例代码:
# 替换数据
mc.replace('key1', 'new_value1', time=60)
print("Replaced key1 with new_value1")
检索数据
Memcached提供了 get 和 gets 命令用于检索数据项。
get 命令
get 命令用于检索一个或多个数据项的值。
get <key>*\r\n
示例代码:
# 检索数据
value = mc.get('key1')
print("Retrieved key1:", value)
3.2.2 gets 命令
gets 命令与 get 类似,但返回的数据项还包括一个唯一的标识符(cas token),用于数据更新时的乐观锁定。
gets <key>*\r\n
示例代码:
# 检索数据及其唯一标识符
result = mc.gets('key1')
print("Retrieved key1 with CAS token:", result)
更新数据
Memcached提供了 cas 命令用于数据项的条件更新,利用唯一标识符进行乐观锁定。
cas 命令
cas 命令用于更新一个数据项,但前提是数据项的唯一标识符未改变。
cas <key> <flags> <exptime> <bytes> <cas token> [noreply]\r\n
<value>\r\n
示例代码:
# 条件更新数据
cas_token = result[1]
mc.cas('key1', 'updated_value1', cas_token, time=60)
print("Conditionally updated key1 with updated_value1")
删除数据
Memcached提供了 delete 命令用于删除数据项。
delete 命令
delete 命令用于删除一个数据项。
delete <key> [noreply]\r\n
示例代码:
# 删除数据
mc.delete('key1')
print("Deleted key1")
计数器操作
Memcached提供了 incr 和 decr 命令用于操作数据项的计数器值。
incr 命令
incr 命令用于增加数据项的计数器值。
incr <key> <value> [noreply]\r\n
示例代码:
# 增加计数器
mc.set('counter', 10)
mc.incr('counter', 5)
counter_value = mc.get('counter')
print("Counter value after increment:", counter_value)
decr 命令
decr 命令用于减少数据项的计数器值。
decr <key> <value> [noreply]\r\n
示例代码:
# 减少计数器
mc.decr('counter', 3)
counter_value = mc.get('counter')
print("Counter value after decrement:", counter_value)