Redis 与 Memcached 的区别及 Redis 应用场景

老牛浏览 344评论 0发表于

1. MySQL + Memcached 架构的问题

Memcached 采用「客户端-服务器」的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端 Library 可以用任何语言实现。

Memcached 服务器使用基于 Slab 的内存管理方式,有利于减少内存碎片和频繁分配销毁内存所带来的开销。各个 Slab 按需动态分配一个 page 的内存(和 4K page的概念不同,这里默认 page 为 1M),page 内部按照不同 slab class 的尺寸再划分为内存 chunk 供服务器存储 KV 键值对使用(slab 机制相当于内存池机制,实现从操作系统分配一大块内存,然后 memcached 自己管理这块内存,负责分配与回收。)

2. 内存分配机制介绍

实际 MySQL 是适合进行海量数据存储的,通过 Memcached 将热点数据加载到 cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:

  1. MySQL 需要不断进行拆库拆表,Memcached 也需不断跟着扩容,扩容和维护工作占据大量开发时间

  2. Memcached 与 MySQL 数据库数据一致性问题

  3. Memcached 数据命中率低或 down 机,大量访问直接穿透到 DB,MySQL 无法支撑

  4. 跨机房 cache 同步问题

3. 众多 NoSQL 百花齐放,如何选择

总体上这些 NoSQL 主要用于解决以下几种问题:

  1. 少量数据存储,高速读写访问。此类产品通过数据全部 in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是 Redis 最主要的适用场景

  2. 海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。这方面最具代表性的是 dynamo 和 bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过 gossip 方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和 redo log,然后定期 compat 归并到磁盘上,将随机写优化为顺序写,提高写入性能

  3. Schema free,auto-sharding 等。比如目前常见的一些文档数据库都是支持 schema-free 的,直接存储 json 格式数据,并且支持 auto-sharding 等功能,比如 mongodb

Redis 最适合所有数据 in-momory 的场景,虽然 Redis 也提供持久化功能,但实际更多的是一个 disk-backed 的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎 Redis 更像一个加强版的 Memcached,那么何时使用 Memcached,何时使用Redis呢?

4. Memcache 和 Redis的比较

4.1 性能方面

没有必要过多的关心性能,因为二者的性能都已经足够高了。无论你使用哪一个,每秒处理请求的次数都不会成为瓶颈。(比如瓶颈可能会在网卡)

4.2 内存使用效率

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

4.3 数据持久化

如果你对数据持久化和数据同步有所要求,那么推荐你选择 Redis,因为这两个特性 Memcached 都不具备。

4.4 数据结构

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

4.5 网络 IO 模型方面

Memcached 是多线程,分为监听线程、worker 线程,引入锁,带来了性能损耗。Redis 使用单线程的 IO 复用模型,将速度优势发挥到最大,也提供了较简单的计算功能。

4.6 内存管理方面

Memcached 使用预分配的内存池的方式,带来一定程度的空间浪费并且在内存仍然有很大空间时,新的数据也可能会被剔除,而 Redis 使用现场申请内存的方式来存储数据,不会剔除任何非临时数据 Redis 更适合作为存储而不是 cache 数据的一致性方面:Memcached 提供了 cas 命令来保证。而 Redis 提供了事务的功能,可以保证一串命令的原子性,中间不会被任何操作打断。

如果简单地比较 Redis 与 Memcached 的区别,大多数都会得到以下观点:

  1. Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储

  2. Redis 支持数据的备份,即 master-slave 模式的数据备份

  3. Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用

  4. Redis 可以实现主从复制,实现故障恢复

  5. Redis 的 Sharding 技术: 很容易将数据分布到多个 Redis 实例中

5. Redis 数据类型

Redis 最为常用的数据类型主要有以下:

5.1 String(字符串)

string 是 Redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。

string 类型是 Redis最基本的数据类型,一个键最大能存储 512MB。

5.2 Hash(哈希)

Redis hash 是一个键名对集合。

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

5.3 List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

5.4 Set(集合)

Redis 的 Set 是 string 类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

5.5 Sorted set(有序集合)

Redis zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。Redis 正是通过分数来为集合中的成员进行从小到大的排序。

zset 的成员是唯一的,但分数(score)却可以重复。

5.6 pub/sub(发布/订阅)

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

5.7 Transactions(事务)

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

6. Redis 实际应用场景

  1. 显示最新的项目列表

  2. 删除与过滤

  3. 排行榜相关

  4. 按照用户投票和时间排序

  5. 处理过期项目

  6. 计数

  7. 特定时间内的特定项目

  8. 实时分析正在发生的情况,用于数据统计与防止垃圾邮件等

  9. Pub/Sub

  10. 队列

  11. 缓存

点击查看原文链接

点赞
收藏
暂无评论,快来发表评论吧~