select_expire_members
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 >> |
---|