소프트웨어 개발 13

안정 해시 설계에 대해 알아보자

대규모의 서비스는 하나의 서버가 아니라 다수의 서버를 통해 운영된다. (수평적 확장) 스케일 아웃된 서버의 효과적인 동작을 위해서는 서비스의 데이터들이 균등하게 분배되어야 한다. 간단한 방식으로는 해시 함수를 통한 처리가 있다. N개의 캐시 서버가 있다고 해보자. serverIndex = hash(key) % N과 같이 간단한 모듈러 연산을 통해 서버를 선정한다. 하지만 위 방식의 경우 서버의 추가, 삭제가 일어났을 때 문제가 발생한다. 키에 대한 해시 값은 변화하지 않지만 서버의 개수인 N의 값이 달라지므로 서버 인덱스 값이 달라지게 된다. 따라서 대부분의 캐시 클라이언트가 데이터가 없는 엉뚱한 서버로 접속하게 된다. (대규모의 캐시 미스 발생) 안정 해시는 이러한 문제를 효과적으로 해결해준다. 해시 ..

QR 코드를 통한 결제는 어떻게 동작할까?

QR 코드 스캔을 통한 결제는 어떻게 동작할까? 동작 방식을 순차적으로 알아보자. [Scan to pay process] The merchant generates QR code and displays The consumer scans and pays QR 코드 생성 생성 과정을 하나씩 살펴보자 계산원이 구매한 상품들을 확정하면 구매 데이터가 PSP(payment service provider)에 전달될 것이다. PSP에서는 주문 번호와 해당 주문 번호에 맞는 QR 코드 URL을 생성하여 응답해줄 것이다. 계산원은 응답 받은 QR 코드를 고객에게 보여준다. 고객 결제 디지털 지갑에서 QR 코드 스캔을 진행한다. 디지털 지갑 앱에서 PSP로 해당 QR 코드에 대한 결제가 완료되었음을 전달한다. PSP에서는 ..

DB에 패스워드는 어떻게 저장하고 관리할까?

데이터베이스에 민감 정보를 저장하고 관리하는 것은 중요한 일이다. 패스워드를 평문으로 저장하면 안된다. 평문일 경우 데이터베이스에 접근할 수 있는 누구든지 데이터를 확인할 수 있게 된다. 데이터베이스에 패스워드를 안전하게 저장하기 위해서는 어떻게 하면 될까? Open Web Application Security Project (OWASP)에서는 안전한 패스워드 저장에 대한 가이드라인을 제시하고 있다. Use a modern hashing algorithm Salt the password 해시 함수를 통해 단방향 암호화를 진행함으로써 복호화가 불가능하게 한다. OWASP 가이드 라인에 따르면 Salt는 랜덤하고 유니크한 문자열이다. Password에 Salt를 추가한 뒤 해시 함수를 통해 더 안전하게 암호..

카프카는 왜 빠를까?

카프카는 왜 빠를까? 카프카는 적은 시간에 많은 데이터를 처리할 수 있도록 최적화되어 있다. 어떤 시스템 디자인 덕분에 카프카가 대량의 데이터를 처리할 수 있는 걸까? 대표적인 2가지 특징을 알아보자. 1) Kafka’s reliance on sequential I/O 디스크의 데이터 접근 방식에는 2가지가 있다. Random Sequential Sequential의 경우 디스크에서 데이터를 읽을 때 바로 옆의 데이터로 순차적으로 읽기 때문에 Random 방식보다 빠르다. 카프카는 append-only log를 통해 Sequential 하게 데이터를 처리한다. 두 접근 방식의 성능을 간략히 비교하면 Random 방식은 100KB/s, Sequential 방식은 100MB/s으로 큰 차이가 난다. 이를 통..

[Redis] 레디스의 주요 명령어에 대해 간단히 알아보자

이번 글에서는 아래 내용에 대해 알아볼 것이다. 레디스의 유용한 명령어 Key와 관련된 주요 명령어 레디스 value의 데이터 타입과 주요 명령어 유용한 명령어 redis-cli monitor 레디스로 요청되는 모든 명령어들을 출력해 준다. 로컬 개발 환경에서 개발 작업을 할 때 의도대로 동작하는지 확인할 때 유용하다. slowlog get 명령 처리 과정에서 시간이 오래 걸린 결과들을 확인 기본적으로 처리 시간이 10ms 이상인 결과들을 기록 format ID 실행시간 수행시간 (microsecond) 명령 client ip/port client name info 버전, 시스템 정보, 클라이언트 연결 개수, 메모리 정보 등 다양한 정보 확인 SELECT 물리적인 데이터베이스 설정 (기본적으로 0번 데이..

[Redis] 레디스의 특징에 대해 간단히 알아보자

Redis는 대표적인 인메모리 데이터베이스이다. Remote Dictionary Server에서 Redis라는 이름이 되었다고 한다. Redis의 특징에 대해 간단히 알아보자. Persist on Disk 레디스의 대표 기능 중 하나로 메모리에 있는 데이터를 디스크에 저장하는 기능을 제공한다. RDB(Snapshot) → 시간 단위로 백업 AOF(Append Only File) → 데이터 쓰기 작업 목록을 적재 기본 설정은 RDB만 활성화 단순 캐시용도면 두가지 기능 모두 끄고 사용하는 경우도 많다. 성능의 트레이드 오프를 고려하여 사용하자. Data types 레디스는 키로 다양한 데이터 타입을 저장할 수 있다. Strings Lists Sets Hashes Sorted sets Single Threa..

웹 브라우저에 URL을 입력하면 어떤 일이 일어날까?

먼저 URL이란, Universe Resource Locator 를 의미하며 4가지 파트로 구성된다. ex) http://example.com/product/electric/phone Scheme Domain Path Resource Scheme http: 브라우저가 http 프로토콜을 통해 서버와 연결한다는 것을 알려준다. Domain example.com 사이트의 도메인명 Path product/electric Resource phone 브라우저는 어떤 과정을 통해 example.com의 서버에 도착할 수 있을까? DNS(Domain Name System) lookup을 통해 도메인의 ip 주소를 찾아낸다. 브라우저는 해당 과정을 빠르게 하기 위해 접속한 도메인에 대한 ip 주소를 잠시동안 캐싱해둔..

'DB 커넥션풀'에 대해 알아보자

백엔드 서버와 디비 서버가 있다. 백엔드 서버가 api 요청을 받아 처리하다가 디비에 접근하여 데이터를 조회할 일이 생기면 디비 서버로 쿼리를 요청한다. 디비 서버는 쿼리 요청에 맞게 데이터를 찾아 백엔드 서버로 응답해 줄 것이다. 백엔드 서버는 쿼리 응답을 받고 추가적인 작업을 맞춘 뒤 api 응답을 진행할 것이다. 위 상황을 조금만 더 자세히 들여다보자. 백엔드 서버와 디비 서버는 각각 서로 다른 컴퓨터에서 동작을 하기 때문에 쿼리를 요청하고 응답받는 과정에서 네트워크 통신이 일어났을 것이다. 일반적으로 백엔드 서버와 디비 서버 간의 네트워크 통신은 TCP 기반으로 동작한다. TCP 기반의 통신은 높은 송수신 신뢰성이라는 강점을 가진다. TCP 기반의 통신은 연결 지향적인 특징을 가지고 있으므로 본격..

'스레드풀'에 대해 알아보자

thread per request api 서버로 들어온 요청을 처리하는 여러 방식이 있다. 'thread per request'도 그중 하나이다. 이름 그대로 요청 하나마다 하나의 스레드가 담당하여 처리할 수 있도록 하는 것이다. 이때 서버에 들어오는 요청마다 스레드를 새롭게 만들어서 처리하고 요청에 대한 처리를 마친 스레드는 사라지는 식으로 동작한다면 어떻게 될까? 스레드 생성에는 오랜 시간이 소요되기 때문에 요청에 대한 처리가 증가하게 될 것이다. 또한 처리 속도보다 빠르게 요청이 늘어나게 되면 스레드는 계속해서 생성되고 이로 인해 컨텍스트 스위칭은 더 자주 발생하게 되며 CPU 오버헤드 증가로 CPU time이 낭비되고, 어느 순간 서버 전체가 응답 불가능한 장애 상태로 번질 수 있다. 스레드마다 ..

'NoSQL'에 대해 알아보자

NoSQL이란?NoSQL에 대해 알아보기에 앞서 먼저 RDB의 단점을 알아보자. 변경에 대한 확장성 부족변화된 요구 사항에 맞춰서 기존 테이블에 새로운 컬럼을 추가해 주어야 하는 일이 발생한다. 이때 새로운 컬럼을 추가해 주기 위해서는 반드시 DB 스키마의 변경이 필요하다. 그런데 요구 사항에 맞춰 새로운 컬럼을 추가해 주어야 하는 테이블에 이미 쌓인 데이터가 엄청나게 많다면 어떻게 될까? 기존에 쌓인 대량의 데이터에 대해 추가된 컬럼의 데이터를 적절히 넣어주어야 하기 때문에 write 하는 시간이 많이 소요될 것이고 그만큼 DB 서버는 큰 부담을 가지게 될 것이다. (결국 어플리케이션 자체에 안 좋은 영향을 주고 장애로 이어질 수도 있을 것이다.) 이처럼 RDB는 테이블의 변경에 있어 확장성이 부족하다..