SELECT Expire Members


Expire members 정보를 조회

엔터프라이즈 버전에서는 expire를 member(value) 단위로도 설정할 수 있습니다.
그리고 아래와 같은 쿼리로 조회할 수 있습니다.
SELET * FROM EXPIRE_MEMBERS.*;
Datatype 부분에 expire_members를 지정해서 조회하면 됩니다.
컬럼은 key, member(value)와 ttl 입니다. 여기에서도 ttl은 컬럼으로 제공됩니다.

테스트 데이터 입력: Expire를 입력합니다.
입력 방법: expire key member second(expire time)
대상 데이터 타입: SET, ZSET, HASH

Example

명령>expire myset1 mem30 81100
명령>expire myset1 mem20 81200
명령>expire myset2 40 81300
명령>expire myzset1 value10 81400
명령>expire myzset1 value20 81500
명령>expire myzset2 mem40 81600
명령>expire myname1 name 81700
명령>expire myname1 age 81800
명령>expire subject2 name 81900
명령>expire subject2 kor 82000

SELECT

  • Count(key)보다 count(*)가 더 빠릅니다.
    Count(*)는 키 전체 개수를 한번에 가져오고, count(key)는 키를 하나씩 일일이 셉니다.

Example

명령>select count(*) from expire_members.*;   opcode
결과> 0) count(*)
1) 10
명령>select count(key) from expire_members.*;   opcode
결과> 0) count(key)
1) 6
명령>select key from expire_members.*;   opcode
결과> 0) key
1) myname1
2) subject2
3) myzset1
4) myset1
5) myset2
6) myzset2
명령>select * from expire_members.*;   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
6) myzset1|value20|81500
7) myset1|mem30|81100
8) myset1|mem20|81200
9) myset2|40|81300
10) myzset2|mem40|81600

ORDER, LIMIT

Order by key, value 또는 key, ttl 또는 ttl 과 같이 다양하게 사용할 수 있습니다.
Limit를 사용할 수 있습니다.

Example

명령>select * from expire_members.* order by key;   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) myset1|mem30|81100
4) myset1|mem20|81200
5) myset2|40|81300
6) myzset1|value10|81400
7) myzset1|value20|81500
8) myzset2|mem40|81600
9) subject2|name|81900
10) subject2|kor|82000
명령>select * from expire_members.* order by key desc;   opcode
결과> 0) key|value|ttl
1) subject2|name|81900
2) subject2|kor|82000
3) myzset2|mem40|81600
4) myzset1|value10|81400
5) myzset1|value20|81500
6) myset2|40|81300
7) myset1|mem30|81100
8) myset1|mem20|81200
9) myname1|name|81700
10) myname1|age|81800
명령>select * from expire_members.* order by key, value;   opcode
결과> 0) key|value|ttl
1) myname1|age|81800
2) myname1|name|81700
3) myset1|mem20|81200
4) myset1|mem30|81100
5) myset2|40|81300
6) myzset1|value10|81400
7) myzset1|value20|81500
8) myzset2|mem40|81600
9) subject2|kor|82000
10) subject2|name|81900
명령>select * from expire_members.* order by value;   opcode
결과> 0) key|value|ttl
1) myset2|40|81300
2) myname1|age|81800
3) subject2|kor|82000
4) myset1|mem20|81200
5) myset1|mem30|81100
6) myzset2|mem40|81600
7) myname1|name|81700
8) subject2|name|81900
9) myzset1|value10|81400
10) myzset1|value20|81500
명령>select * from expire_members.* order by ttl;   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
3) myset2|40|81300
4) myzset1|value10|81400
5) myzset1|value20|81500
6) myzset2|mem40|81600
7) myname1|name|81700
8) myname1|age|81800
9) subject2|name|81900
10) subject2|kor|82000
명령>select * from expire_members.* limit 5;   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
명령>select * from expire_members.* order by key limit 5;   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) myset1|mem30|81100
4) myset1|mem20|81200
5) myset2|40|81300
명령>select * from expire_members.* order by key limit 3,4;   opcode
결과> 0) key|value|ttl
1) myset1|mem20|81200
2) myset2|40|81300
3) myzset1|value10|81400
4) myzset1|value20|81500

FUNCTIONS

Min(), max(), upper(), length() 등 일반적인 function을 사용할 수 있습니다.

Example

명령>select min(key), max(key) from expire_members.*;   opcode
결과> 0) min(key)|max(key)
1) myname1|subject2
명령>select key, upper(key), length(key) from expire_members.*;   opcode
결과> 0) key|upper(key)|length(key)
1) myname1|MYNAME1|7
2) subject2|SUBJECT2|8
3) myzset1|MYZSET1|7
4) myset1|MYSET1|6
5) myset2|MYSET2|6
6) myzset2|MYZSET2|7

WHERE

  • Expire_members에서는 expire_members.key*와 같이 사용할 수 없습니다.
    Where key = 'key1' or key glob 'key*'와 같이 사용하세요.
  • 키에는 순서가 없지만, 키 안에서는 ttl로 정렬됩니다.

Example

명령>select * from expire_members.* where key <= 'myset1';   opcode
결과> ) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) myset1|mem30|81100
4) myset1|mem20|81200
명령>select * from expire_members.* where key > 'myset1';   opcode
결과> 0) key|value|ttl
1) subject2|name|81900
2) subject2|kor|82000
3) myzset1|value10|81400
4) myzset1|value20|81500
5) myset2|40|81300
6) myzset2|mem40|81600
명령>select * from expire_members.* where key = 'myset1';   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
명령>select * from expire_members.* where key != 'myset1';   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
6) myzset1|value20|81500
7) myset2|40|81300
8) myzset2|mem40|81600
명령>select * from expire_members.* where value = 'name';   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) subject2|name|81900
명령>select * from expire_members.* where value > 'name';   opcode
결과> 0) key|value|ttl
1) myzset1|value10|81400
2) myzset1|value20|81500
명령>select * from expire_members.* where value < 'name';   opcode
결과> 0) key|value|ttl
1) myname1|age|81800
2) subject2|kor|82000
3) myset1|mem30|81100
4) myset1|mem20|81200
5) myset2|40|81300
6) myzset2|mem40|81600
명령>select * from expire_members.* where ttl < 100;   opcode
결과> (nil)
명령>select * from expire_members.* where ttl > 100;   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
6) myzset1|value20|81500
7) myset1|mem30|81100
8) myset1|mem20|81200
9) myset2|40|81300
10) myzset2|mem40|81600

GLOB, LIKE

  • Glob는 와일드카드(wildcard)로 '*'를 사용하고, 대소문자를 구분합니다.
  • Like는 '%'를 사용하고 대소문자 구분없이 비교합니다.

Example

명령>select * from expire_members.* where key glob 'myset*';   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
3) myset2|40|81300
명령>select * from expire_members.* where key like 'myset%';   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
3) myset2|40|81300
명령>select * from expire_members.* where value glob 'name*';   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) subject2|name|81900
명령>select * from expire_members.* where value not glob 'name*';   opcode
결과> 0) key|value|ttl
1) myname1|age|81800
2) subject2|kor|82000
3) myzset1|value10|81400
4) myzset1|value20|81500
5) myset1|mem30|81100
6) myset1|mem20|81200
7) myset2|40|81300
8) myzset2|mem40|81600

BETWEEN, IN

  • BETWEEN, NOT BETWEEN 사용 가능합니다.
  • IN, NOT IN 사용할 수 있습니다.

Example

명령>select * from expire_members.* where key between 'myset1' and 'myset2';   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
3) myset2|40|81300
명령>select * from expire_members.* where key not between 'myset1' and 'myset2';   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
6) myzset1|value20|81500
7) myzset2|mem40|81600
명령>select * from expire_members.* where key in ('myset1','myset2');   opcode
결과> 0) key|value|ttl
1) myset1|mem30|81100
2) myset1|mem20|81200
3) myset2|40|81300
명령>select * from expire_members.* where key not in ('myset1','myset2');   opcode
결과> 0) key|value|ttl
1) myname1|name|81700
2) myname1|age|81800
3) subject2|name|81900
4) subject2|kor|82000
5) myzset1|value10|81400
6) myzset1|value20|81500
7) myzset2|mem40|81600

GROUP

Example

명령>select left(key,5), count(*) from expire_members.* group by left(key,5);   opcode
결과> 0) left(key,5)|count(*)
1) mynam|2
2) myset|3
3) myzse|3
4) subje|2
명령>select left(key,5), min(key), max(key) from expire_members.* group by left(key,5);   opcode
결과> 0) left(key,5)|min(key)|max(key)
1) mynam|myname1|myname1
2) myset|myset1|myset2
3) myzse|myzset1|myzset2
4) subje|subject2|subject2

REDIS FUNCTIONS

  • updatetime(): 키 생성/수정 일시를 리턴합니다.
  • type(): 키의 datatype을 리턴합니다.
  • encoding(): 키의 내부 datatype을 리턴합니다.
  • memory(): 키의 메모리 사용량(value 포함)을 리턴합니다.
  • 기타 여러 function을 사용할 수 있습니다.

Example

명령>select key, updatetime(key) from expire_members.*;   opcode
결과> 0) key|updatetime(key)
1) myname1|2022-04-07 20:40:55
2) subject2|2022-04-07 20:40:55
3) myzset1|2022-04-07 20:40:55
4) myset1|2022-04-07 20:40:55
5) myset2|2022-04-07 20:40:55
6) myzset2|2022-04-07 20:40:55
명령>select key, type(key), encoding(key) from expire_members.*;   opcode
결과> 0) key|type(key)|encoding(key)
1) myname1|hash|ziplist
2) subject2|hash|ziplist
3) myzset1|zset|ziplist
4) myset1|set|hashtable
5) myset2|set|intset
6) myzset2|zset|ziplist
명령>select key, type(key), encoding(key) from expire_members.* order by type(key), encoding(key);
  opcode
결과> 0) key|type(key)|encoding(key)
1) myname1|hash|ziplist
2) subject2|hash|ziplist
3) myset1|set|hashtable
4) myset2|set|intset
5) myzset1|zset|ziplist
6) myzset2|zset|ziplist
명령>select key, memory(key) from expire_members.*;   opcode
결과> 0) key|memory(key)
1) myname1|122
2) subject2|118
3) myzset1|127
4) myset1|408
5) myset2|74
6) myzset2|325
명령>select key, memory(key) from expire_members.* order by memory(key);   opcode
결과> 0) key|memory(key)
1) myset2|74
2) subject2|118
3) myname1|122
4) myzset1|127
5) myzset2|325
6) myset1|408

TTLDATE()

  • TTLDATE(ttl): 만료 시각을 일시로 리턴합니다. 예) 2022-04-08 18:02:53
    ttl은 초로 표시되기 때문에 실제 멤버가 삭제될 일시를 환산해 보아야 하는 불편함이 있습니다. 그래서 ttldate() function을 제공합니다.

Example

명령>select key, value, ttl, ttldate(ttl) from expire_members.*;   opcode
결과> 0) key|value|ttl|ttldate(ttl)
1) myname1|name|81700|2022-04-08 19:22:35
2) myname1|age|81800|2022-04-08 19:24:15
3) subject2|name|81900|2022-04-08 19:25:55
4) subject2|kor|82000|2022-04-08 19:27:35
5) myzset1|value10|81400|2022-04-08 19:17:35
6) myzset1|value20|81500|2022-04-08 19:19:15
7) myset1|mem30|81100|2022-04-08 19:12:35
8) myset1|mem20|81200|2022-04-08 19:14:15
9) myset2|40|81300|2022-04-08 19:15:55
10) myzset2|mem40|81600|2022-04-08 19:20:55
명령>select key, value, ttl, ttldate(ttl) from expire_members.* where ttl > 0;   opcode
결과> 0) key|value|ttl|ttldate(ttl)
1) myname1|name|81700|2022-04-08 19:22:35
2) myname1|age|81800|2022-04-08 19:24:15
3) subject2|name|81900|2022-04-08 19:25:55
4) subject2|kor|82000|2022-04-08 19:27:35
5) myzset1|value10|81400|2022-04-08 19:17:35
6) myzset1|value20|81500|2022-04-08 19:19:15
7) myset1|mem30|81100|2022-04-08 19:12:35
8) myset1|mem20|81200|2022-04-08 19:14:15
9) myset2|40|81300|2022-04-08 19:15:55
10) myzset2|mem40|81600|2022-04-08 19:20:55

Expire_members 내부 구조

Expire member는 아래 그림과 같이 expire_keys와 expire_members에 저장됩니다.

  • Expire_keys는 Zset 구조를 사용하고, expire_members는 hash table과 zset을 사용합니다.
  • Expire_keys에는 expire time으로 정렬(sort)되어 있습니다.
  • Expire_members에는 key별로 zset에 저장합니다.

Expire member 설정

  • Expire key1 B 60
    Zset으로 key1을 만들고 B, 60을 저장합니다.
    key1을 hash table(expire_members)에 저장합니다.
    expire_keys에 key1, 60을 저정합니다.
  • Expire key1 A 40
    key1에 A, 40을 저장합니다.
    expire_keys의 key1을 40으로 업데이트합니다.
  • Expire key5 BB 30
    Zset으로 key5을 만들고 BB, 30을 저장합니다.
    key5을 hash table(expire_members)에 저장합니다.
    expire_keys에 key5, 30을 저정합니다.

정기적으로 설정된 expire member 삭제

  • 100ms(1초에 10번) 마다 check and delete
  • expire_keys에서 첫번째 키를 검사합니다.
    만료시각(expire time)을 지났는지 확인해서 지났으면 expire_members에서 해당 키와 멤버를 확인해서 삭제합니다.
  • expire_keys에서 key5를 30에서 100으로 수정합니다.
  • 아래 그림은 key5 BB, 30을 삭제하기 전, 후 모습니다.
  • 한 cycle 당 최대 20개까지 삭제합니다.
  • 삭제할 member가 많을 경우 해당 시각이 지나도 삭제되지 않을 수 있기 때문에 키를 읽을 때마다 check해서 삭제한다.

OPCODE


OPCODE는 SQL의 실행 계획(execution plan)입니다.

select count(*) from expire_members.*;

select count(key) from expire_members.*;

select key from expire_members.*;

select * from expire_members.*;

select * from expire_members.* order by key;

select * from expire_members.* order by key desc;

select * from expire_members.* order by key, value;

select * from expire_members.* order by value;

select * from expire_members.* order by ttl;

select * from expire_members.* limit 5;

select * from expire_members.* order by key limit 5;

select * from expire_members.* order by key limit 3,4;

select min(key), max(key) from expire_members.*;

select key, upper(key), length(key) from expire_members.*;

select * from expire_members.* where key <= 'myset1';

select * from expire_members.* where key > 'myset1';

select * from expire_members.* where key = 'myset1';

select * from expire_members.* where key != 'myset1';

select * from expire_members.* where value = 'name';

select * from expire_members.* where value > 'name';

select * from expire_members.* where value < 'name';

select * from expire_members.* where ttl < 100;

select * from expire_members.* where ttl > 100;

select * from expire_members.* where key between 'myset1' and 'myset2';

select * from expire_members.* where key not between 'myset1' and 'myset2';

select * from expire_members.* where key glob 'myset*';

select * from expire_members.* where key like 'myset%';

select * from expire_members.* where value glob 'name*';

select * from expire_members.* where value not glob 'name*';

select * from expire_members.* where key in ('myset1','myset2');

select * from expire_members.* where key not in ('myset1','myset2');

select left(key,5), count(*) from expire_members.* group by left(key,5);

select left(key,5), min(key), max(key) from expire_members.* group by left(key,5);

select key, updatetime(key) from expire_members.*;

select key, type(key), encoding(key) from expire_members.*;

select key, type(key), encoding(key) from expire_members.* order by type(key), encoding(key);

select key, memory(key) from expire_members.*;

select key, memory(key) from expire_members.* order by memory(key);

select key, value, ttl, ttldate(ttl) from expire_members.*;

select key, value, ttl, ttldate(ttl) from expire_members.* where ttl > 0;


<< Select Expires Select Expire Members Select Expire Keys >>

Email 답글이 올라오면 이메일로 알려드리겠습니다.