레디스(Redis)란?
Remote에 위치한 프로세스로 존재하는 In-Memory 기반의 고성능 키-값 저장소면서
문자열, 리스트, 해시, 셋, 정렬된 셋 형식의 데이터를 지원하는 NoSQL.
A. Redis 사용(캐시데이터로 활용)
일반적으로 웹 서버는 클라이언트 요청을 받아서 데이터를 제공하는 상황.
String 자료구조 사용
데이터가 존재하는지 Cache를 먼저 확인.
Cache에 데이터가 존재하면 해당 데이터를 제공.
Cache에 데이터가 존재하지 않으면 DB에서 읽은 뒤 Cache 저장 후 제공.
String 명령어
SET: SET, SETNX, SETEX, SETPEX, MSET, MSETNX, APPEND, SETRANGE
GET: GET, MGET, GETRANGE, STRLEN
INCR: INCR, DECR, INCRBY, DECRBY, INCRBYFLOAT
Enterprise: SETS, DELS, APPENDS (subquery)
1. SET
데이터를 저장, key가 이미 있으면 덮어쓴다.
set 'key' '<T>Value'
2. SETNX
지정한 key가 없을 경우에만 데이터를 저장
setnx 'key' '<T>Value'
3. SETEX
지정한 시간(초) 이후에 데이터 자동 삭제
setex 'key' 'time' '<T>Value'
4. GET
데이터를 조회
get 'key'
기본 명령어
Key 확인, 조회: EXISTS, KEYS, SCAN, SORT
Key 이름 변경: RENAME, RENAMENX
Key 삭제: UNLINK, RM
Key 자동 소멸 관련: EXPIRE, EXPIREAT, TTL, PEXPIRE, EXPIREAT, PTTL, PERSIST
정보 확인: TYPE, OBJECT
샘플링: RANDOMKEY
Data 이동: MOVE, DUMP, RESTORE, MIGRATE
1. EXISTS
Key가 존재하는지 확인
exists 'key' 1:있음 0:없음
C# 소스 샘플(캐시데이터)
/// <summary>
/// 없으면 Add 있으면 Get
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="timeSpan"></param>
/// <param name="func"></param>
/// <returns></returns>
public async Task<T> GetOrCreateAsync<T>(string key, TimeSpan timeSpan, Func<T> func)
{
T ret = default;
// 존재하면 return
if (await iRedisDatabase.ExistsAsync(key))
{
ret = await iRedisDatabase.GetAsync<T>(key);
}
// 없으면 함수 실행
else
{
ret = func();
await iRedisDatabase.AddAsync(key, ret, timeSpan);
}
// 혹시라도 아무데이터가 없으면 다시 재호출
if (ret is null)
{
ret = func();
await iRedisDatabase.AddAsync(key, ret, timeSpan);
}
return ret;
}
B. Redis 사용(랭킹데이터로 활용)
랭킹시스템을 구축해야 하는 상황.
ZSet(Sorted Set) 자료구조 사용
key에 score와 value 구성.
기본적으로 score로 order 진행.
같은 score일 경우 value로 order 진행.
이러한 특성을 이용하여 랭킹 시스템 구현.
ZSet(Sorted Set) 명령어
SET: ZADD
GET: ZRANGE, ZRANGEBYSCORE, ZRANGEBYLEX, ZREVRANGE, ZREVRANGEBYSCORE, ZREVRANGEBYLEX, ZRANK, ZREVRANK, ZSCORE, ZCARD, ZCOUNT, ZLEXCOUNT, ZSCAN
POP: ZPOPMIN, ZPOPMAX
REM: ZREM, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREMRANGEBYLEX
INCR: ZINCRBY
집합연산: ZUNIONSTORE, ZINTERSTORE
Enterprise: ZISMEMBER, ZLS, ZRM, SLEN, SADDS (subquery)
1. ZADD
집합에 score와 member를 추가
zadd 'key' 'score' 'value'
score는 반드시 숫자.
// redis-cli
zadd rank 300 "A" 200 "B" 250 "C"
// .net core C#
result = await iDatabase.SortedSetAddAsync(`key`, `value`, `score_va`);
2. ZRANGE
index로 범위를 지정해서 조회
'zrange 'key' 'start' 'stop'
start, stop (index 검색)
start: 0, stop : -1 (전체 검색)
// redis-cli
// index 0 ~ 3
zrange rank 0 3
// 전체
zrange rank 0 -1
// .net core C#
var results = await iDatabase.SortedSetRangeByRankWithScoresAsync(`key`, `start`, `stop`, isDesc ? Order.Descending : Order.Ascending);
C# 소스 샘플(랭킹)
for (var i = 0; i < ranks.Count; i++)
{
var rank = ranks[i];
await iDatabase.SortedSetAddAsync(key, rank.member_id, rank.score);
await iDatabase.HashSetAsync(rank.member_id.ToString(), new HashEntry[]
{
new HashEntry("name", rank.name)
});
}
/// <summary>
/// 랭크 데이터 가져오기
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="ent"></param>
/// <param name="isDesc"></param>
/// <returns></returns>
public async Task<JArray> RankRange(string key, int start, int ent, bool isDesc)
{
JArray jarray = new JArray();
try
{
List<RankResponseModel> data = new List<RankResponseModel>();
// 해당하는 키들이 있는지 확인
var results = await iDatabase.SortedSetRangeByRankWithScoresAsync(key, start, ent, isDesc ? Order.Descending : Order.Ascending);
UInt16 startRank = (isDesc ? start + 1 : (results.Count() / 2 - start)).ToString().ToUShortInt();
UInt16 rank_no = startRank;
UInt16 before_score = 0;
UInt16 increaseFactor = (isDesc ? 1 : -1).ToString().ToUShortInt();
var items = results.ToList();
for (var i = 0; i < items.Count; i++)
{
var member_info = await GetMemberInfo(items[i].Element);
data.Add(
new RankResponseModel
{
key = key,
member_id = items[i].Element.ToString(),
score = items[i].Score.ToString().ToUShortInt(),
name = member_info[0].Value.ToString(),
rank_no = rank_no,
}); ;
startRank += increaseFactor;
before_score = items[i].Score.ToString().ToUShortInt();
if (!before_score.Equals(items[i].Score.ToString().ToUShortInt())) // 같은 점수가 아닐 경우
{
rank_no = startRank;
}
}
jarray = JArray.FromObject(data);
}
catch
{
throw;
}
return jarray;
}
C. Windows redis-cli 설치
1. redis install
https://github.com/MicrosoftArchive/redis
2. redis 접속 및 연결확인
// 경로 이동
C:\Program Files\Redis
redis-cli.exe -h `redis-ip` -p `port` -a `password`
// 연결 확인
ping -> pong
// .net core redis 연결
string redisConnection = $"{ip}:{port},password={password}";
services.AddSignalR().AddStackExchangeRedis(redisConnection);
참고자료 : http://redisgate.kr/redis/command/zsets.php
'DataBase > Redis' 카테고리의 다른 글
[Redis/AWS] redis 외부 접속 허용 설정 (0) | 2023.02.10 |
---|---|
[Redis/AWS] 리눅스2 Redis 설치 하기 (0) | 2023.02.10 |