SSR

  • Server Side Rendering
  • 요청시마다 새로 고침이 일어나며 서버에 새로운 페이지에 대한 요청을 하는 방식
  • 서버에서 사용자에게 보여줄 페이지를 모두 구성하여 페이지를 보여주는 방식

CRS & SPA

  • Client Side Rendering
  • SPA는 최초 한번 페이지 전체를 로딩한 후 부터 데이터만 변경해서 사용 할 수 있는 웹 애플리케이션
  • SEO 취약함

SEO

  • Search Engine Optimization
  • SEO는 웹 사이트나 웹 페이지가 검색 엔진에서 노출 되기 위해 사용 되는 전략
  • 검색엔진은 웹 페이지의 콘텐츠를 파악하고 순위를 매겨 제공
  • SSR을 통해 서버에서 렌더링 된 콘텐츠는 SEO에 유리하며 CSR에서는 추가적인 작업이 필요하다

CORS (Cross-origin resource sharing)란?

한 출처의 리소스 (Html, Css, JavaScript, 이미지) 를 다른 출처에서 요청하고 응답을 받는것을 허용하는 보안 정책.
웹 브라우저는 기본적으로 다른 출처의 리소스를 요청하는 것을 차단한다. 이는 보안상의 이유로 다른 출처의 리소스가 악의적인 코드를 포함 할 수 있기 때문입니다.
해당 이유로 서버가 허락한다면 브라우저에서는 요청을 허락하고, 동의하지 않는 다면 브라우저에서 거절합니다. 이러한 메커니즘을 HTTP-Header 를 이용해서 가능한데, 이를 CORS 라고 부릅니다.

Cross Origin

  • Protocol - http/https
  • Domain - aaa.bbb.ccc.ddd / aaa.bbb.ccc.eee
  • Port - 8080 / 80

CORS 헤더 종류

  • Origin: 요청을 보낸 출처를 나타냅니다.
  • Access-Control-Allow-Origin: 응답을 받을 수 있는 출처를 나타냅니다.
  • Access-Control-Allow-Methods: 허용되는 요청 메서드를 나타냅니다.
  • Access-Control-Allow-Headers: 허용되는 요청 헤더를 나타냅니다.
  • Access-Control-Expose-Headers: 응답에서 노출할 수 있는 헤더를 나타냅니다.

** 개인적인 학습내용으로 정확하지 않은 부분들이 있을 수 있습니다.

Redis란?

  • Redis는 Key-Value 기반의 인메모리 데이터베이스입니다.
  • 주요 특징
    • Key-Value 기반
    • 인메모리
    • 고성능
    • 다양한 데이터 타입 지원
      • String, Sets, Sorted Set, Lists ...
    • 싱글 스레드

Redis 용도 예시

  • 캐싱
  • 세션 관리
  • 메시지 브로커
  • 게시물 랭킹
  • 게임 점수 관리

Redis 명령어

# 데이터 생성
SET key value
# 데이터 조회
GET key
# 데이터 수정
SET key value
# 관리
FLUSHDB # 데이터베이스 초기화

Redis를 이용한 사용자 로그인 여부 확인

  • 사용자 토큰 인증
    • 사용자의 token을 다음과 같은 형태로 저장한다.
    • key : users:token:<tokenValue> value : 토큰 관련 정보
    • 사용자가 로그인 하면 다음과 같이 토큰 정보를 생성합니다.
    • redisTemplate.opsForHash().put("users:token", tokenValue, tokenInfo);
    • 사용자가 로그인 여부를 확인
    • TokenInfo tokenInfo = redisTemplate.opsForHash().get("users:token", tokenValue); if(tokenInfo == null) return null; // 이외 토큰 유효성 판별 ...

Redis 캐싱 전략

  • Cache Aside 패턴
    • Flow
      • Cache Store에 검색하는 데이터가 있는지 확인
      • Cache Store에 없을 경우 Data Store에 데이터 조회
      • Data Store에 조회 해온 데이터를 Cache Store 에 업데이트
    • 읽기 및 반복적 호출 적합
    • 장애 대비
      • Redis가 다운 되더라도 DB에서 데이터를 가져 올 수 있어 서비스 자체는 문제가 없음
      • 단 레디스가 다운된 순간, 순간적으로 DB로 몰려서 DB 부하 가능성
    • 정합성 문제
      • Cache Store와 Data Stroe가 가지고 있는 데이터가 서로 다름
      • 캐시 만료 시간 설정: 캐시의 만료 시간을 설정하여 캐시된 데이터가 오래되면 데이터베이스에서 데이터를 다시 읽도록 합니다.
      • 캐시 무효화: 캐시된 데이터가 변경되면 데이터베이스에서 데이터를 다시 읽어 캐시를 무효화합니다.
      • 데이터베이스 트랜잭션 사용: 데이터베이스에서 데이터를 변경하는 트랜잭션을 사용하면 캐시된 데이터도 자동으로 업데이트됩니다.
  • Read Through 패턴
    • Flow
      • Cache Store에 검색하는 데이터가 있는지 확인
      • Cache Store에 없을 경우 Data Store에 데이터 조회
      • Data Store에 직접 Cache Store 에 업데이트
    • Read Through 방식은 Cache Aside 방식과 비슷하지만 Cache Store 에 저장하는 주체가 Server 또는 Data Store 에서 차이점 존재 Cache Aside 방식은 Data Store 로부터 서버가 쿼리 결과를 얻고나서 캐시에 저장
    • Read Through 패턴은 초기 데이터는 cache miss 가 항상 발생한다는 단점을 커버할 수 있도록 애플리케이션 측면에서 캐시 대상을 판단하여 Data Store 저장 (Commit) 시 Cache Store 에 쿼리를 동일하게 자동 수행하도록 설정
    • 정합성 문제
      • Cache Store와 Data Stroe가 가지고 있는 데이터가 서로 다름
      • 캐시 만료 시간 설정: 캐시의 만료 시간을 설정하여 캐시된 데이터가 오래되면 데이터베이스에서 데이터를 다시 읽도록 합니다.
      • 캐시 무효화: 캐시된 데이터가 변경되면 데이터베이스에서 데이터를 다시 읽어 캐시를 무효화합니다.
      • 데이터베이스 트랜잭션 사용: 데이터베이스에서 데이터를 변경하는 트랜잭션을 사용하면 캐시된 데이터도 자동으로 업데이트됩니다.
  • Write Back 패턴
    • Flow
      • 모든 데이터를 Cache Store 에 저장
      • 일정 시간 후 Data Store에 저장
    • 큐 역할, 데이터 베이스에 대한 전체 쓰기를 줄 일 수 있어 해당 비용을 감소
    • 정합성 확보
    • 캐시 장애시 데이터 유실, 불필요한 리소스 저장
    • Write Back 패턴의 경우 Cache Store 가 데이터 저장소 역할을 하면서 동시에 Data Store 에 Write 부하를 줄이기 위한 Queue 역할을 겸하게 됨
      • 이로 인해 Database의 부하를 경감시킬 수 있다는 장점 있음
      • 대체로 쓰기 작업이 많은 경우 적용을 권고
  • Write Through 패턴
    • Flow
      • 모든 데이터를 Cache Store에 저장
      • 그리고 바로 Cache Stroe에서 DB로 저장
    • 항상 동기화 되어 있어 데이터베이스에 작성할 때마다 캐시에 데이터를 추가
    • 캐시와 백업 저장소에 업데이트를 같이 하여 데이터 일관성을 유지할 수 있어서 안정적
    • 데이터 유실이 발생하면 안 되는 상황에 적합
    • 단 속도가 느린 기억장치에 데이터를 기록할 때 CPU가 대기하는 시간이 필요하기 때문에 성능이 떨어짐
    • Wrtie Through 패턴은 Cache Store 에도 반영하고 Data Store에도 동시에 반영하는 방식
    • Write Back은 일정 시간을 두고 나중에 한꺼번에 저장
    • 그래서 항상 동기화가 되어 있어 항상 최신정보를 가지고 있다는 장점이 있음
    • 하지만 결국 저장할 때마다 2단계 과정을 거쳐치기 때문에 상대적으로 느리며 무조건 일단 Cache Store 에 저장하기 때문에 캐시에 넣은 데이터를 저장만 하고 사용하지 않을 가능성이 있어서 리소스 낭비 가능성이 있음
    • 이 역시 이를 해결하기 위해 TTL을 꼭 사용하여 사용되지 않는 데이터를 반드시 삭제해야 함

'Study > BE' 카테고리의 다른 글

Docker / Docker-Compse  (2170) 2023.08.28

원티드 프리온보딩 인턴십 - 백엔드 6차 교육 내용 정리

Hash Table

Hash Table

  • Key와 Value를 쌍으로 가지고 있는 자료 구조
  • 검색/삽입/삭제 작업에 효율적인 자료구조
  • 평균 O(1)의 시작 복잡도
  • 저장 순서 보장하지 않음

동작원리

  • Hash Table에 데이터를 추가하거나 조회 할 때, Hash Function을 사용
  • Hash Function
    • Hash Table에서 해시 함수는 Key 값을 입력 받아 Hash Table 상의 주소 값을 반환한다.
    • 입력 키를 해시 테이블 전체에 고루 분산 시켜 저장 할 수 있는 함수가 좋은 해시 함수이다.
    • 일반적으로 Hash Table의 크기는 2의 멱수에 가깝지 않은 소수를 선택하면, 균등성이 높아질 가능성이 많다.

사용 사례

  • 데이터에 빠른 검색/삽입/삭제 작업 수행이 필요한 상황
  • 키-값 쌍의 데이터를 관리해야 되는 상황
  • 중복 데이터 검사 : 해시 테이블은 키의 유일성을 보장 하기 때문에 데이터 중복 검사 및 제거 가능

HastTable 장/단점

  • 장점
    • 빠른 테이터 접근 속도
    • 키-값 쌍 저장
    • 중복 방지
  • 단점
    • 2개 이상의 키가 동일한 해시 값을 가질 경우 충돌발생. 충돌을 관리하는 방법이 여러가지 있지만, 충돌이 빈번하게 발생할 경우 성능 저하를 가져올 수 있음.

Hash Table에서 충돌 처리

Hash Collision

  • 해시 테이블 내에 어떤 키가 이미 자리 잡고 있는 상태에서 다른 키가 삽입을 시도 하는 경우에, 해시 함수가 서로 다른 입력에 대해 동일한 값을 반환하는 경우 Hash Collision이 발생한다.

Hash Collision이 발생하는 이유

  • 해시 함수는 임의의 크기의 입력을 고정 크기의 해시 값으로 변환한다.
  • 이때 해시 함수의 출력 공간이 입력 공간보다 작을 수 있기 때문에 해시 충돌이 발생 할 수 있다.

해결방법 - Separate Chaning

  • 같은 주소로 해싱 되어 충돌이 일어나는 Entry를 연결 리스트로 연결해서 저장하는 방식으로 해시 충돌을 피할 수 있다.
  • Chaning 방법에서 임의의 키에 해당하는 엔트리를 저장 할 때는 해시 값이 가리키는 bucket의 연결 리스트에 삽입한다.
  • 이 때 내가 사용 하고 있는 연결 리스트의 구현체에 따라서 맨 앞 혹은 맨 끝에 삽입하는것이 좋다.

해결방법 - Open Addressing

  • Separate Chaining 방식과 달리 추가 공간을 사용하지 않고 충돌을 해결하는 방법
  • 해시 충돌이 일어나도 정해진 Hash Table 공간에 다른위치에 저장한다. 이러한 특징 때문에 데이터의 key의 해시 결과 반환되는 bucket의 인덱스와 일치하는 주소에 저장된다는 보장은 없다.
  • 개방 주소법에서 엔트리를 해시 테이블에 삽입하는 과정
    • 해시 -> 해시 충돌 발생 x -> 해시 결과 반환된 bucket 위치에 저장
    • 해시 -> 해시 충돌 발생 o -> 정해진 규칙에 의해 다음 자리를 찾아 저장
  • 충돌이 일어 났을 때, 다음 주소를 정하는 방법
    • 선형 탐색
    • 이차원 탐색
    • 더블 해싱

'Study > 자료구조' 카테고리의 다른 글

자료구조 - Stack & Queue  (1290) 2023.09.26
자료구조 - Array & LinkedList  (1290) 2023.09.25

+ Recent posts