제가 공부한 내용을 정리하는 블로그입니다.
아직 많이 부족하고 배울게 너무나도 많습니다. 틀린내용이 있으면 언제나 가감없이 말씀해주시면 감사하겠습니다😁

Cache 적용 후 Select Query 비교


DML에 따른 캐시 성능 / 12시경 캐시 적용

  • 캐시는 얼마나 Hit 되는지가 중요한 요소
  • SELECT는 캐시 Hit 이후 평균 시간이 급격하게 감소
  • UPDATE는 캐시 Hit가 있을 수 없으므로 캐시 적용 전과 비슷.

CPU 사용량

  • 서비스에 따라 다르지만 SELECT가 DB에 도착하지 않으므로(캐시를 사용하므로) CPU 사용량이 줄어듦.
    • DB에 레플리카를 만들어서 SELECT
    • WRITE에는 다른 트릭을 적용해서 CPU 사용량을 줄일 수 있음.
💡 Performance Tool
gatling, locust, 엥그라이드, jmeter가 존재. 최근에는 gatling, locust가 많이 사용하는 추세

분산 캐시


  • 데이터가 많다면, 하나의 Cache Server가 아니라 여러 캐시 서버를 구성할 수 있음.
  • ex) Redis With Range, Redis with PreShard, Redis with Consistent Hashing

상황

데이터를 나누는 기준이 중요

  • 서버는 계속 늘어나기에 데이터를 나누는 기준이 필요
    • 데이터가 재분배가 계속되면 안좋음.

  • 전체를 찾는건 서버에 부하

 

1. 모듈러(%2, %3 ... %N)

  • 서버 추가시 데이터 재분배가 일어나야함.

2. Range로 구분하는 방법

  • 초창기에 들어오는 유저는 활동량이 많고 이벤트시 들어오는 유저는 활동량이 없음.
  • 활동적인 유저는 서버 1에만, 이벤트 시 들어오는 유저는 서버 2에만 들어가기에 서비스 분배에 부적합
  • 서버의 부하도가 다름.

 

3. Preshard

  • hash값으로 균등하게

 

 

 

Session Store


Session Store로 저장하는 법

  • Session Store(로그인 토큰 같은 정보 저장)로 Redis를 많이 사용
  • Session을 개별 서버나, 클러스터링이 아닌, 외부 스토리지(Redis)에 저장.
  • Session Store가 죽으면 정보가 사라짐.

Distribution Lock


  • 분산 락으로 동작
    • Optimistic Lock으로 동작
    • Key가 존재하면 대기하는 형태
      • 바로 실패로 구성할지, Spinlock 형태로 동작할 지(Redisson 구현체) 등 구현에 따라 다름.
  • setnx
    • 키(데이터)가 없을때만 쓸 수 있음.
    • 키가 있으면 실패
    • 락을 얻음.
    • 락을 풀기 위해 key를 지우면 됨.
  • t_string.c/setGenericCommand
    • found가 false일 때만 사용할 수 있음
void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, int unit, robj *ok_reply, robj *abort_reply) {
    long long milliseconds = 0; /* initialized to avoid any harmness warning */
    int found = 0;
    int setkey_flags = 0;

    if (expire && getExpireMillisecondsOrReply(c, expire, flags, unit, &milliseconds) != C_OK) {
        return;
    }

    if (flags & OBJ_SET_GET) {
        if (getGenericCommand(c) == C_ERR) return;
    }

    found = (lookupKeyWrite(c->db,key) != NULL);

    if ((flags & OBJ_SET_NX && found) ||
        (flags & OBJ_SET_XX && !found))
    {
        if (!(flags & OBJ_SET_GET)) {
            addReply(c, abort_reply ? abort_reply : shared.null[c->resp]);
        }
        return;
    }
    // ...
}
127.0.0.1:6379> setnx ossca 2024
(integer) 1
127.0.0.1:6379> setnx ossca 123
(integer) 0
127.0.0.1:6379> get ossca
"2024"
127.0.0.1:6379> set ossca 4/26
OK
127.0.0.1:6379> get ossca
"4/26"
  • 처음에는 key가 ossca인 데이터가 없으므로 성공적으로 만들어졌기에 1이 반환됨.
  • 두번째는 ossca라는 값이 있으므로 실패를 뜻하는 0이 반환됨.
  • get을 통해 2024 값을 잘 읽어오고
  • set은 lock과 관계 없이 설정이 된다.
  • 프로세스가 지워지면 ttl을 5초 걸어두어 그 전에 접속하면 된다. 그 후에는 key가 사라진다.

Leaderboard


  • Sorted Set(zset)이 score를 저장할 수 있기에 redis로 활용함.
    • score, key 순
    • zrange zkey1 0 -1 하면 오름차순으로 랭킹이 나옴
    • src/t_zset.c
      • double 형태로 인자를 받음
      • zslCreateNode()
      • 근사값이므로 값이 오차가 발생할 수 있음
127.0.0.1:6379> zadd zkey1 100 one
(integer) 1
127.0.0.1:6379> zadd zkey1 1000 two
(integer) 1
127.0.0.1:6379> zrange zkey1 0 -1
1) "one"
2) "two"
127.0.0.1:6379> zadd zkey1 500 three
(integer) 1
127.0.0.1:6379> zrange zkey1 0 -1
1) "one"
2) "three"
3) "two"
127.0.0.1:6379> zrange zkey1 0 -1 withscores
1) "one"
2) "100"
3) "three"
4) "500"
5) "two"
6) "1000"

 

+ Recent posts