(八)实际项目中涉及到的缓存数据结构及算法

软件开发中常用的缓存算法主要有:FIFO-先进先出算法,LRU-最近最久未使用,LFU-最近最少使用。实际项目中缓存算法对这些都有涉及。

一、理论:

1.FIFO(First Input First Output):

特点:先进先出,符合公平性,实现简单。

数据结构使用对列

淘汰原则:如果一个数据最先进入缓存中,则应该最早淘汰掉。也就是说,当缓存满的时候,应当把最先进入缓存的数据给淘汰掉。

2.LRU(Least Recently Used):

特点:按照时间长短,最不经常使用的缓存数据,先淘汰。

数据结构:链表和hashmap

淘汰原则:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。

3.LFU(Least Frequently Used):

特点:按照访问次数,最近最少使用的缓存数据,先淘汰。

数据结构:数组、hashmap、堆

淘汰原则:如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。

二、实际项目中使用(java项目为例):

1.ehcache框架:

Ehcache配置参数(具体参数含义请查找资料):


缓存的3 种清空策略 :

FIFO :first in first out (先进先出).
LFU : Least Frequently Used (最不经常使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
LRU :Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

2.Redis缓存回收策略配置:


(一)、最大缓存设置

示例:maxmemory 15000mb 
单位:mb,gb。
默认为0,没有指定最大缓存,如果有新的数据添加,超过最大内存,则会使redis崩溃,所以一点要设置。
设置maxmemory之后,配合的要设置缓存数据回收策略。


(二)、回收策略算法设置

 当maxmemory限制到达的时候,Redis将采取的准确行为是由maxmemory-policy配置指令配置的。 
    以下策略可用: 
(1)、noeviction:当到达内存限制时返回错误。当客户端尝试执行命令时会导致更多内存占用(大多数写命令,除了DEL和一些例外)。
(2)、allkeys-lru:回收最近最少使用(LRU)的键,为新数据腾出空间。
(3)、volatile-lru:回收最近最少使用(LRU)的键,但是只回收有设置过期的键,为新数据腾出空间。
(4)、allkeys-random:回收随机的键,为新数据腾出空间。
(5)、volatile-random:回收随机的键,但是只回收有设置过期的键,为新数据腾出空间。
(6)、volatile-ttl:回收有设置过期的键,尝试先回收离TTL最短时间的键,为新数据腾出空间。

使用策略规则:
(1)、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru。
(2)、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random。
 
redis回收算法,实际不是严谨的LRU算法,而是抽样回收数据,这样算是为了减少消耗内存使用,但是抽样回收的缓存和全部数据回收缓存差异非常小,或者根本就没有。

(三)、生产使用

(1)、先预测好系统所需要的内存高峰,部署相对应内存的缓存服务器。
(2)、设置maxmemory和相对应的回收策略算法,设置最好为物理内存的3/4,或者比例更小,因为redis复制数据等其他服务时,也是需要缓存的。以防缓存数据过大致使redis崩溃,造成系统出错不可用。牺牲一部分缓存数据,保存整体系统可用性。

3.Memcached缓存策略:

(一).memcached缓存原理:

Memcached有两个核心组件组成:服务端(ms)和客户端(mc)。首先mc拿到ms列表,并对key做hash转化,根据hash值确定kv对所存的ms

位置。然后在一个memcached的查询中,mc先通过计算key的hash值来确定kv对所处在的ms位置。当ms确定后,客户端就会发送一个查询请求

给对应的ms,让它来查找确切的数据。因为ms之间并没有护卫备份,也就不需要互相通信,所以效率较高。

(二)、缓存策略:     

       Memcached会优先使用已超时的记录空间,但即使如此,也会发生追加新纪录时空间不足的情况。此时就要使用名为Least Recently Used (LRU)机制来分配空间。这就是删除最少使用的记录的机制。因此当memcached的内存空间不足时获取到新空间时,就从最近未使用的记录中搜索,并将空间分配给新的记录。

(三)、客户端代码示例:

spring集成memcache示例:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.            http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.   
  7.     <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool"   
  8.         factory-method="getInstance" init-method="initialize">  
  9.         <constructor-arg>  
  10.             <value>neeaMemcachedPool</value>  
  11.         </constructor-arg>  
  12.         <property name="servers">  
  13.             <list>  
  14.                 <value>127.0.0.1:11211</value>  
  15.             </list>  
  16.         </property>  
  17.         <property name="initConn">  
  18.             <value>20</value>  
  19.         </property>  
  20.         <property name="minConn">  
  21.             <value>10</value>  
  22.         </property>  
  23.         <property name="maxConn">  
  24.             <value>50</value>  
  25.         </property>  
  26.         <property name="nagle">  
  27.             <value>false</value>  
  28.         </property>  
  29.         <property name="socketTO">  
  30.             <value>3000</value>  
  31.         </property>  
  32.     </bean>  
  33.     <bean id="memcachedClient" class="com.danga.MemCached.MemCachedClient">  
  34.         <constructor-arg>  
  35.             <value>neeaMemcachedPool</value>  
  36.         </constructor-arg>  
  37.     </bean>  
  38. </beans>  
测试用例:

  1. public class MemcachedSpringTest {    
  2.     
  3.     private MemCachedClient cachedClient;    
  4.         
  5.     @Before    
  6.     public void init() {    
  7.         ApplicationContext context = new ClassPathXmlApplicationContext("com/luo/config/beans.xml");    
  8.         cachedClient = (MemCachedClient)context.getBean("memcachedClient");    
  9.     }    
  10.         
  11.     @Test    
  12.     public void testMemcachedSpring() {    
  13.         UserBean user = new UserBean("luo""hi");    
  14.         cachedClient.set("user", user);    
  15.         UserBean cachedBean = (UserBean)user;    
  16.         Assert.assertEquals(user, cachedBean);    
  17.     }    
  18. }    
注意点:
memcached是在服务器端的内存中缓存对象的,没有持久化到硬盘,是一个纯内存式的分布式缓存服务系统;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值