로 컬 캐 시 와 LRU

9008 단어
LRU 는 메모리 도태 알고리즘 으로 실제 적 으로 해석 하 는 것 도 매우 간단 하 다. 두 가지 차원 으로 나 뉜 다. 1. 용량;2. 시간.
우 리 는 경계 대기 열 이 있 습 니 다. 그 안에 데 이 터 를 계속 기록 하면 가득 차 있 을 것 입 니 다. 이 럴 때 데 이 터 를 도태 시 켜 야 합 니 다.용량 을 초과 하면 데 이 터 를 삽입 할 때 어떤 데 이 터 를 도태 시 켜 야 합 니까?그것 은 자주 사용 하지 않 는 냉 데이터 다.LRU 의 주 지 는 최근 에 자주 사용 하 는 데 이 터 를 저장 하 는 것 입 니 다. 자주 사용 하 는 데 이 터 를 핫 이 슈 데이터 라 고 합 니 다. 그들의 가 치 는 자주 방문 되 고 캐 시 에서 가 져 오 면 데이터 베이스 등 다른 저장 소 에 자주 접근 하지 않 아 도 됩 니 다. 그러면 프로그램의 효율 을 높 일 수 있 습 니 다.
일반적인 캐 시 용 기 는 모두 양 끝 대기 열 형 으로 head 와 tail 이 있 습 니 다.용량 이 상한 선 에 이 르 렀 을 때 tail 의 요 소 는 팀 에서 나온다.만약 팀 의 요소 가 자주 방문 된다 면, 그것 은 헤드 로 들 어 갈 것 이다.JDK 는 용량 에 따라 팀 을 구성 하 는 데이터 구 조 를 제공 했다. 링크 드 하 쉬 맵.
그 구 조 는 HashMap 의 구조 입 니 다. 이 를 바탕 으로 모든 링크 대상 Entity 는 pre 와 next 지침 (대충 뜻) 을 추가 하여 삽입 순 서 를 표시 합 니 다.그래서 방문 할 때 Hash 의 시스템 O (1) 를 걷 고 옮 겨 다 닐 때 삽입 순 서 를 식별 할 수 있 습 니 다.이와 함께 LRU 도 실현 할 수 있다.  
public class LRULinkedMap extends LinkedHashMap{
    private static final int DEFAULT_CAPACITY = 1<<4;
    private static final float DEFAULT_FACTOR = 0.75f;
    private static final int DEFAULT_LIMIT = DEFAULT_CAPACITY/2;

    private int limit;

    public LRULinkedMap(){
        super(DEFAULT_CAPACITY,DEFAULT_FACTOR,true);
        limit = DEFAULT_LIMIT;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {

        if(this.size() > limit){
            System.out.println("       :"+eldest.getKey()+","+eldest.getValue());
            return true;
        }else {
            return false;
        }
    }
}

removeEldestEntity 를 다시 쓰 는 방법 은 가장 오래된 노드 를 언제 제거 하 는 지 알려 줍 니 다.이곳 에는 두 개의 좋 지 않 은 곳 이 있 는데, 하 나 는 스 레 드 가 안전 하지 않다 는 것 이다.둘째, 용량 에 따라 만 제거 할 수 있 습 니 다. 시간 에 따라 대상 을 놓 을 때 대상 에 시간 스탬프 를 달 고 스스로 실현 해 야 합 니 다.
        LRULinkedMap lruLinkedMap = new LRULinkedMap();
        for(int i=0;i<20;i++){
            String val = "  :"+i;
            System.out.println("    :"+i+","+val);
            lruLinkedMap.put(i,val);
        }
    :0,  :01,  :12,  :23,  :34,  :45,  :56,  :67,  :78,  :8
       :0,  :09,  :9
       :1,  :110,  :10
       :2,  :211,  :11
       :3,  :312,  :12
       :4,  :413,  :13
       :5,  :514,  :14
       :6,  :615,  :15
       :7,  :716,  :16
       :8,  :817,  :17
       :9,  :918,  :18
       :10,  :1019,  :19
       :11,  :11

 
google 은 JVM 캐 시 도 구 를 제공 합 니 다.
        
        <dependency>
            <groupId>com.google.guavagroupId>
            <artifactId>guavaartifactId>
            <version>24.0-jreversion>
        dependency>
        Cache cache = CacheBuilder.newBuilder()
                .maximumSize(1<<4)
                .expireAfterWrite(3,TimeUnit.SECONDS)
                .build();

        cache.put(1,"  1");
        System.out.println("    :"+cache.getIfPresent(1));
        Thread.sleep(5000);
        System.out.println("    :"+cache.getIfPresent(1));
    :  1
    :null

간단 한 구축 으로 JVM 캐 시 를 사용 할 수 있 습 니 다. 로 컬 캐 시 는 네트워크 호출 (Redis, Memcached), 데이터 베이스 접근, RPC 호출 을 절약 하 는 것 이 장점 입 니 다.  
그것 의 put 방법 은 이 렇 습 니 다. 아주 익숙 합 니 다. 바로 1.7 의 hashmap 세그먼트 자물쇠 이기 때문에 스 레 드 가 안전 합 니 다.
    public V put(K key, V value) {
        Preconditions.checkNotNull(key);
        Preconditions.checkNotNull(value);
        int hash = this.hash(key);
        return this.segmentFor(hash).put(key, hash, value, false);
    }

또한 Loading Cache, 어떤 개념 을 제공 합 니까? 실 효 된 Key 는 다시 쓰 는 방법 으로 다시 불 러 옵 니 다. 즉, 데 이 터 를 새로 고 치 는 기능 입 니 다.
캐 시 사용 주 지 는 동정 분리 에 있어 서 별로 변 하지 않 는 데이터 나 실효 성 이 있 고 자주 방문 하 는 데이터 에 대해 캐 시 를 사용 하여 디스크 IO 를 방지 하 는 것 이 시스템 성능 을 향상 시 키 는 방안 입 니 다.

좋은 웹페이지 즐겨찾기