写点什么

5.2 分布式缓存架构:常见的缓存实现形式

用户头像
张荣召
关注
发布于: 2020 年 10 月 25 日

1. 正向代理缓存

代理用户,部署在用户端。


2.反向代理缓存

代理服务器,部署在服务端(数据中心)。


3.多层反向代理缓存

代理内部服务器,部署在服务端(数据中心)。


4.内容分发网络(CDN)

价值:离用户更近,加快访问速度,降低数据中心服务器负载压力。


5.CDN 同时配置静态文件和动态内容



6.通读缓存(read-through)


             1.正向代理缓存,反向代理缓存,CDN 缓存都是通读缓存。

             2.通读缓存给客户端返回缓存资源,并在请求未命中缓存时获取实际数据。

             3.客户端连接的是通读缓存而不是生成响应的原始服务器。

            特点:客户端不直接连接到数据源---客户端不需要知道实际数据源位置


7.旁路缓存(cache-aside)

      1.对象缓存是一种旁路缓存,旁路缓存通常是独立的键值对存储(key-value)

      2.应用代码通常会询问对象缓存需要的对象是否存在,如果存在,它会获取并使用缓存的对象;

     如果不存在或已经过期,应用会连接主数据源组装数据,并将其保存回到对象缓存中,以便将来使用。

              特点:客户端直连数据源-----客户端需要知道数据源位置+旁路缓存位置。


  • 浏览器对象缓存--旁路缓存

      //在 WebStorage 中缓存对象的 Javascript 代码

      var preferences=   { /*data object to be stored */};

      localStorage.setItem('preferences',JSON.stringify(preferences));


     //访问缓存对象的 Javascript 的代码

     var cacheData=localStorage.getItem('preferences');

     var preferences=JSON.parse(cachedData);

  • 本地对象缓存

     1.对象直接缓存在应用程序内存中。

     2.对象存储在共享内存,同一台机器的多个进程可以访问他们。

     3.缓存服务作为独立应用和应用程序部署在同一台服务器上。 

8.本地对象缓存构建分布式集群


   1.本地缓存构建分布式集群。

   2.每台服务器缓存同样的数据(假设为:key1=value1)。问题:其中一台服务器更新缓存对象 key1(key1=value1.1),其他服务器缓存为就数据 value1,造成读取脏数据。

   3.jboss 方案:自己同步更新缓存-----A 服务器缓存更新后,通知集群中其他服务器同步更新。次生问题:如果集群规模较大,比如 10000 台服务器,每台服务器同步更新缓存,产生大量网络流量。

   缺点:1.每台服务器缓存数据都是一样的。需要缓存大量数据时,有限的内存缓存的同样数据,浪费内存资源。

             2.A 更新缓存时,同步更新集群中其他服务器缓存。占用有限的带宽网络资源。

             3.没有足够的数据放到缓存中,降低缓存命中率。

   ====>互联网早期方案,但是因为这些缺点,很快就被放弃。

9.远程分布式对象缓存



优点:

1.不再争用资源:不再争用前端服务器内部的内存资源。有利于提高前端服务器自身的性能和扩展性。

2.可构建集群:缓存部署在专用的服务器上,可以构建成为集群,有利于自身集群的性能和扩展性。

                     当集群存储空间不足时,可以添加服务器提供更多的内存,存储更多的数据。

                      有利于线性伸缩。

                   ==>现代互联网常用的缓存架构设计方案-----分布式缓存:Memcached,Redis

10.Memcached 分布式对象缓存


      //PHP 客户端访问 Memcached 集群

      $m=new Memcached();

      //添加服务器集群

      $cache->addServers(array(

           array('cache1.example.com',11211),

           array('cache2.example.com',11211),

           array('cache3.example.com',11211),

      ));

      //写缓存,失效时间 5 分钟

      $m->set('userCount',123,600); //根据 Key 计算服务器地址

     //读缓存:

     $m->get('userCount'); //根据 Key 计算服务器地址


    share-nothing 架构:虽然构建了集群, Memcached 服务器之间相互独立,不共享任何信息,不相互通信,不相互感知对方。

    有 memcached 客户端来控制 memcached 服务器访问。服务器的增减,有客户端做相应调整。客户端能够感知到集群中的服务器。

11.Memcached 分布式缓存访问模型


       假如:路由算法:取模余数法。

       当前 Memcached 服务器有三台,路由算法:根据 Key 计算 hash 值,hash 值 %3=【0-2】,有余数计算得到目标服务器地址。

       比如:key="beijing";

                "beijing".hashCode()=10;

                10%3=1;

                ====>目标服务器地址:Node1(10.0.0.1:9100)。 

      

       分布式缓存集群要求可伸缩:增加一台 memcached 服务器至 4 台。仍然使用取模余数法: hashCode%4=【0-3】.

       同理分析:key="beijing"; 

                      "beijing".hashCode()=10;

                      10%4=2;====>目标服务器地址:Node2(10.0.0.2:9100)。

        问题:路由算法改变,导致相同的 key,不能命中同一台服务器。

        延申:大型互联网分布式缓存集群,增加一台服务器后,原本目的:增加内存,缓存更多的数据,提高缓存命中率。

        结果:采用取模余数法,缓存不被命中,集群失效,虽然数据仍然在缓存中,但是不能被命中。

                  大量请求涌向数据库,数据库负载急剧升高,可能超过数据库的最大承受能力,

                 导致数据库崩溃==>应用崩溃==>整个系统崩溃。

                 ===>没有达到线性伸缩目的:集群扩容。

        根本原因:路由算法的改变,路由算法不合适。 ===>达到集群扩容的目的,应该采用什么算法呢?


用户头像

张荣召

关注

还未添加个人签名 2018.05.02 加入

还未添加个人简介

评论

发布
暂无评论
5.2分布式缓存架构:常见的缓存实现形式