Redis의 기준 수

기수 계수는 원소의 수량을 계산하는 데 사용되며, 어떠한 중복도 존재하지 않는다.Redis에서는 이 작업을 수행할 수 있는 데이터 구조가 많습니다.그러나 당신의 용례에 가장 적합한 방식은 무엇입니까?본고는 기술 선택의 배후 고려 요소를 보여줄 것이다.

사용자 시나리오


만약 우리가 센서 네트워크의 고장률을 얻어 보고서의 질을 조사해야 한다고 가정한다면.따라서 우리는 전송 요청을 통해 시간 단위로 건강 상태를 기록해야 한다.
프로세스를 단순화하는 것이 중요합니다. 먼저 수치를 추출하여 그것이 존재하는지 확인한 다음에 기록을 삽입하고 싶지 않습니다. 예를 들어 다음과 같습니다.

반대로 우리는 매번 기록을 삽입해야 한다. 저장은 우리를 위해 중복을 제거할 수 있다.또는 사전 처리 데이터를 제한하여 저장 속도를 높일 수 있습니다.

Assume that we have a sensor A, and the sensor requested to the server at 1/2 1:11, 1/3 2:22, and 1/8 3:00.


자, 레드스가 기수를 어떻게 계산하는지 봅시다.

설정


기본 사상은 set을 사용하는 것이다.집합에 추가하기 전에, 우리는 반드시 날짜를 미리 처리해야 한다.우리의 요구 때문에, 우리는 시간만 보류하고, 분초는 보류하지 않는다.
const date1 = new Date(2021, 0, 2, 1, 0);
const d1 = date1.toISOString(); 
그리고 우리는 d1를 통해 SADD를 집합에 추가할 수 있다.
SADD sensorA "2021-01-02T01:00:00.000Z"
SADD sensorA "2021-01-03T02:00:00.000Z"
SADD sensorA "2021-01-08T03:00:00.000Z"
건강 상태를 얻기 위해 우리는 SCARD를 사용할 수 있다.
SCARD sensorA
> 3
set을 사용하여 간단함을 실현하기;그러나 2021년 등 특정 시기의 건강 상태를 계산하려면 set에서 이 요청을 처리할 수 없습니다.

정렬 세트


따라서 특정 시간대와 전체 시간대의 수요를 충족시키려면 정렬집을 이용할 수 있다.set과 유사합니다.우선, 날짜를 예처리한다.
const date1 = new Date(2021, 0, 2, 1, 0);
const d1 = date1.getTime();
ISO 문자열을 사용하는 것과 달리, 우리는 여기에서 epoch를 사용하여 특정한 시간 범위를 쉽게 찾을 수 있습니다.현재 우리는 ZADD를 통해 정렬 집합에 추가할 수 있다.
ZADD sensorA 1609520400000 1609520400000
ZADD sensorA 1609610400000 1609610400000
ZADD sensorA 1610046000000 1610046000000
그 중에서 모든 가치를 찾으려면:
ZCARD sensorA
> 3
다른 한편, 특정한 시간 범위를 검색하기 위해 우리는 ZCOUNT에서 시작과 끝을 지정한다.
ZCOUNT sensorA 1609520400000 1610040000000
> 2

비트맵


우리는 두 가지 방법을 겪었지만 집합과 정렬 집합은 모두 공간 효율이 아니다.Redis의 상세한 실현은 데이터 구조를 나타내는 데 많은 공간을 필요로 한다.센서 수가 커지거나 레코드의 지속 시간이 길어지면 Redis의 공간이 빠르게 증가합니다.
어떻게 공간을 줄입니까?우리는 문자열, 비트맵의 확장 기능을 이용할 수 있다.비트맵은 한 사람당 한 자리를 의미로 하여 공간을 매우 절약한다.
그러나 사전 처리가 좀 복잡하기 때문에 우리는 반드시 편이량을 얻어 위치를 조작해야 한다.예를 들어, 서비스 시작 시간과 현재 시간 간의 차이 시간(예: 2021/21:11)을 계산할 수 있습니다.
const base = new Date(2021, 0, 1, 0, 0);
const date1 = new Date(2021, 0, 2, 1, 11);
const diffTime = Math.abs(date1 - base);
const diffHours = Math.ceil(diffTime / (1000 * 60 * 60));
그런 다음 오프셋을 1로 설정합니다.
SETBIT sensorA 26 1
SETBIT sensorA 51 1
SETBIT sensorA 171 1
따라서 우리는 BITCOUNT를 통해 전체적인 건강 상태를 얻을 수 있다.
BITCOUNT sensorA
> 3
BITCOUNT는 범위 일치도 제공하기 때문에 우리는 정렬 집합과 같은 특정한 시간 범위를 검색하기 위해 시작과 끝을 지정할 수 있다.주의해야 할 것은, 이곳의 시작과 끝은 바이트의 편이량을 나타낸다.우리는 시작 시간과 끝 시간을 diff hours 바이트로 바꾸어야 한다. 계산이 매우 복잡하기 때문에, 나는 본문에서 초점을 잃는 것을 방지하기 위해 예를 제공하지 않을 것이다.

초대수


마지막 방법은hyperloglog라고 합니다.이것은 빅데이터 통계 알고리즘이다.Redis는 이를 기본 제공 방법으로 제공합니다.
집합, 정렬 집합이든 비트맵이든 시간이 지날수록 공간 사용량이 커진다.예를 들어, 10년 동안 상태를 유지할 경우 비트맵에도 365*10*24/1024~85.5KB의 많은 공간이 사용됩니다.
그러나hyperlog에서 공간 사용은 고정적이다.hyperloglog는 보존 기간이 얼마나 걸리든지 상관없이 12KB의 공간을 지속적으로 차지합니다.예처리 과정은 설정한 대로
const date1 = new Date(2021, 0, 2, 1, 0);
const d1 = date1.toISOString();
그리고 우리는 PFADD를 통해 날짜를hyperloglog에 추가할 수 있다.
PFADD sensorA "2021-01-02T01:00:00.000Z"
PFADD sensorA "2021-01-03T02:00:00.000Z"
PFADD sensorA "2021-01-08T03:00:00.000Z"
총 계수를 얻는 것은 매우 간단하다.
PFOCUNT sensorA
> 3
Hyperloglog는 정확하지 않아서 데이터 집합이 크면PFCOUNT의 결과는 약간의 편차를 포함할 수 있지만 성능은 상당히 좋다.

결론


이 네 가지 방법을 총결해 봅시다.
설정
정렬 세트
비트맵
초대수
사업을 실시하다
낮았어
낮았어
높았어
낮았어
특정 시간 범위
다섯
다섯
공간 비용
높았어
높았어
낮음 ~ 중간
낮았어
본고의 예는 결코 중요하지 않지만, 나는 당신이 이러한 방법의 개념을 이해할 수 있을 것이라고 믿습니다.가장 중요한 것은 모든 방법이 자신의 장점과 단점을 가지고 지능적인 방식으로 그것을 사용하는 것이 개발자의 책임이다.

좋은 웹페이지 즐겨찾기