一、缓存概念
缓存就是数据交换的缓冲区(称作:Cache),当某一硬件要读取数据时,会首先从缓存汇总查询数据,有则直接执行,不存在时从内存中获取。由于缓存的数据比内存快的多,所以缓存的作用就是帮助硬件更快的运行
二、为什么使用缓存
首先对于互联网应用来说,用户体验是非常重要的,而使用缓存的目的是想通过提高服务的性能从而提高应用的用户体验。
而系统性能的指标一般包括:响应时间、延迟时间、吞吐量、并发用户数量和资源利用率等几个方面。
吞吐量:系统在单位时间内处理的请求的数量
三、缓存的分类
对于java程序开发者来说,根据缓存在软件系统中所处的位置的不同,缓存大体可以分为三类:
- 客户端缓存:
对于BS架构的互联网应用来说客户端缓存主要分为页面缓存和浏览器缓存两种,对于APP而言主要是自身所使用的缓存
2、网络中缓存
网络中的缓存主要是指代理服务器对客户端请求数据的缓存,主要分为WEB代理缓存和边缘缓存(CDN边缘缓存)
3、服务端缓存
从系统的架构上面区分可以将缓存分为
3.1 、服务器本地读缓存(localCache)
3.2 、分布式缓存(Redis、Memcached等nosql)
3.3 、数据库缓存
3.3.1 服务器本地缓存
本地缓存是一级缓存,位于服务本机的内存中,在操作本地缓存的时候不需要网络IO不需要文件IO,直接从本机内存中读取数据,因此读写速度最快。
本地缓存存在的问题:
- 本读缓存数据直接保存在JVM中,需要考虑缓存数据的大小、JVM的垃圾回收性能消耗
- 单服务是集群部署的时候,应该考虑是否需要做集群中本地缓存的数据同步
在实际的开发中可以自己实现简单的本地缓存也可以使用开源的本地缓存框架,比如:ehcache、JBoss Cache等
3.3.2分布式缓存
当本地缓存被穿透的时候就会去查询分布式缓存,当在分布式缓存中查询到数据的时候,直接将查询结果放到本地缓存中。
对于分布式缓存主要是使用NoSQL数据库来实现,常用的NoSQL数据库有Redis、Memcached、MongoDB等。目前比较流行的Redis来说,支持Slava/Master模式和Cluster
3.3.3缓存中的几个常用术语
1.缓存命中:当客户端请求的数据在缓存中,这个缓存中的数据就会被使用,这一行为被称为缓存命中
2.没有命中:缓存中没有查询到数据,并且数据库中可以查到此数据,并将数据放到缓存中
3.缓存穿透:是指查询一个缓存中一定不存在的数据。即缓存中不存在,并且数据库中也不存在,并且在数据库中没有查询到数据的情况下,不会去写缓存,这样就导致每次对于此数据的查询都会去查询数据库,这样就导致缓存失去了意义。对于如何解决缓存穿透问题,后面会具体分析。
4.存储成本:缓存没有命中的时候,从其他数据源取出数据并放到缓存中的时间成本和空间成本就是存储成本。
5.缓存失效:当缓存中的数据已经更新时,则此数据已经失效
6.替代策略:当缓存没有命中的时,并且缓存容量已满,就需要在缓存中去除一条旧数据,然后加入一条新数据,而应该去除哪些数据,就由替代策略来决定。
常用的替代策略有:LRU、LFU等。在使用缓存算法的时候,通常会考虑使用频率、获取成本、缓存容量和时间等因素。
8.缓存雪崩
3.3.4使用云服务提供的缓存服务
国内的阿里云扽提供商提供Redis的云服务器,这些服务有以下特点:
1.动态扩容:通过后台配置升级Redis存储空间
2.数据多备,数据存储在一主一备中
3.自动容灾:主机宕机后系统自动检测,并切换到备机上,实现了服务的高可用
3.3.5数据库缓存
数据库在设计的时候也有缓存操作,更改相关参数开启查询缓存
四、常用缓存(mongodb、memcached、Redis )
mongodb和memcached不是一个范畴内的东西。mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据。mongodb和memcached不存在谁替换谁的问题。
和memcached更为接近的是redis。它们都是内存型数据库,数据保存在内存中,通过tcp直接存取,优势是速度快,并发高,缺点是数据类型有限,查询功能不强,一般用作缓存。
Redis 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。目前由VMware主持开发工作。
1) 数据模型
作为Key-value型数据库,Redis也提供了键(Key)和值(Value)的映射关系。除了常规的数值或字符串,Redis的键值还可以是以下形式之一:
Lists (列表)
Sets (集合)
Sorted sets (有序集合)
Hashes (哈希表)
键值的数据类型决定了该键值支持的操作。Redis支持诸如列表、集合或有序集合的交集、并集、差集等高级原子操作;同时,如果键值的类型是普通数字,Redis则提供自增等原子操作。
2) 持久化:
Redis通常将数据存储于内存中,或被配置为使用虚拟内存。
通过两种方式可以实现数据持久化:使用快照的方式,将内存中的数据不断写入磁盘;或使用类似MySQL的日志方式,记录每次更新的日志。前者性能较高,但是可能会引起一定程度的数据丢失;后者相反。
3) 性能同步:
Redis支持将数据同步到多台从库上,这种特性对提高读取性能非常有益。相比需要依赖磁盘记录每个更新的数据库,基于内存的特性无疑给Redis带来了非常优秀的性能,读写操作之间有显著的性能差异。
4) API 语言
支持C、 C++、 C#、 Java、 Javascript、 Lua、 Objective-C、 Perl、 PHP、 Python、 Ruby、 Go等语言,更多请见:Redis 官网
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
1) 事件处理
memcached使用libevent库,能在Linux、BSD、Solaris等操作系统上发挥其高性能。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。
2)数据存储
为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used,最近最少使用)算法自动删除不使用的缓存。memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。
3) API语言
支持 C、C#、 C++、 Java、Perl、 PHP、 Python、 Ruby、 Lua等语言,更多请见: Memcached Clients
MongoDB 是一个基于分布式文件存储的数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB服务端可运行在Linux、Windows或IOS平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB,64位平台则非常大。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
1) 特点:高性能、易部署、易使用,存储数据非常方便
2) 功能:面向集合存储,易存储对象类型的数据;支持动态查询,支持完全索引,包含内部对象;支持复制和故障恢复;使用高效的二进制数据存储,包括大型对象(如视频等);自动处理碎片,以支持云计算层次的扩展性
3) 格式:文件存储格式为BSON(一种JSON的扩展);可通过网络访问
4) API语言:C、C#、 C++、Java、JavaScript、 PHP、Ruby、Python、Perl等,更多请见: MongoDB Home 来自:http://blog.csdn.net/sunboy_2050/article/details/8552155
redis相比memcached:
1、redis具有持久化机制,可以定期将内存中的数据持久化到硬盘上。
2、redis具备binlog功能,可以将所有操作写入日志,当redis出现故障,可依照binlog进行数据恢复。
3、redis支持virtual memory,可以限定内存使用大小,当数据超过阈值,则通过类似LRU的算法把内存中的最不常用数据保存到硬盘的页面文件中。
4、redis原生支持的数据类型更多,使用的想象空间更大。
5、前面有位朋友所提及的一致性哈希,用在redis的sharding中,一般是在负载非常高需要水平扩展时使用。我们还没有用到这方面的功能,一般的项目,单机足够支撑并发了。redis 3.0将推出cluster,功能更加强大。
一起对比如下
redis | Memcached | MongoDB | |
开发语言 | C语言 | C++ | |
特点 | 高性能的key-value数据库 | 仅支持简单的key-value结构、高性能 | 基于分布式文件存储 的数据库 |
数据模型 | Lists (列表) Sets (集合) Sorted sets (有序集合) Hashes (哈希表) key- value | key- value | 面向集合存储,易存储对象类型的数据,储格式为BSON(JSON 的一种扩展) |
数据存储 | 内存、磁盘 | 内存 | 内存、磁盘 |
集群 | 支持 | 支持 | 支持 |
分布式 | 服务器端构建分布式存储 | 客户端实现分布式存储 | |
支持语言 | C、 C++、 C#、 Java、 Javascript、 Lua、 Objective-C、 Perl、 PHP、 Python、 Ruby、 Go等 | Perl、PHP、Python、Ruby、C#、C/C++、Lua 等等。 | Perl、PHP、Java、C#、JavaScript、Ruby、C 和C++ |