分布式缓存上—浅谈缓存的理解

文章目录

  • 1.概述
    • 1.1 概念
    • 1.2 作用
    • 1.3 原理
  • 2.缓存的分类
    • 2.1 CDN缓存
      • 应用场景
      • 优点
    • 2.2 反向代理缓存
      • 应用场景
    • 2.3 本地应用缓存
      • 应用场景
      • 缓存介质
      • 实现
        • 1.通过编程实现
        • 2.Ehcahe
    • 缓存数据过期策略
  • 3.分布式缓存
    • 3.1 Memcached
      • 基本介绍
      • 特点
      • 基本架构
      • 缓存数据过期策略
      • 数据淘汰内部实现
      • 分布式集群实现
        • 数据存储步骤:
        • 分布式算法
    • 3.2 Redis
      • 基本介绍
      • 数据模型
      • 数据淘汰策略
      • 数据淘汰内部实现
      • 持久化方式
      • 底层实现部分解析
      • Redis缓存设计原则
    • 3.3 Redis与Memcached比较

PS:在了解分布式缓存之前我们先看看缓存是个什么概念

1.概述

1.1 概念

用于存储数据的硬件或软件的组成部分,以使得后续更快的访问相应的数据,缓存中的数据可能是提前计算好的结果、数据的副本等。

1.2 作用

缓存时分布式中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题,提供高性能的数据快速访问。

1.3 原理

  • 将数据写入速度更快的存储设备
  • 将数据缓存到离应用最近的位置
  • 将数据缓存到离用户最近的位置

2.缓存的分类

缓存主要分为:

  • CDN缓存
  • 反向代理缓存
  • 本地应用缓存
  • 分布式缓存

2.1 CDN缓存

CDN(Content Delivery Network 内容分发网络)的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求

应用场景

主要缓存静态资源,例如图片,视频
分布式缓存上—浅谈缓存的理解_第1张图片

分布式缓存上—浅谈缓存的理解_第2张图片

优点

  • 镜像服务
    消除了不同运营商之间互联的瓶颈造成的影响,实现了跨运营商的网络加速,保证了不同网络中的用户都能得到良好的质量访问
  • 远程加速
    远程访问用户根据DNS负载均衡技术智能自动选择Cache服务器,选择最快的Cache服务器,加快远程的访问速度
  • 宽带优化
    自动生成服务器的远程minior(镜像)cache服务器,远程用户访问时从cache服务器上读取数据,减少远程访问的宽带,分担网络流量,减轻原站点WEB服务器负载等功能
  • 集群抗攻击
    广泛分布的CDN节点加上节点之间的智能冗余机制,可以有效的预防黑客入侵以及降低各种DOS攻击对网站的影响,同时保证较好的服务质量

2.2 反向代理缓存

反向代理位于应用服务器机房,处理所有对WEB服务器的请求。
如果用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户。如果没有缓冲则先向WEB服务器发出请求,取回数据,本地缓存后再发送给用户。通过降低向WEB服务器的请求数,从而降低了WEB服务器的负载。

应用场景

一般只缓存体积较小静态文件资源,如css、js、图片
分布式缓存上—浅谈缓存的理解_第3张图片

像开源的实现有:Varnish、Nginx、Squid

2.3 本地应用缓存

指的是在应用中的缓存组件,其最大的优点是应用和cache是在同一个进程内部,请求缓存非常快速,没有过多的网络开销等,在单应用不需要集群支持或者集群情况下各节点无需互相通知的场景下使用本地缓存较合适;
同时,它的缺点也是应为缓存跟应用程序耦合,多个应用程序无法直接的共享缓存,各应用或集群的各节点都需要维护自己的单独缓存,对内存是一种浪费。

应用场景

缓存字典等常用数据

缓存介质

  • 硬盘缓存
    将数据缓存到硬盘,读取时从硬盘读取,其原理是直接读取本机文件,减少了网络传输消耗,比通过网络去读取数据库要快很多
    适用场景:对速度要求不是很高,但需要大量缓存存储场景
  • 内存缓存
    直接将数据存储到本机内存中,通过程序直接维护缓存对象,是访问速度最快的方式

实现

1.通过编程实现

分布式缓存上—浅谈缓存的理解_第4张图片

2.Ehcahe

应用场景:

  • 1.单个应用或者对缓存访问要求很高的应用
  • 2.简单的共享可以,但是对于缓存恢复,数据缓存不合适
  • 3.大型系统,存在缓存共享、分布式部署、缓存内容很大的不适合

Ehcahe主要特征
分布式缓存上—浅谈缓存的理解_第5张图片

缓存数据过期策略

分布式缓存上—浅谈缓存的理解_第6张图片

  • 1.FIFO
    先进先出
  • 2.LFU
    最少被使用,缓存的属性有一个hit属性,hit值最小的将会被清出缓存
  • 3.LRU
    最近最少使用,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清理出缓存
    Ehcache过期数据淘汰机制

懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期


有了上面的一些知识基础,下面我们再接着聊一聊分布式缓存

3.分布式缓存

指的是与应用分离的缓存组件或服务,其最大的优点是自身就是一个独立的应用,与本地应用隔离,多个应用可直接的共享缓存。

主要应用场景

  • 1.缓存经过复杂运算得出数据
  • 2.缓存存储系统中有频繁的访问热点数据,减轻数据库压力

主要接入方式

  • 1.程序代码实现的中间层
  • 2.独立部署的中间件

下面介绍分布式缓存常见的2大开源实现Memcached和Redis

3.1 Memcached

基本介绍

Memcached是一个高性能,分布式内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。

特点

  • 1.使用物理内存作为缓存区,可独立运行在服务器上。
    每个进程最大2G,如果想缓存更多的数据,可以开辟更多的Memcached进程(不同端口)或者使用分布式Memcached进行缓存,将数据缓存到不同的物理机或者虚拟机上。
  • 2.使用key-value的方式来存储数据,这是一种单索引的结构化数据组织形式,可使数据项查询时间复杂度为O(1)
  • 3.协议简单:基于文本行的协议,直接通过telnet在memcached服务器上可进行存取数据操作,简单,方便多种缓存参考此协议
  • 4.基于Libevent高性能通信:Libevent是一套利用C开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口,与传统的select相比,提高了性能。
  • 5.内置的内存管理方式:所有数据都保存在内存中,存取数据比硬盘快当内存满后,通过LRU算法自动删除不使用的缓存,但没有考虑数据的容灾问题,重启服务,所有数据会丢失
  • 6.分布式:各个Memcached服务器之间互不通信,各自独立存取数据,不共享任何信息。服务器并不具有分布式功能,分布式部署取决于Memcached客户端。

基本架构

分布式缓存上—浅谈缓存的理解_第7张图片

缓存数据过期策略

LRU(最近最少使用)到期失效策略,在Memcached内存储数据项时,可以指定它在缓存的失效时间,默认为永久。当Memcached服务器用完分配的内时,失效的数据被首先替换,然后也是最近未使用的数据。

数据淘汰内部实现

懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取 的时候要和设置的时间做TTL比较来判断是否过期

分布式集群实现

服务端并没有 “ 分布式 ” 功能。每个服务器都是完全独立和隔离的服务。 Memcached的分布式,是由客户端程序实现的
分布式缓存上—浅谈缓存的理解_第8张图片

数据存储步骤:
  • 1.客户端根据算法来进行选择服务器
  • 2.客户端与服务器通信存取数据
分布式算法

余数算法、散列算法

3.2 Redis

基本介绍

Redis是一个远程内存数据库(非关系型数据库),性能强劲,具有复制特性以及解决问题而生的独一无二的数据模型。
它可以存储键值对与5种不同类型的值之间的映射,可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,Redis还可以使用客户端分片来扩展写性能。
内置了:复制(replication),LUA脚本(Lua scripting),LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。

数据模型

分布式缓存上—浅谈缓存的理解_第9张图片

数据淘汰策略

  • volatile-Iru:从已设置过期时间的数据集(server.db[ i].expires)中挑选最近最少使用的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集(server.db[ i].expires)中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集(server.db[ i].expires)中任意选择数据淘汰
  • allkeys-lru:从数据集(server.db[ i].dict)中挑选最近最少使用的数据淘汰
  • allkeys-random:从数据集(server.db[ i].dict)中任意选择数据淘汰
  • no-enviction(驱逐)∶禁止驱逐数据

数据淘汰内部实现

  • 1.消极方法(passive way):
    • 在主键被访问时如果发现它失效,就删除它;
    • 触发时机:在实现GET,MGET,HGET,LRANGE等所有涉及到读取命令时都会调用
  • 2.积极方法(active way):
    • 周期性的从设置了失效时间的主键中,选择一部分失效的主键删除
    • 触发时机:redis的时间事件,即每隔一段时间就中断一下,完成一些操作指令

持久化方式

  • RDB(Redis DataBase):默认的持久化方案,数据库的快照以二进制的方式定时保存到磁盘中
  • AOF(Append Only File):以协议文本的方式,将所有对数据库进行过写入的命令及其参数记录到APF文件,依此达到记录数据库状态的目的

底层实现部分解析

  • 启动的部分过程图解
    分布式缓存上—浅谈缓存的理解_第10张图片

  • server端持久化的部分操作图解
    分布式缓存上—浅谈缓存的理解_第11张图片

  • 底层哈希表实现(渐进式Rehash)

    • 初始化字典
      分布式缓存上—浅谈缓存的理解_第12张图片
    • 字典元素图解
      分布式缓存上—浅谈缓存的理解_第13张图片
    • Rehash执行流程
      分布式缓存上—浅谈缓存的理解_第14张图片

Redis缓存设计原则

  • 1.只应将热数据放到缓存中
  • 缓存过期时间应当分散以避免集中过期
  • 缓存key应具备可读性
  • 应避免不同业务出现同名缓存key
  • 可对key进行适当的缩写以节省内存空间
  • 选择合适的数据结构
  • 确保写入缓存中的数据是完整且正确的
  • 避免使用耗时较长的操作命令,如:keys*
  • 一个key对应的数据不应过大
  • 避免缓存穿透
  • 可以进行适当的缓存预热
  • 读的顺序是先缓存,后数据库;
  • 写的顺序是先数据库后缓存

3.3 Redis与Memcached比较

Redis Memcached
支持的数据结构 哈希、列表、集合、有序集合 纯kev-value
持久化支持
高可用支持 redis天然支持集群功能,可以实现主动复制,读写分离。官方也提供了sentinel集群管理工具,能够实现主从服务监控,故障自动转移,这一切,对于客户端都是透明的,无需程序改动,也无需人工介入 需要二次开发
存储value容量 最大512M 最大1M
内存分配 临时申请空间,可能导致碎片 预分配内存池的方式管理内存,能够省去内存分配时间
虚拟内存使用 有自己的VM机制,理论上能够存储比物理内存更多的数据,当数据超量时,会引发swap,把冷数据刷到磁盘上 所有的数据存储在物理内存里
网络模型 非阻塞IO复用模型,提供一些非KV存储之外的排序,聚合功能,在执行这些功能时,复杂的CPU计算,会阻塞整个IO调度 非阻塞IO复用模型
水平扩展的支持 暂无 暂无
多线程 Redis支持单线程 Memcached支持多线程,CPU利用方面Memcache优于Redis
过期策略 有专门线程,清除缓存数据 懒淘汰机制:每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期
单机QPS 约10W 约60W
源代码可读性 代码清爽简洁 能是考虑了太多的扩展性,多系统的兼容性,代码不清爽
适用场景 复杂数据结构、有持久化、高可用需求、value存储内容较大 纯KV,数据量非常大,并发量非常大的业务

下一篇 分布式缓存下—缓存架构设计常见问题以及解决方案

你可能感兴趣的:(分布式,缓存,CDN,设计原则,反向代理,过期策略)