2012-12-12 2 views
6

미디어 객체를 저장하려고하고 redis를 통해 특정 시간 범위로 검색 할 수 있습니다. 이 작업을 수행하려면 정렬 된 집합 데이터 형식을 선택했습니다. 나는 다음과 같은 요소를 추가하고 있습니다 :redis에서 정렬 된 세트의 고유성 확인

zAdd: key: media:552672 score: 1355264694 
zAdd: key: media:552672 score: 1355248565 
zAdd: key: media:552672 score: 1355209157 
zAdd: key: media:552672 score: 1355208992 
zAdd: key: media:552672 score: 1355208888 
zAdd: key: media:552672 score: 1355208815 

여기서 key는 미디어가 촬영 된 위치 ID에 고유하며 점수는 미디어 객체의 생성 시간입니다. 그리고 그 값은 미디어 객체의 json_decode입니다.

zRevRangeByScore을 사용하여 검색 할 때 가끔 중복 된 항목이 있습니다. 필자는 본질적으로 외부 API에 대한 버퍼로 Redis를 사용하고 있습니다. 사용자가 동일한 API 호출을 X 초 동안 두 번 수행하면 캐시에서 결과를 검색합니다. 그렇지 않으면 캐시에 추가하고 체크하지 않습니다. 중복을 포함하지 않는 세트의 정의로 인해 이미 존재하는지 확인하십시오. 알려진 문제 : 캐싱간에 미디어 개체 특성이 변경된 경우 중복으로 표시됩니다.

redis 클라이언트 측에서 확인하지 않고 이러한 유형의 데이터를 저장하는 더 좋은 방법이 있습니까?

TLDR; 타임 스탬프로 오브젝트 범위를 선택하고 고유 한 것을 보장 할 수있는 Redis의 오브젝트를 저장하고 검색하는 가장 좋은 방법은 무엇입니까?

답변

23

는, 그래서 여기에 있는지 우리가 같은 것들에 대해 얘기 할 수 있습니다 레디 스이 세트 분류에 대한 용어입니다 :

ZADD key score member [score] [member] 
summary: Add one or more members to a sorted set, or update its score if it already exists 
  • key를 - '이름'의
  • score을 설정 분류를 - 점수 (우리의 경우 타임 스탬프)
  • member - 점수가 연결되는 문자열
  • 정렬 된 집합에는 점수가있는 많은 구성원이 있습니다.

JSON으로 인코딩 된 객체 문자열을 회원으로 사용하는 것 같습니다. 구성원은 정렬 된 집합에서 고유 한 것입니다. 말한대로, 개체가 변경되면 정렬 된 집합에 새 구성원으로 추가됩니다. 그것은 아마도 당신이 원하는 것이 아닙니다.

정렬 된 집합은 타임 스탬프별로 데이터를 저장하는 Redis 방식이지만 집합에 저장된 구성원은 대개 Redis의 다른 키에 대한 '포인터'입니다.

  • A가 생성 된 타임 스탬프

내가 저장하는 것이 좋습니다 각각의 고유 한 미디어에 대한 문자열 또는 해시 모든 미디어를 저장 소트 세트 : 귀하의 설명에서

난 당신이 데이터 구조를 원한다고 생각 해시에있는 미디어 객체는 더 많은 유연성을 허용합니다. 예 :이 방법으로 저장된 데이터를 검색하는 방법은 두 가지가 있습니다

# add some members to our sorted set 
redis 127.0.0.1:6379> ZADD media 1000 media:1 1003 media:2 1001 media:3 
(integer) 3 
# create hashes for our members 
redis 127.0.0.1:6379> HMSET media:1 id 1 name "media one" content "content string for one" 
OK 
redis 127.0.0.1:6379> HMSET media:2 id 2 name "media two" content "content string for two" 
OK 
redis 127.0.0.1:6379> HMSET media:3 id 3 name "media three" content "content string for three" 
OK 

.특정 타임 스탬프 범위 (예 : 지난 7 일) 내에 구성원을 가져 오려면 ZREVRANGEBYSCORE을 사용하여 구성원을 검색 한 다음 HGETALL 또는 그와 유사한 각 해시를 가져 오는 멤버를 반복해야합니다. 서버 호출 한 번으로 루프를 수행하는 방법은 pipelining을 참조하십시오. 당신은 단지 마지막 n 회원 얻고 싶은 경우에

redis 127.0.0.1:6379> ZREVRANGEBYSCORE media +inf -inf 
1) "media:2" 
2) "media:3" 
3) "media:1" 
redis 127.0.0.1:6379> HGETALL media:2 
1) "id" 
2) "2" 
3) "name" 
4) "media two" 
5) "content" 
6) "content string for two" 

(또는 예 :에 10이 가장 최근의 가장 최근 100) 당신이 항목을 얻을 SORT를 사용할 수 있습니다. 구문 및 다른 해시 필드를 검색하고 결과 및 기타 옵션을 제한하는 방법은 sort documentation을 참조하십시오.

redis 127.0.0.1:6379> SORT media BY nosort GET # GET *->name GET *->content1) DESC 
1) "media:2" 
2) "media two" 
3) "content string for two" 
4) "media:3" 
5) "media three" 
6) "content string for three" 
7) "media:1" 
8) "media one" 
9) "content string for one" 

NB : 점수 (BY nosort)에 의해 정렬 된 해시를 정렬은 레디 스 2.6에서 작동합니다.

마지막 날, 주, 달 등의 미디어를 가져올 계획이라면 각 미디어에 대한 별도의 정렬 된 세트를 사용하고 ZREMRANGEBYSCORE을 사용하여 이전 멤버를 제거하는 것이 좋습니다. 이러한 정렬 된 집합에 SORT을 사용하여 데이터를 검색 할 수 있습니다.

+0

감사합니다. 정확한 것을 찾고있었습니다. 한 가지 간단한 질문 : 중복되는 것을 원하지 않는 상황이 있으므로 정렬 된 집합을 검사 한 다음 해시를 추가하고 추가합니다. 나는 그것이 지나친 것이라고 묻고 싶었다. –