복붙노트

[REDIS] 어떻게 핸들 세션 레디 스를 내놓고 만료?

REDIS

어떻게 핸들 세션 레디 스를 내놓고 만료?

나는 레디 스를 기반으로 세션 저장소를 구현하려는. 나는 레디 스에 세션 데이터를 넣어 싶습니다. 하지만 세션이-만료 처리하는 방법을 모르겠어요. 나는 키 (세션 id를) 모두를 통해 루프를 레디 스 내가 클라이언트에 모든 키를로드해야하므로, 마지막 액세스 시간 및 최대 대기 시간을 평가하고,이 1,000m 세션 키가 될 수 있으며, 매우 가난 I / O로 이어질 수 있습니다 공연. 나는 레디 스이 만료 관리 할 수 ​​있도록하고 싶지만, 키가 만료 때 HttpSessionListener을 유발하는 것은 불가능하므로 더 리스너 또는 콜백이 없다. 어떤 충고?

해결법

  1. ==============================

    1.당신이 당신의 응용 프로그램이 필요합니다 그래서 세션이 레디 스에 만료 될 때 통지합니다.

    당신이 당신의 응용 프로그램이 필요합니다 그래서 세션이 레디 스에 만료 될 때 통지합니다.

    레디 스에서이 기능을 지원하지 않지만, 당신이 그것을 구현하는 데 사용할 수있는 트릭은 여러 가지가있을 수 있습니다.

    업데이트 : 버전 2.8.0에서 레디 스이를 지원 http://redis.io/topics/notifications 않습니다

    이 논의 아직이지만, 레디 스의 미래 버전에 추가 될 수 있습니다 첫째, 사람들은 그것에 대해 생각된다. 다음과 같은 문제를 참조하십시오 :

    자, 여기 당신이 현재 레디 스 버전과 함께 사용할 수있는 몇 가지 솔루션입니다.

    해결 방법 1 : 레디 스 패치

    사실, 간단한 알림을 추가하면 레디 스 키 만료가 어렵지 않다 수행 할 때. 그것은 레디 스 소스 코드의 db.c 파일에 10 줄을 추가하여 구현 될 수있다. 다음은 그 예이다 :

    https://gist.github.com/3258233

    는 '@'문자 (임의 선택)와이 짧은 패치 #expired 목록에 키가 키가 만료 된 경우 게시물이 시작됩니다. 그것은 쉽게 여러분의 필요에 적용 할 수 있습니다.

    당신의 세션 개체에 대한 만료 시간을 설정하려면이 만료되거나 SETEX 명령을 사용하고 "#expired"목록에서 디큐에 BRPOP에 루프 작은 데몬을 작성하고 응용 프로그램에서 알림을 전파 한 후 간단하다.

    중요한 점은 유효일 메커니즘은 레디 스에서 어떻게 작동하는지 이해하는 것입니다. 만기에 두 개의 서로 다른 경로, 동시에 활성 모두 사실이 있습니다 :

    참고 위의 패치는 두 경로로 벌금을 작동합니다.

    결과는 레디 스 만료 시간이 정확하지 않은 것입니다. 모든 키가 만료을 가지고 있지만, 경우 하나는 활성 만료 작업이 열쇠를 찾기 위해 몇 분 정도 걸릴하고 만료 수, 만료되기 직전에, 그것은 액세스 할 수 없습니다. 당신이 알림에 약간의 정확성을 필요로하는 경우, 이것은가는 방법이 아니다.

    해결 방법 2 : zsets로 만료를 시뮬레이션

    레디 스 키 만료 메커니즘에 의존하지만, 추가 인덱스 플러스 폴링 데몬을 사용하여 시뮬레이션 할에 생각이 여기입니다. 이 수정되지 않은 레디 스 2.6 버전으로 작업 할 수 있습니다.

    세션이 레디 스에 추가 될 때마다, 당신은 실행할 수 있습니다 :

    MULTI
    SET <session id> <session content>
    ZADD to_be_expired <current timestamp + session timeout> <session id>
    EXEC
    

    to_be_expired 소트 세트가 만료되어야하는 첫 번째 키에 액세스하기위한 단지 효율적인 방법입니다. 데몬은 다음 루아 서버 측 스크립트를 사용하여 to_be_expired에 폴링 할 수 있습니다 :

    local res = redis.call('ZRANGEBYSCORE',KEYS[1], 0, ARGV[1], 'LIMIT', 0, 10 )
    if #res > 0 then
       redis.call( 'ZREMRANGEBYRANK', KEYS[1], 0, #res-1 )
       return res
    else
       return false
    end
    

    스크립트를 실행하는 명령은 다음과 같습니다

    EVAL <script> 1 to_be_expired <current timestamp>
    

    데몬은 가장 10 개 항목에 얻을 것이다. 이들 각각의 경우, 세션을 제거하고 응용 프로그램을 알리기 위해 DEL 명령을 사용한다. 하나 개의 아이템이 실제로 (즉 루아 스크립트의 수익이 비어 있지 않은) 처리 된 경우, 데몬 루프 즉시 달리 1 개 초 대기 상태가 도입 될 수있는 것이다.

    루아 스크립트 덕분에,이 병렬로 여러 폴링 데몬을 실행 할 수 있습니다 (키가 루아 스크립트 자체에 의해 to_be_expired에서 제거되기 때문에 주어진 세션은, 한 번에 처리되는 것을 스크립트 보장).

    해결 방법 3 : 외부 분산 타이머를 사용

    또 다른 해결책은 외부 분산 타이머에 의존하는 것입니다. 큐잉 시스템 경량 콩나무이에 대한 좋은 가능성입니다

    세션이 시스템에 추가 될 때마다 지연을 가진 콩나무 큐 애플리케이션 포스트 세션 ID는 세션 타임 아웃에 대응. 데몬은 큐 듣고있다. 이 항목을 큐에서 제거 할 때 세션이 만료 된 것을 의미한다. 그것은 단지 레디 스에서 세션을 청소하고 응용 프로그램을 통지해야한다.

  2. from https://stackoverflow.com/questions/11810020/how-to-handle-session-expire-basing-redis by cc-by-sa and MIT license