복붙노트

[REDIS] 어떻게 루아 스크립트의 한계에서 레디 스 호출을 피하기 위해?

REDIS

어떻게 루아 스크립트의 한계에서 레디 스 호출을 피하기 위해?

나는 PHP가 레디 스 및 APCu 모두를 사용합니다 캐시 구현을 태그 설정하고있다. APC는 키 - 값 저장소입니다, 나는 APC의 각 웹 서버와 키 태그 관계 및 synchoronize에 대한 레디 스를 사용하는거야.

나의 현재 질문에 관해서 만 레디 스. 아마 당신은 구현을 알고 있지만 상황이 명확하게하려면 다음 키와 연관된 태그를 가질 수 있습니다. 시간의 일부 이후 시점에서 당신은 어떤 태그에 의해 캐시 키를 삭제할 수 있습니다. 많은 키와 많은되지 태그가와 키와 태그 사이의 N-에-N 관계가있다.

세트 (키, 값은 태그)로 구성

SET key value
foreach tag in tags
    SADD tag key

검색하거나 설정 한 후 태그를 변경할 필요가 없기 때문에, 난 단지 태그 - 투 - 키 관계를 유지해야합니다.

deleteByTag (태그)입니다

keys = SUNION tag1 tag2 tag3...
DEL key1 key2 key2...

빨리 일을하려면, 내가 SCRIPT로드하고 EVALSHA를 부르는 2 간단한 루아 스크립트를 만들었습니다.

루아 스크립트 설정 :

redis.call('set', KEYS[1], KEYS[2])
for _, tag in pairs(ARGV) do
    redis.call('sadd', tag, KEYS[1])
end

호출

EVALSHA setHash 2 key value tag1 tag2 tag3...

deleteByTag 스크립트이 같은 외모에 문제가 :

redis.call('del', unpack(redis.call('sunion', unpack(ARGV))))
redis.call('del', unpack(ARGV))

호출

EVALSHA deleteByTagHash 0 tag1 tag2 tag3...

모든 제외 잘 때 redis.call ( 'sunion'압축 풀기 (ARGV)) 키의 반환을 많이. 루아는 방법이 가질 수있는 인수의 수에 하드 제한이 보인다. 내 환경에서는 8000입니다. 나는 피에 불과 태그에 의해 키를 취소 할 수있는 방법이 있는지 알고 싶어 :

다음은 빠른 충분히 작동하지 않는 경우 (2)

for _, key in pairs(redis.call('sunion', unpack(ARGV))) do
    redis.call('del', key)
end
redis.call('del', unpack(ARGV))

해결법

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

    1.나는 거의 확실히, 당신은 (루아 환경) 사용자 환경의 luaconf.h에서 LUAI_MAXCSTACK 값을 변경하고 다시 작성하는 번호 (8000)를 증가시킬 수 있어요.

    나는 거의 확실히, 당신은 (루아 환경) 사용자 환경의 luaconf.h에서 LUAI_MAXCSTACK 값을 변경하고 다시 작성하는 번호 (8000)를 증가시킬 수 있어요.

    이미 눈치 챘을 기본적 하나입니다 :

    /*
    @@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
    @* can use.
    ** CHANGE it if you need lots of (Lua) stack space for your C
    ** functions. This limit is arbitrary; its only purpose is to stop C
    ** functions to consume unlimited stack space. (must be smaller than
    ** -LUA_REGISTRYINDEX)
    */
    #define LUAI_MAXCSTACK  8000
    

    만 그것은 포르노 a를 비트처럼 보인다.

    어떤 테이블을 사용하고 table.concat을 통해 <= 8000 키의 () 덩어리를 반복 어떻습니까?

  2. ==============================

    2.동일한 문제가 있었고,이 루아 기능을 해결 :

    동일한 문제가 있었고,이 루아 기능을 해결 :

    local call_in_chunks = function (command, args)
        local step = 1000
        for i = 1, #args, step do
            redis.call(command, unpack(args, i, math.min(i + step - 1, #args)))
        end
    end
    
    call_in_chunks('del', keys)
    
  3. from https://stackoverflow.com/questions/19202367/how-to-avoid-redis-calls-in-lua-script-limitations by cc-by-sa and MIT license