[hash] redis에서 “HSET”자식 키를 “EXPIRE”하는 방법은 무엇입니까?

1 개월이 지난 redis 해시의 모든 키를 만료시켜야합니다.



답변

이것은 Redis를 단순하게 유지 하기 위해 불가능 합니다 .

Redis의 창시자 Quoth Antirez :

안녕하세요, 해당 특정 필드에 대해 다른 최상위 키를 사용하거나 만료 시간이있는 다른 필드와 함께 저장하고 둘 다 가져 와서 애플리케이션이 여전히 유효한지 여부를 이해하도록하는 것은 불가능합니다. 현재 시간.


답변

Redis는 TTL 전체 해시를 만료시키는 최상위 키 이외의 해시 사용을 . 샤딩 된 클러스터를 사용하는 경우 사용할 수있는 다른 접근 방식이 있습니다. 이 접근 방식은 모든 시나리오에서 유용 할 수는 없으며 성능 특성이 예상되는 것과 다를 수 있습니다. 여전히 언급할만한 가치가 있습니다 :

해시가있을 때 구조는 기본적으로 다음과 같습니다.

hash_top_key
  - child_key_1 -> some_value
  - child_key_2 -> some_value
  ...
  - child_key_n -> some_value

TTL자식 키 에 추가하고 싶기 때문에 상위 키로 이동할 수 있습니다. 요점은 이제 키가 hash_top_key와 자식 키 의 조합이어야한다는 것입니다 .

{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value

우리는 {}의도적으로 표기법을 사용하고 있습니다. 이렇게하면 모든 키가 동일하게 떨어 hash slot집니다. https://redis.io/topics/cluster-tutorial 에서 자세한 내용을 읽을 수 있습니다.

이제 동일한 해시 작업을 수행하려면 다음을 수행 할 수 있습니다.

HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1

HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1

HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]

HGETALL hash_top_key =>
  keyslot = CLUSTER KEYSLOT {hash_top_key}
  keys = CLUSTER GETKEYSINSLOT keyslot n
  MGET keys

여기서 흥미로운 것은입니다 HGETALL. 먼저 우리 hash slot는 모든 자녀 키를 얻습니다 . 그런 다음 특정 키를 얻고 hash slot마지막으로 값을 검색합니다. 여기에주의해야합니다. n키 보다 더 많은 키 hash slot가있을 수 있고 우리가 관심이없는 키가있을 수 있지만 동일한hash slot 입니다. 또는 명령 Lua을 실행하여 서버에서 이러한 단계를 수행 하는 스크립트를 실제로 작성할 수 있습니다. 다시 말하지만, 특정 시나리오에 대해이 접근 방식의 성능을 고려해야합니다.EVALEVALSHA

더 많은 참조 :


답변

엔트리 TTL 지원으로 해시 객체 를 구현 하는 Redisson 자바 프레임 워크가 Map있습니다. 그것은 사용 hmapzset레디 스는 후드 객체. 사용 예 :

RMapCache<Integer, String> map = redisson.getMapCache('map');
map.put(1, 30, TimeUnit.DAYS); // this entry expires in 30 days

이 접근 방식은 매우 유용합니다.


답변

이것은 Redis의 Fork 인 KeyDB 에서 가능합니다 . Fork이기 때문에 Redis와 완벽하게 호환되며 드롭 인 대체물로 작동합니다.

EXPIREMEMBER 명령을 사용하십시오. 세트, 해시 및 정렬 된 세트와 함께 작동합니다.

EXPIREMEMBER 키 이름 하위 키 [시간]

TTL 및 PTTL을 사용하여 만료를 확인할 수도 있습니다.

TTL 키 이름 하위 키

https://docs.keydb.dev/docs/commands/#expiremember 에서 더 많은 문서를 사용할 수 있습니다.


답변

NodeJS 구현과 관련 expiryTime하여 HASH에 저장 한 객체에 사용자 정의 필드를 추가했습니다 . 그런 다음 특정 기간이 지난 후 다음 코드를 사용하여 만료 된 HASH 항목을 지 웁니다.

client.hgetall(HASH_NAME, function(err, reply) {
    if (reply) {
        Object.keys(reply).forEach(key => {
            if (reply[key] && JSON.parse(reply[key]).expiryTime < (new Date).getTime()) {
                client.hdel(HASH_NAME, key);
            }
        })
    }
});


답변

할 수 있습니다. 여기에 예가 있습니다.

redis 127.0.0.1:6379> hset key f1 1
(integer) 1
redis 127.0.0.1:6379> hset key f2 2
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> expire key 10
(integer) 1
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key
1) "1"
2) "1"
3) "2"
redis 127.0.0.1:6379> hvals key

사용 EXPIRE 또는 EXPIREAT 명령을 .

1 개월이 지난 해시의 특정 키를 만료하려는 경우. 이건 불가능 해. Redis expire 명령은 해시의 모든 키에 대한 것입니다. 일일 해시 키를 설정하면 키 수명을 설정할 수 있습니다.

hset key-20140325 f1 1
expire key-20140325 100
hset key-20140325 f1 2


답변

이를 위해 Redis에 키 / 값을 다르게 저장할 수 있습니다. 예를 들어 “hset_”와 같이 키를 저장할 때 키에 접두사 또는 네임 스페이스를 추가하면됩니다.

  • 다음과 같은 키 / 값 가져 GET hset_key오기HGET hset key

  • 키를 추가 / 값 SET hset_key value에 동일HSET hset key

  • 다음과 같은 모든 키 가져 KEYS hset_*오기HGETALL hset

  • 모든 KEYS hset_*값 가져 오기는 2 개의 작업으로 수행되어야하며 먼저 모든 키를 가져온 다음 각 키의 값을 가져옵니다.

  • TTL을 사용 하여 키 / 값을 추가 하거나 문제의 주제 인 만료 :

 SET hset_key value
 EXPIRE hset_key

참고 : KEYS특히 큰 데이터베이스가있는 경우 성능에 영향을 미칠 수있는 전체 데이터베이스에서 키와 일치하는지 검색합니다.

노트 :

  • KEYS특히 큰 데이터베이스가있는 경우 성능에 영향을 미칠 수있는 전체 데이터베이스에서 키와 일치하는지 검색합니다. 동안은 SCAN 0 MATCH hset_*이 서버를 차단하지 않습니다하지만 여전히 성능이 큰 데이터베이스의 경우 문제는만큼 더 좋을 수 있습니다.

  • 특히 작은 키 집합 인 경우 만료하려는 이러한 키를 별도로 저장하기 위해 새 데이터베이스를 만들 수 있습니다.

관련 성능 문제를 강조한 @DanFarrell에게 감사드립니다.
KEYS