缓存重点知识总结以及分布式缓存框架redis和Memcached介绍

本文介绍了缓存的基本概念,包括服务端缓存和缓存淘汰策略,深入探讨了Redis与Memcached的特性、区别及使用场景。文章还讨论了分布式缓存的定义及其与NoSQL的关系。通过实例展示了缓存如何提高系统性能,同时阐述了Ehcache、Memcached和Redis的优缺点以及如何在实际项目中应用。

Table of Contents

一个实际的例子

缓存的分类

服务端缓存

缓存的几种淘汰策略是什么

Redis,Memcached,和Ehcache等缓存框架,主要的特点是什么?分别适用于哪些业务场景

Ehcache

Memcached

Redis

redis支持哪些数据结构,提供哪些数据类型?

redis是单线程的吗?

redis是如何存储一个String的

redis的部署方式

redis的哨兵模式

redis的持久化策略

memcached简介

redis和memcached的区别?

什么是分布式缓存?

分布式缓存与NoSQL


一个实际的例子

缓存是一个范围相当大的概念。我们可以按前后端分,可以按缓存类型特点分。 从我个人角度而言,事实上任何有数据的地方都可以有缓存。在这里我想首先从自己接触并使用的缓存开始讲起。

我目前用到的缓存是在一个服务器项目里的一个例子。简单的原理如下。

service A需要提供数据给另外几个services:B, C,D调用。如下:

而A服务器每次都需要去数据库里请求对应的数据返回给调用者。后来专门为A服务器做了一个Client,这个Client里面定义了一个map,用于存储从A服务器中获得的数据。

因此当其他程序要从A中取数据的时候,就先判断这个map当中有没有需要的数据,若有,就不用向A发请求。

但是这里有一个问题就是假如缓存的数据失效了或者不是最新的了的话该怎么办。这其实是一个消息中间件的典型应用场景。在A服务器与其他调用者之间需要建立一个消息中间件的机制。

在这个mq上需要根据缓存的对象内容建立一个绑定关系。然后在缓存当中需要配置对应的事件监听者,也就是一个Listener。当A当中的数据,即数据库中的数据更新的时候。A需要发出一个缓存更新的message出去,然后调用者的缓存当中的listener收到这个message,发现消息过期,然后就从新从A中取一次数据,并更新缓存。

除此之外,在mq不工作的时候,由于无法确保缓存的正确性,也应该清除掉缓存,这也是在缓存当中配置一个mq断开的事件监听来实现的。后来这一套流程,已经被spring cache框架所替代,替代框架用到了Guava,ehcache3,redis,用户可以自己选配。

这应该算一个最基本的cache,这个cache有一个显而易见的问题就是,当我的对象非常大的时候,他可能会占很大的空间,并且,这个缓存也做不到自己清理这样的功能,但是一些比较常用的缓存框架,是有这些功能的。

一些总结:cache本质上是以空间换时间。所有的cache的结构都是一个map。

什么是缓存穿透? cache penetration

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

1:对查询结果为空的情况也进行缓存,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤

3: 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截。

什么是缓存击穿?cache breakdown

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

      解决方案:

  1. 设置热点数据永远不过期。
  2. 加互斥锁。todo

什么是缓存雪崩? cache avalanche

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

4: 设置热点数据永远不过期。

缓存的分类

缓存按使用场景大概可以分为以下几类:

缓存简介
页面缓存页面缓存有两层含义: 一个是页面自身对某些元素或全部元素进行缓存;另一层意思 是服务端将静态页面或动态页面的元素进行缓存, 然后给客户端使用
浏览器缓存浏览器缓存是通常只要一次会话。浏览器会在硬盘上专门开辟一个空间来存储资源副 本作为缓存。在用户触发”后退"操作或点击一个之前看过的链接的时候,浏览器缓存会 很管用
网络中的缓存网络中的缓存位于客户端和服务端之间, 代理或响应客户端的网络请求, 从而对重复的请求返回缓存中的数据资源。 同时, 接受服务端的请求, 更新缓存中的内容
 Web 代理缓存Web代理几乎是伴随着互联网诞生的, 常用的Web代理分为正向代理、 反向代理和透明代理。 Web代理缓存是将Web代理作为缓存的一种技术
边缘缓存

边缘缓存中典型的商业化服务就是CDN了,例如AWS的CloudFront, 我国的
ChinaCache 等, 现在一般的公有云服务商都提供了 CDN 服务。 CDN 是 Content Delivery 

Network的简称

服务端缓存服务端缓存是整个缓存体系中的重头戏, 从网站的架构演进中已经看到了服务端缓存 是系统性能的重中之重了。 数据库是整个系统中的 "慢性子”,有时候数据库调优能够以小搏大, 在不改变架构和代码逻辑的前提下, 缓存参数的调整往往是条捷径。 在系统开发的 过程中, 可以直接在平台侧使用缓存框架, 当缓存框架无法满足系统对性能的要求时, 就 需要在应用层自主开发应用级缓存了, 即使利用可供参考的开源架构, 应用级缓存的开发也是一件有挑战的事情。
数据库缓存数据库属千IO密集型的应用, 主要负责数据的管理及存储。 数据库缓存是一类特殊的 缓存, 是数据库自身的缓存机制。 大多数数据库不需要配置就可以快速运行, 但并没有为 特定的需求进行优化。 在数据库调优的时候, 缓存优化是一项很重要的工作。
以MySQL为例,MySQL中使用了查询缓冲机制, 将SELECT语句和查询结果存放在 缓冲区中, 以后对千同样的SELECT语旬, 将直接从缓冲区中读取结果, 以节省查询时间, 提高了SQL查询的效率

参考:https://blog.csdn.net/busidihuang/article/details/80676106

问题来了,那么我们经常听到的分布式缓存(Distribute Cache)是什么呢?它的定义是什么?

就这个问题我也在百度上查了一下,发现竟然没有一篇博客给出一个准确的定义。首先我们应该弄清楚的问题是,分布式到底是什么意思?

其实顾名思义,用白话说,就是原本在一个地方的东西,把它放在了好几个地方。在计算机的世界里,就是说把一个系统按照模块拆分成多个子系统。

那么接下来分布式缓存就很好理解了,无非就是把缓存部署在系统的多个地方,或者说在系统的多个地方都引入缓存。

服务端缓存

服务端缓存,对于java开发而言,spring已经提供了非常好的支持,在spring官方文档有一个专门的部分介绍spring cache。实现原理也是利用AOP进行cache增强。

缓存的几种淘汰策略是什么

事实上不止是缓存,只要设计的内存,或者存储空间,所用到的策略和方法都是哪几种,在操作系统里面的虚拟内存页面置换算法,有:最佳置换算法,FIFO,LRU,LFR,CNRU等等,和这里的缓存的淘汰策略如出一辙,只是在操作系统里是用来判定怎样替换更好。我个人的观点:所有涉及到存储空间里的内容清除,置换的,都是这些算法。

缓存淘汰策略用于决定缓存系统中哪些数据应该被删去。常见算法类型包括LFU、LRU、ARC、FIFO、MRU。

最不经常使用算法(LFU):

这个缓存算法使用一个计数器来记录条目被访问的频率。通过使用LFU缓存算法,最低访问数的条目首先被移除。这个方法并不经常使用,因为它无法对一个拥有最初高访问率之后长时间没有被访问的条目缓存负责。

最不经常使用算法(LFU):

这个缓存算法使用一个计数器来记录条目被访问的频率。通过使用LFU缓存算法,最低访问数的条目首先被移除。这个方法并不经常使用,因为它无法对一个拥有最初高访问率之后长时间没有被访问的条目缓存负责。

自适应缓存替换算法(ARC):

在IBM Almaden研究中心开发,这个缓存算法同时跟踪记录LFU和LRU,以及驱逐缓存条目,来获得可用缓存的最佳使用。

先进先出算法(FIFO):

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

最近最常使用算法(MRU):

这个缓存算法最先移除最近最常使用的条目。一个MRU算法擅长处理一个条目越久,越容易被访问的情况。

Ehcache

在java项目广泛的使用。它是一个开源的、设计于提高在数据从RDBMS中取出来的高花费、高延迟采取的一种缓存方案。正因为Ehcache具有健壮性(基于java开发)、被认证(具有apache 2.0  license)、充满特色(稍后会详细介绍),所以被用于大型复杂分布式web application的各个节点中。

什么特色?

1.  够快

Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.

2. 够简单

开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目

比如:hibernate

3.够袖珍

关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3  才 668KB。

4. 够轻量

核心程序仅仅依赖slf4j这一个包,没有之一!

5.好扩展

Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多

6.监听器

缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的

如何使用?

Ehcache的一大特色是够简单,用起来非常容易

贴一段基本使用代码

CacheManager manager = CacheManager.newInstance("src/config/ehcache.xml");
Ehcache cache = new Cache("testCache", 5000, false, false, 5, 2);
cacheManager.addCache(cache);
代码中有个ehcache.xml文件,现在来介绍一下这个文件中的一些属性
  1.        name:缓存名称。
  2.        maxElementsInMemory:缓存最大个数。
  3.        eternal:对象是否永久有效,一但设置了,timeout将不起作用。
  4.        timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  5.        timeToLiveSeconds:设置对象在失效前允许存活时间,最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时 间无穷大。
  6.        overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
  7.        diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  8.        maxElementsOnDisk:硬盘最大缓存个数。
  9.        diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
  10.        diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  11.        memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU。你可以设置为 FIFO或是LFU。
  12.        clearOnFlush:内存数量最大时是否清除。

Memcached

memcache 是一种高性能、分布式对象缓存系统,最初设计于缓解动态网站数据库加载数据的延迟性,你可以把它想象成一个大的内存HashTable,就是一个key-value键值缓存。Danga Interactive为了LiveJournal所发展的,以BSD license释放的一套开放源代码软件。

1.依赖

memcache C语言所编写,依赖于最近版本的GCC和libevent。GCC是它的编译器,同事基于libevent做socket io。在安装memcache时保证你的系统同事具备有这两个环境。

2.多线程支持

memcache支持多个cpu同时工作,在memcache安装文件下有个叫threads.txt中特别说明,By default, memcached is compiled as a single-threaded application.默认是单线程编译安装,如果你需要多线程则需要修改./configure –enable-threads,为了支持多核系统,前提是你的系统必须具有多线程工作模式。开启多线程工作的线程数默认是4,如果线程数超过cpu数容易发生操作死锁的概率。结合自己业务模式选择才能做到物尽其用。

3.高性能

通过libevent完成socket 的通讯,理论上性能的瓶颈落在网卡上。

Redis

redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的Key-Value数据库。它可以用作:数据库、缓存和消息中间件。它十分适合存储少、访问量巨大的场景,所有数据全部in-memory保证了数据的高速访问。

redis支持哪些数据结构,提供哪些数据类型?

redis是一种高级的key:value存储系统,其中value支持五种数据类型:

1.字符串(strings)
2.字符串列表(lists)
3.字符串集合(sets)
4.有序字符串集合(sorted sets)
5.哈希(hashes)

String—字符串(key-value 类型):Strings就是一个最最简单的Key-Value形式存储的变量。

Hash—字典(hashmap) Redis的哈希结构可以使你像在数据库中更新一个属性一样只修改某一项属性值。Hash存储是键值对的value。即Key-Hash,而Hash又是一个k-v的结构
List—列表 实现消息队列。List是一个有序可重复的集合,其遵循FIFO的原则,底层是依赖双向链表实现的,因此支持正向、反向双重查找
Set—集合 利用唯一性。Set是一个无序的天然去重的集合,即Key-Set
Sorted Set—有序集合 可以进行排序 可以实现数据持久化。类似于java中的TreeSet,是Set的可排序版。

redis是单线程的吗?

是的,Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由C语言编写,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 Memcached 差!有兴趣的可以参考官方的基准程序测试《How fast is Redis?》(https://redis.io/topics/benchmarks

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路I/O复用模型,非阻塞IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

redis是如何存储一个String的

我们知道Redis是由C语言编写的,以高效和轻量著称。而C语言中的字符串是怎么实现的呢?字符数组。

比如一个简单的字符串”hello world”,其实是一个如下的字符的数组:

[‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘ ‘, ‘w’, ‘o’, ‘r’, ‘l’, ‘d’, ‘\0’]

最后的一个’\0’是空字符,表示字符串的结尾。

Redis由于各种原因,并没有直接使用了C语言的字符串结构,而是对其做了一些封装,得到了自己的简单动态字符串(simple dynamic string, SDS)的抽象类型。Redis中,默认以SDS作为自己的字符串表示。只有在一些字符串不可能出现变化的地方使用C字符串。

SDS的定义如下:

1

2

3

4

5

6

7

8

9

struct sdshdr {

    // 用于记录buf数组中使用的字节的数目

    // 和SDS存储的字符串的长度相等

    int len;

    // 用于记录buf数组中没有使用的字节的数目

    int free;

    // 字节数组,用于储存字符串

    char buf[];

};

可以看出来,SDS的结构并不复杂。

buf是一块可用的内存空间,通常大小会大于等于需要存储的字符串的大小(大于?为什么要大于呢?读者可以思考一下)。

len表示字符串的长度,也表示buf中已经被使用的空间的大小。

free表示buf中没有被使用的空间的大小。

要注意的是,buf的大小等于len+free+1,其中多余的1个字节是用来存储’\0’的。

redis的部署方式

单节点模式

主从模式master -slave

哨兵模式

redis的哨兵模式

Redis-Sentinel是官方推荐的高可用解决方案,当redis在做master-slave的高可用方案时,假如master宕机了,redis本身(以及其很多客户端)都没有实现自动进行主备切换,而redis-sentinel本身也是独立运行的进程,可以部署在其他与redis集群可通讯的机器中监控redis集群。

它的主要功能有一下几点

1、不时地监控redis是否按照预期良好地运行;
2、如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
3、能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。
4、哨兵为客户端提供服务发现,客户端链接哨兵,哨兵提供当前master的地址然后提供服务,如果出现切换,也就是master挂了,哨兵会提供客户端一个新地址。

哨兵(sentinel)本身也是支持集群的

很显然,单个哨兵会存在自己挂掉而无法监控整个集群的问题,所以哨兵也是支持集群的,我们通常用三台哨兵机器来监控一组redis集群。

redis的持久化策略

redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。

RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储到磁盘等介质上;

AOF,则是换了一个角度来实现持久化,那就是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

redis事务

Redis中的事务(transaction)是一组命令的集合。
reids事务不会回滚,只有全部执行和全部不执行两种,部分语句执行失败不会停止
MULTI(事务开始)EXEC(末尾) watch(观察) unwatch(解除观察)

reids过期策略

定时删除:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除(基本不使用)
惰性删除:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。(内置策略)
定期删除:每隔一段时间执行一次删除(在redis.conf配置文件设置hz,1s刷新的频率)过期key操作

redis的使用场景是什么

redis的优点主要是

  1. nosql数据库没有关联关系,数据结构简单,拓展表比较容易

  2. nosql读取速度快,对较大数据处理快

因此redis适应的场景包括:

  1. 数据高并发的读写

  2. 海量数据的读写

  3. 对扩展性要求高的数据

不太适合:

  1. 需要事务支持(非关系型数据库)

  2. 基于sql结构化查询储存,关系复杂

因此redis可以用于:

1.配合关系型数据库做高速缓存

  • 缓存高频次访问的数据,降低数据库io

  • 分布式架构,做session共享

2.可以持久化特定数据

  • 利用zset类型可以存储排行榜。常见的排行问题,例如最热话题、游戏排名等等,这些都可以通过Redis来轻松实现,直接使用ZRank即可得到。

  • 利用list的自然时间排序存储最新n个数据。如果在传统的关系型数据库,这就需要使用select * from table where name="" order by time desc limit  100;这十分消耗数据库性能,但是通过Redis,就可以直接在Redis里面通过Id创建一个List,指定长度1w,当需要查找时,直接输出该list的后100条记录。

  • 可以自动删除过期数据。Redis不是真正意义上的可持久化数据库,可以给数据加上一个有效时间,在有效时间超过时,Redis会自动删除对应数据

memcached简介

memcached就是一个开源的缓存系统,它开始是为网站缓存而开发的,它基于key-value这一通用的数据结构,采用C++开发。memcached基于libevent,因此在安装时,必须先安装libevent。

redis和memcached的区别?

1、Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;

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

3、虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;

4、过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10;

5、分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;

6、存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);

7、灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;

8、Redis支持数据的备份,即master-slave模式的数据备份;

9、应用场景不一样:Redis出来作为NoSQL数据库使用外,还能用做消息队列、数据堆栈和数据缓存等;Memcached适合于缓存SQL语句、数据集、用户临时性数据、延迟查询数据和session等。

什么是分布式缓存?

在回答什么是分布式缓存之前,我们不妨来看看一般的缓存可能会有什么样的问题

对于web服务而言,缓存的意义是当我们在向一个服务请求数据时,不用每次都向数据库去拿数据,而是可以在缓存当中有数据时,直接从缓存当中返回。这样可以提高效率和响应时间。

当我们只有一个服务器的时候,看上去似乎没有问题。但是当我们有一个集群类型的服务时,就会变得更复杂,每一次当一个cache的数据更新时,我们必须保证这个集群里面所有相关的cache全部都得到更新,否则,就有可能带来严重的问题。

或者,我们可以有一个唯一的更大的cache,但是这个cache服务可能会挂掉,因此我们可能至少需要两个。这便是分布式缓存的用意。

常见的分布式缓存框架有: Infinispan, Terracotta/Ehcache, Hazelcast, Memcached, Redis, Cassandra, Elasticache.

缓存是围绕键和值构造的,每个键都有一个缓存entry。当您想从数据库加载某些内容时,首先检查缓存是否没有带有该键的entry(例如,基于数据库记录的ID)。如果在缓存中存在,则不执行数据库查询。

但是数据是如何“distributed”的呢?同时加载所有节点上的所有数据是没有意义的,因为冗余的数据是浪费空间,并且保持缓存一致性也是一个问题。大多数解决方案依赖于所谓的“一致哈希Consistent hashing”。在查找特定键时,将计算其散列hash,并且(取决于缓存集群中的机器数量),缓存解决方案确切地知道对应的值位于哪台机器上。

分布式缓存与NoSQL

在上一个部分我们提到了缓存是围绕key和value的键值对构造的,而且计算key也需要用到hash算法。而nosql的定义是:NoSQL 又称为Not Only Sql,主要是指非关系型,分布式、支持水平扩展的数据库设计模式。(更多信息可以参考我的另一篇博客:数据库重要知识).

到这里,我们不难发现,nosql的设计理念和使用场景,是非常适合分布式缓存这种使用场景的。可以这样说:分布式缓存是nosql适用的其中一种重要的场景

为什么传统的关系型数据库难以满足这样的使用场景,原因如下:

1) 根据CAP 理论,一致性(consistency)、可用性(availability)和分区容错(partition tolerance)这3 个要素最多同时满足两个,不可能三者兼顾.对云平台中部署的大量Web 应用而言,数据可用性与分区容错的优先级通常更高,所以一般会选择适当放松一致性约束.传统数据库的事务一致性需求制约了其横向伸缩与高可用技术的实现;
2) 传统数据库难以适应新的数据存储访问模式.Web 2.0 站点以及云平台中存在大量半结构化数据,如用户Session 数据、时间敏感的事务型数据、计算密集型任务数据等,这些状态数据更适合以Key/Value 形式存储,不需要RDBMS 提供的复杂的查询与管理功能;
3) NoSQL 提供低延时的读写速度,支持水平扩展,这些特性对拥有海量数据访问请求的云平台而言是至关重要的.传统关系型数据无法提供同样的性能,而内存数据库容量有限且不具备扩展能力.分布式缓存作为NoSQL 的一种重要实现形式,可为云平台提供高可用的状态存储与可伸缩的应用加速服务,与其他NoSQL 系统间并无清晰的界限.平台中应用访问与系统故障均具有不可预知性,为了更好地应对这些挑战,应用软件在架构时通常采用无状态设计,大量状态信息不再由组件、容器或平台来管理,而是直接交
付给后端的分布式缓存服务或NoSQL 系统.。

 

参考:

https://blog.csdn.net/truelove12358/article/details/49686035

https://www.cnblogs.com/idiotgroup/p/5450157.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值