Redis
레디스는 오픈소스 key-value 기반의 인-메모리인-메모리는 데이터를 하드디스크가 아닌 RAM에 저장하고 처리하는 기술 데이터 저장소이다.
별도의 쿼리를 날리지 않기 때문에 일반 DB보다 빠르다.
Redis 특징
1. 성능
모든 Redis 데이터는 RAM에 저장되어 대기 시간을 낮추고 처리량을 높인다.
평균적으로 읽기 및 쓰기 속도가 1ms로 디스크 기반 데이터베이스보다 빠르다.
2. 유연한 데이터 구조
Redis의 데이터 타입은 String, Lists, Hashs, Sets, Sorted Set, Bitmap, Streams, Geospatial indexes 등 다양한 데이터 구조를 지원한다.
따라서, 애플리케이션의 요구 사항에 알맞은 다양한 데이터 타입을 활용할 수 있다.
3. 개발 용이성
Redis는 쿼리문이 필요로 하지 않으며, 단순한 명령 구조로 데이터의 저장, 조회 등이 가능하다.
또한, Java, Python, C, C++, C#, JS, PHP, Node.js, Ruby 등을 비롯한 다수의 언어를 지원한다.
단순한 명령들
keys * # 모든 키 검색
keys A* # A로 시작하는 키 검색
exits <key> # 키가 존재 하는지
rename <key> # 키 이름 변경
SET key1 "Hello" # key1라는 키에 Hello라는 값 넣기
UNLINK key1 # key1 삭제
flushall # 모든 키 삭제
save # rdb 파일로 저장(포그라운드)
4. 영속성
Redis는 영속성을 보장하기 위해 데이터를 디스크로 저장할 수 있다.
중요한 데이터일 경우, 백업을 위해 디스크로 저장하고 추후에 치명적인 문제가 발생했을 경우, 복구 시킬 수 있다.
5. 싱글 스레드 방식
Redis는 싱글 스레드 방식을 사용하여 한 번에 하나의 명령어만 처리한다.
따라서 연산을 원자적으로 처리하여 Race Condition이 거의 발생하지 않는다.Race Condition은 2개 이상의 프로세스나 스레드가 공유 메모리 자원에 동시에 접근하여 읽거나 쓸 때, 작업의 실행 순서나 타이밍에 따라 결과 달라지는 비결정적인 상태이다. 이를 방지하기 위해 세마포어 등의 동기화 메커니즘을 사용한다.
하지만, 멀티 스레드를 지원하지 않기 때문에 시간 복잡도가 O(n)인 명령어의 사용은 주의할 필요가 있다.
시간 복잡도 O(n)의 명령어
- 키 갯수가 많을 경우의
keys *. - 데이터를 삭제하는 스레드
- SADD
- Smembers
- Hgerall
비동기와 동기 차이점
비동기
- 특정 코드가 끝날때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것으로 Web API, Ajax, setTimeOut이 있다.
- 요청을 보낸 후 응답의 수락 여부와는 상관없이 다음 태스크가 동작하는 방식으로, a 태스크가 실행되는 시간 동안 b 태스크를 할 수 있으므로 자원을 효율적으로 사용할 수 있다. 쉽게 설명하면, 한번에 여러 일들을 동시에 병렬로 실행된다.
동기
- 직렬적으로 태스크를 수행하는 방식이다.
- 즉, 요청을 보낸 후 응답을 받아야지만 다음 동작이 이루어지는 방식으로, 어떠한 태스크를 처리할 동안 나머지 태스크는 대기 상태이다.
비동기 처리
비동기 요청시 응답 후 처리할 콜백할수를 함께 알려준다. 따라서 해당 태스크가 완료되면, 콜백함수가 호출된다.
이러한 콜백 함수가 중첩이 되면, 콜백 헬콜백 헬은 JavaScript를 이용한 비동기 프로그래밍시 발생하는 문제로서, 함수의 매개 변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상이 발생된다.
이런 콜백 헬을 보완하기 위해, 두 가지 방법이 있다.
- 프로미스는 ES6에 도입되었고 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 시점을 명확하게 표현할 수 있다.
- async/await는 ES8에 도입되었고 비동기 코드를 마치 동기 코드처럼 작성할 수 있다.
프로미스
앞서, 소개한 프로미스는 비동기 연산의 최종 결과를 나타내는 객체로서, 성공 또는 실패 시점에 실행될 콜백 함수들을 연결할 수 있게 한다.
콜백 중첩 대신 then/catch 체인을 사용해 가독성을 높여준다.
프로미스의 상태
- Pending: 초기 상태, 이행되거나 거부되는 않은 상태
- fulfilled: 연산이 성공적으로 완료된 상태
- rejected: 연산이 실패한 상태
즉, Pending (대기) -> fulfilled or rejected (성공 또는 실패)
async/await
자바스크립트의 비동기 처리 패턴 중 하나이며, 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하는 방식이다.
이 구문은 프로미스를 더 편리하게 사용할 수 있도록 도와주는 syntactic sugar(문법 설탕)이다.
- async 함수는 항상 프로미스를 반환하여, 일반 값을 반환하더라도 이 값은 프로미스로 감싸진다.
- await 키워드는 오직 async 함수안에서만 동작한다. await는 프로미스가 처리될때까지 해당 함수만 실행을 일시 중단시키고, 처리가 완료되면 해당 프로미스의 결과값이 await 표현식의 값이 된다.
이 구문을 사용하면, 프로미스의 결과 값을 더 직관적이고 동기적인 방식으로 처리할 수 있다.
HTTP 메서드
클라이언트 - 서버 구조에서 요청과 응답이 이루어지는 방식으로, 서버가 수행해야 할 동작을 지정하여 요청을 보내는 방법이다.
HTTP 메서드 사용 이유
서버가 수행해야 할 동작(조회, 생성, 수정, 삭제)을 명확하게 정의하여 전달하기 위해 사용된다.
이는 데이터와 동작을 분리하여 REST API 설계의 일관성을 높이고, 서버가 요청의 의미를 정확하게 파악할 수 있도록 하여, 효율적으로 처리가 가능하도록 유도한다.
- 동작의 명확성 : 서버가 HTTP 메시지의 의도를 쉽게 파악하여 동작 수행
- REST API 표준 : 리소스와 행동을 분리하여 관리하므로, API의 구조가 직관적이고 예측 가능
- 멱등성 보장 : 여러 번 호출해도 결과가 같아 시스템을 안정적인 운영 가능
- 캐싱 및 성능 최적화 : GET 요청은 캐싱이 가능하여 불필요한 서버 요청을 줄이고 속도 향상
HTTP 메서드의 종류
- GET : 리소스 조회
- POST : 새로운 리소스 생성
- PUT : 리소스 전체 교체/수정
- PATCH : 리소스 일부 수정
- DELETE : 리소스 삭제
GET 메서드
리소스를 조회하는 메서드로, 멱등성이라는 개념을 가지고 있어, 여러 번 조회 요청을 하여도 리소스는 변하지 않는다.
GET 요청에서 서버에 데이터를 전달하는 경우, 쿼리스트링을 통해 전달한다.
단, 쿼리스트링은 클라이언트에게 전달하는 데이터 정보가 노출되므로, 유의해야 하며 최대 2048자 내외이다.
POST 메서드
주로 새로운 리소스를 생성하는데 사용한다. 생성을 성공할 경우, 201 HTTP 응답을 반환한다.
데이터를 메시지 바디에 쿼리 파라미터key-value 형식으로 전달하며, 메시지 길이 제한이 없다.
GET 방식은 쿼리스트링으로 노출되지만, POST는 노출되지 않아 보안상의 이점이 있다.
그렇다고 POST로 조회할 경우 멱등성을 가지고 있지 않아 여러번 수행할 경우 같은 결과값이 출력되는 것을 보장하지 않는다.
PUT 메서드
리로스를 덮어씌우는 개념으로, 클라이언트가 리소스를 식별할 수 있기 때문에, 구체적인 리소스 위치를 아는 상태에서 URI를 지정한다.
부분 수정이 불가능하며, 멱등성을 가진다.
PATCH 메서드
PUT과 같이 리소스를 수정하는 역할 하지만, 리소스를 부분 변경한다는 점에서 차이가 있다.
기존 데이터를 하나만 수정할 수 있어, A와 B가 있을 경우 B -> C로 변경한다면, A와 C로 수정된다.
멱등성을 가지고 있지 않는다.
DELETE
리소스를 제가하는 역할을 한다.
멱등성을 가진다.
XSS 와 CSRF
XSS (Cross-Site-Scripting 크로스 사이트 스크립트)
웹 사이트에서 의도치 않은 스크립트를 넣어서 실행시키는 기법이다.
웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 발생하며, 결과로 사용자는 의도치 않은 동작을 수행하거나 쿠키, 세션 등의 정보를 탈취당하게 된다.
공격 흐름
- 제 3자(침입자)는 사이트의 취약점을 찾는다.
- 취약점을 찾아 세션/쿠키를 탈취하는 스크립트를 사이트에 삽입한다.
- 사용자가 웹 사이트에 접근할 때마다 스크립트는 작동되어 사용자의 세션/쿠키를 탈취한다.
대응 방법
- 중요한 정보는 쿠키 대신 서버에 저장한다.
- 정보를 암호화한다.
- HTTPOnly 옵션(document.cookie를 이용해 쿠키에 직접 접근하는 것을 방지)을 설정한다.
- URI Encoding이나 문자열을 치환한다.
CSRF (Cross-Site Request Fogery 크로스 사이트 요청 변조)
사용자가 자신의 의지와는 무관하게 침입자가 의도한 행위를 서버에 요청하게 만드는 공격이다.
XSS는 사용자가 특정 사이트를 신뢰하기 때문에 발생하는 문제라면, CSRF는 특정 사이드가 사용자를 신뢰하기 때문에 발생하는 문제이다.
CSRF의 조건
- 사용자가 사이트에 로그인한 상태
- 사용자는 조작된 페이지에 접속.
공격 흐름
- 침입자는 서버로 넘거가는 전송에 대한 요청을 조작한다.
- 하이퍼링크에 전송 요청에 대한 스크립트를 삽입하고 사이트에 로그인할 사람들에게 전송한다.
- 사용자가 링크를 누르면, 의도치 않게 서버로 요청을 보내게 된다.
- 서버는 로그인된 사용자의 요청이기 때문에 정상적으로 인식하고 전송을 실행해 침입자에게 돈을 요구한다.
대응 방법
- 요청 헤더의 도메인과 일치하는지 Refferer 속성 검증 : 같은 도메인의 요청이 아닐 경우 차단
- CSRF 토큰 사용 : 핸덤한 UUID와 같은 임의의 난수를 세션에 저장해두고 해당 난수가 전달되지 않을 경우 요청 거부
- Security 토큰 사용 : 사용자 세션에 암호화된 값을 저장하고 사용자의 요청마다 해당 암호화된 값을 포함시켜 전송한 후 이후 서버에서 요청을 받을 때마다 세션에 저장된 토큰 값과 요청에 전달되는 토큰 값이 일치하는지 확인
- CAPTCHA : 컴퓨터와 인간을 구분하기 위한, 완전 자동화된 공개 튜링 테스트
XSS와 CSRF 비교
- XSS가 사용자가 특정 사이트를 신뢰하기 때문에 발생하는 문제라면, CSRF는 특정 사이트가 사용자를 신뢰하기 때문에 발생하는 문제이다.
- XSS는 클라이언트의 브라우저에서 발생하는 문제이고, CSRF는 서버에서 발생하는 문제이다.
- XSS는 사용자의 쿠키/세션를 탈취할 수 있고, CSRF는 서버로부터 권한을 탈취할 수 있다.
브라우저 렌더링
렌더링은 HTML, CSS, JS로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것이다.
파싱은 프로그래밍 언어의 문법에 맞게 작성된 텍스트 문서를 읽고 실행하기 위해 텍스트 문자의 문자열을 분해하고 구조를 생성하는 일련의 과정이다.
렌더링 과정
1. 불러오기
로더가 서버로부터 전달받은 리소스 스트림을 읽는 과정이다.
2. DOM, CSSOM 생성
웹 엔진의 HTML/XML 파서가 문서를 파싱해 DOM Tree를, CSS 파서가 CSSOM 트리를 생성한다.
3. 생성된 DOM과 CSSOM으로 렌더링 트리 생성
생성된 트리들에서 화면에 필요한 노드만 선택해 페이지를 렌더링하는데 사용하기 위한 렌더링 트리를 생성한다.
4. 레이아웃
렌더링 트리를 토대로 그려질 노드와 스타일, 크기를 계산한다.
렌더링 트리에서 위치, 크기등을 알 수 없기 때문에 객체들에게 위치 크기 등을 정해줘야 한다.
CSS는 선택자에 따라 적용되는 태그가 다르기 때문에 모든 CSS 스타일을 분석해 태그에 스타일 규칙이 적용되게 결정해준다.
5. 페인팅
렌더링 트리의 각 노드를 실제 픽셀로 변환하고 실제로 그리는 작업을 수행한다.자바 스크립트가 DOM,CSSOM 트리를 수정하는 경우를 리렌더링, 레이아웃을 다시 계산하는 것을 리플로우, 재결합된 렌더링 트리를 기반으로 다시 페인팅하는 것을 리페인트라고 한다.
렌더링 최적화
1. CSS, JS 최적화
웹 페이지의 디지인과 동작을 결정하는 역할이지만, 지나치게 복잡하거나, 파일 크기가 크면 렌더링 성능을 저하시키는 원인이 된다.
- CSS 코드를 압축하고 중복된 스타일 코드를 제거
- JS 코드를 압축하고, 불필요한 코드 제거
- JS 코드를 지연 로딩하거나 비동기 로딩을 이용하여 페이지 로딩 시간 최적화
2. 이미지 최적화
웹 페이지에서 사용되는 이미지를 최적화하여 불필요한 로딩 시간을 줄이는 것이 중요하다.
- 이미지 포맷을 최적화하여 파일 크기를 줄인다.(JPEG는 사진, PNG는 아이콘)
- 불필요한 이미지를 제거하거나, 여러 이미지를 하나의 이미지 파일로 통합한다.
- 지연 로딩 기술을 이용하여 페이지 스크롤링에 따라 이미지를 로딩한다.
3. 레이아웃 최적화
레이아웃은 브라우저에서 웹 페이지의 요소를 배치하는 과정으로, 렌더링 성능에 큰 영향을 미친다.
따라서, 레이아웃 최적화는 렌더링 성능을 향상시키는 중요한 방법이다.
- CSS FlexBox, Grid를 이용하여 요소를 배치한다.
- 요소의 크기와 위치를 계산할 때, 불필요한 계산을 줄이는 최적화 기술을 사용한다.(레이아웃 스래싱 방지, 하드웨어 가속, DOM 변경 최소화 등)
- 가장 효과적인 기술은 레이아웃을 변경하는 속성(width, top 등)의 사용을 줄이고, 애니메이션은 transform을 사용하여 DOM 읽기/쓰기를 분리하여 처리하는 것이다.
'Daily Dev Q&A 정리 템플릿' 카테고리의 다른 글
| 26.01.27 트랜잭션과 인덱스는 어떤 관계가 있을까? (0) | 2026.01.27 |
|---|---|
| 26.01.23 쿠키와 세션 중에 어떤것을 사용해야 할까? (0) | 2026.01.23 |
| 26.01.22 HTTP와 HTTPS의 차이점 (0) | 2026.01.22 |
| 26.01.21 GET, POST의 개념과 함께 데이터 흐름 알아보자. (0) | 2026.01.21 |
| 26.01.20 3-way-handshake (0) | 2026.01.20 |