WhyRedis
速度快,完全基于内存,使用C语言实现,网络层使用epoll解决高并发问题,单线程模型避免了不必要的上下文切换及竞争条件;
| GuavaCache | Tair | EVCache | Aerospike | |
|---|---|---|---|---|
| 类别 | 本地JVM缓存 | 分布式缓存 | 分布式缓存 | 分布式nosql数据库 |
| 应用 | 本地缓存 | 淘宝 | Netflix、AWS | 广告 |
| 性能 | 非常高 | 较高 | 很高 | 较高 |
| 持久化 | 无 | 有 | 有 | 有 |
| 集群 | 无 | 灵活配置 | 有 | 自动扩容 |
与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。
1、简单高效
1)完全基于内存,绝大部分请求是纯粹的内存操作。数据存在内存中,类似于 HashMap,查找和操作的时间复杂度都是O(1);
2)数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;
3)采用单线程,避免了多线程不必要的上下文切换和竞争条件,不存在加锁释放锁操作,减少了因为锁竞争导致的性能消耗;(6.0以后多线程)
4)使用EPOLL多路 I/O 复用模型,非阻塞 IO;
5)使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;
2、Memcache
| redis | Memcached |
|---|---|
| 内存高速数据库 | 高性能分布式内存缓存数据库 |
| 支持hash、list、set、zset、string结构 | 只支持key-value结构 |
| 将大部分数据放到内存 | 全部数据放到内存中 |
| 支持持久化、主从复制备份 | 不支持数据持久化及数据备份 |
| 数据丢失可通过AOF恢复 | 挂掉后,数据不可恢复 |
| 单线程(2~4万TPS) | 多线程(20-40万TPS) |
使用场景:
1、如果有持久方面的需求或对数据类型和处理有要求的应该选择redis。
2、如果简单的key/value 存储应该选择memcached。
3、Tair
Tair(Taobao Pair)是淘宝开发的分布式Key-Value存储引擎,既可以做缓存也可以做数据源(三种引擎切换)
- MDB(Memcache)属于内存型产品,支持kv和类hashMap结构,性能最优
- RDB(Redis)支持List.Set.Zset等复杂的数据结构,性能次之,可提供缓存和持久化存储两种模式
- LDB(levelDB)属于持久化产品,支持kv和类hashmap结构,性能较前两者稍低,但持久化可靠性最高
分布式缓存
大访问少量临时数据的存储(kb左右)
用于缓存,降低对后端数据库的访问压力
session场景
高速访问某些数据结构的应用和计算(rdb)
数据源存储
快速读取数据(fdb)
持续大数据量的存入读取(ldb),交易快照
高频度的更新读取(ldb),库存
痛点:redis集群中,想借用缓存资源必须得指明redis服务器地址去要。这就增加了程序的维护复杂度。因为redis服务器很可能是需要频繁变动的。所以人家淘宝就想啊,为什么不能像操作分布式数据库或者hadoop那样。增加一个中央节点,让他去代理所有事情。在tair中程序只要跟tair中心节点交互就OK了。同时tair里还有配置服务器概念。又免去了像操作hadoop那样,还得每台hadoop一套一模一样配置文件。改配置文件得整个集群都跟着改。
4、Guava
分布式缓存一致性更好一点,用于集群环境下多节点使用同一份缓存的情况;有网络IO,吞吐率与缓存的数据大小有较大关系;
本地缓存非常高效,本地缓存会占用堆内存,影响垃圾回收、影响系统性能。
本地缓存设计:
以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况,每个实例都需要各自保存一份缓存,缓存不具有一致性。
解决缓存过期:
1、将缓存过期时间调为永久
2、将缓存失效时间分散开,不要将缓存时间长度都设置成一样;比如我们可以在原有的失效时间基础上增加一个随机值,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
解决内存溢出:
第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
Google Guava Cache
自己设计本地缓存痛点:
- 不能按照一定的规则淘汰数据,如 LRU,LFU,FIFO 等。
- 清除数据时的回调通知
- 并发处理能力差,针对并发可以使用CurrentHashMap,但缓存的其他功能需要自行实现
- 缓存过期处理,缓存数据加载刷新等都需要手工实现
Guava Cache 的场景:
- 对性能有非常高的要求
- 不经常变化,占用内存不大
- 有访问整个集合的需求
- 数据允许不实时一致
Guava Cache 的优势:
- 缓存过期和淘汰机制
在GuavaCache中可以设置Key的过期时间,包括访问过期和创建过期。GuavaCache在缓存容量达到指定大小时,采用LRU的方式,将不常使用的键值从Cache中删除
- 并发处理能力
GuavaCache类似CurrentHashMap,是线程安全的。提供了设置并发级别的api,使得缓存支持并发的写入和读取,采用分离锁机制,分离锁能够减小锁力度,提升并发能力,分离锁是分拆锁定,把一个集合看分成若干partition, 每个partiton一把锁。更新锁定
- 防止缓存击穿
一般情况下,在缓存中查询某个key,如果不存在,则查源数据,并回填缓存。(Cache Aside Pattern)在高并发下会出现,多次查源并重复回填缓存,可能会造成源的宕机(DB),性能下降 GuavaCache可以在CacheLoader的load方法中加以控制,对同一个key,只让一个请求去读源并回填缓存,其他请求阻塞等待。(相当于集成数据源,方便用户使用)
- 监控缓存加载/命中情况
统计
问题:
OOM->设置过期时间、使用弱引用、配置过期策略
5、EVCache
EVCache是一个Netflflix(网飞)公司开源、快速的分布式缓存,是基于Memcached的内存存储实现的,用以构建超大容量、高性能、低延时、跨区域的全球可用的缓存数据层。
E:Ephemeral:数据存储是短暂的,有自身的存活时间
V:Volatile:数据可以在任何时候消失
EVCache典型地适合对强一致性没有必须要求的场合
典型用例:Netflflix向用户推荐用户感兴趣的电影
EVCache集群在峰值每秒可以处理200kb的请求,
Netflflix生产系统中部署的EVCache经常要处理超过每秒3000万个请求,存储数十亿个对象,
跨数千台memcached服务器。整个EVCache集群每天处理近2万亿个请求。
EVCache集群响应平均延时大约是1-5毫秒,最多不会超过20毫秒。
EVCache集群的缓存命中率在99%左右。
典型部署
EVCache 是线性扩展的,可以在一分钟之内完成扩容,在几分钟之内完成负载均衡和缓存预热。
1、集群启动时,EVCache向服务注册中心(Zookeeper、Eureka)注册各个实例
2、在web应用启动时,查询命名服务中的EVCache服务器列表,并建立连接。
3、客户端通过key使用一致性hash算法,将数据分片到集群上。
6、ETCD
和Zookeeper一样,CP模型追求数据一致性, 越来越多的系统开始用它保存关键数据。比如,秒杀系统经常用它保存各节点信息,以便控制消费 MQ 的服务数量。还有些业务系统的配置数据,也会通过 etcd 实时同步给业务系统的各节点,比如,秒杀管理后台会使用 etcd 将秒杀活动的配置数据实时同步给秒杀 API 服务各节点。
- [ 萱儿AXW ]