[Kafka] 'Topic Replication'에 대해 알아보자

Topic replication factor 토픽은 replication factor를 가진다. 보통 2와 3 정도로 설정하며 3으로 설정하는 경우가 가장 흔하다. 이를 통해 카프카 서버(브로커)가 다운되었을 때 또 다른 브로커에 있는 데이터 사본을 통해 작업을 수행할 수 있게 된다. ex) Topic-A, 2개의 파티션, 복제 계수 2의 브로커 리더 파티션 1개의 브로커가 파티션 리더 역할을 수행한다. 프로듀서는 파티션의 리더인 브로커에만 데이터를 전송할 수 있다. 리더 브로커가 아닌 브로커들은 리더 브로커의 데이터를 복제한다. 이 때 리더 브로커의 데이터를 복제한 레플리카를 ISR이라 한다. (in-sync replica) (반대로는 out-of-sync replica) 리더 파티션의 기본 동작 기본..

Kafka 2024.03.11 0

[Kafka] 'Broker'에 대해 알아보자

Kafka Broker 카프카 클러스터는 다수의 카프카 브로커로 구성된다. 브로커는 서버를 의미한다. 카프카 브로커는 Integer 타입의 ID로 식별된다. 각각의 브로커는 특정한 토픽 파티션을 가진다. 데이터가 모든 브로커에 걸쳐 분산된다. 클러스터에 있는 모든 브로커를 미리 알고 있을 필요는 없다. 하나의 브로커에 연결하면 클라이언트가 자동으로 나머지에 연결된다. 브로커 개수는 3개 정도로 시작하는 것이 좋으며 여러 개로 설정 가능하다. 예시를 통해 브로커와 토픽의 관계를 이해해보자. 3개의 파티션으로 이루어진 토픽 A와 2개의 파티션으로 이루어진 토픽 B가 있다. 토픽 파티션은 순서에 상관 없이 모든 브로커에 걸쳐 분산되었다. (수평적 스케일링) 파티션과 브로커를 더 추가하면 더 많은 데이터가 전체..

Kafka 2024.03.06 0

[Kafka] 'Consumer'에 대해 알아보자

앞서 토픽에 데이터를 보내는 프로듀서에 대해 알아보았으니 이제 토픽으로부터 데이터를 읽는 역할을 수행하는 컨슈머에 대해 알아보자. 카프카 브로커가 컨슈머에 데이터를 push 하는 것이 아니라 컨슈머가 데이터를 pull 해온다. 하나 이상의 파티션으로부터 데이터를 읽어오는 것도 가능하다. 위처럼 파티션으로부터 데이터를 읽어와야 하는 컨슈머들은 자동적으로 어떤 카프카 브로커(서버)로부터 데이터를 읽을지 알고 있다. 파티션으로부터 오프셋에 따라 데이터를 순차적으로 읽어온다. Consumer Deserializer 컨슈머는 메시지를 읽고 Kafka로부터 받은 바이트를 객체나 데이터로 역직렬화한다. 컨슈머에서 역직렬화하기 위해서는 프로듀서에서 해당 토픽을 저장할 때 어떠한 형식의 Serializer인지에 따라 알..

Kafka 2024.03.04 0

[Kafka] 'Producer과 Message key'에 대해 알아보자

Producer 카프카 토픽 내 파티션으로 데이터를 전송하는 역할을 수행한다. 프로듀서는 토픽 내 어떤 파티션으로 데이터가 전송될 지를 미리 알고 있다. 장애가 발생했을 경우 자동적으로 대응한다. (추후 학습) Message key 프로듀서는 생성하는 카프카 메시지에 메시지 키를 설정 할 수 있다. (optional) 메시지 키가 존재하지 않는 경우(null인 경우) 라운드 로빈 방식으로 파티션에 데이터를 전달한다. 키가 존재하는 경우 같은 키를 가진 데이터들은 같은 파티션으로의 전달을 보장받는다. (hashing) Kafka Message 카프카 메시지는 아래와 같은 정보들로 구성된다. Kafka Message Serializer 프로듀서로부터 입력값으로 직렬화 된 바이트만을 받고 컨슈머에게 출력값으로..

Kafka 2024.03.02 0

[Kafka] 'Topic과 Partition'에 대해 알아보자

Topic Topic은 카프카 클러스터 내의 특정한 데이터 스트림을 의미한다. 하나의 Kafka cluster가 다수의 토픽을 가질 수 있다. ex)로그 토픽, 구매 토픽, 댓글 토픽 비유하자면 DB의 테이블이라고 할 수 있다. 테이블과 다르게 constraint은 존재하지 않는다. 카프카 토픽으로 무엇을 보내더라도 데이터에 대한 검증은 이루어지지 않는다. 클러스터 내의 토픽 간의 구분은 name을 통해 이루어진다. 다양한 메시지 포맷을 지원한다. Partition 토픽은 파티션으로 나뉜다. ex) 특정한 토픽이 [파티션 0, 파티션 1, 파티션 2] 3개의 파티션을 가질 수 있다. 토픽으로 보내진 메시지는 이러한 파티션들에게로 순차적으로 전달된다. 한 번 파티션에 저장된 메시지는 immutable하다...

Kafka 2024.02.28 0

[Kotlin 기초] 제어문 / 반복문 / 예외 / 함수

코틀린에서의 조건문 자바에서 if-else는 Statement이지만, 코틀린에서는 Expression이다. Statement 프로그램의 문장, 하나의 값으로 도출되지 않음 Expression 하나의 값으로 도출되는 문장 코틀린에서는 if-else를 expression으로 사용할 수 있으므로 삼항 연산자가 없다. 코틀린에서는 switch문보다 강력한 기능을 가진 when 을 사용할 수 있다. 코틀린에서의 반복문 for each문 자바에서는 : 를 사용하는 것과 달리 코틀린에서는 in 을 사용한다. ..연산자 범위를 만들어 내는 연산자 코틀린에서의 예외 Checked Exception과 Unchecked Exception 코틀린에서는 Checked Exeption과 Unchecked Exeption을 구분하..

Kotlin 2024.02.26 0

[Kotlin 기초] 변수 / Null / Type / 연산자

코틀린에서 변수 다루기 var과 val의 차이점 var variable의 약자 변할 수 있는 값을 담는 변수 선언 시 사용 val value의 약자 변하지 않는 값을 담는 변수 선언 시 사용 Kotlin에서 nullable 변수 Nullable한 변수는 타입 뒤에 ?를 붙인다. 코틀린에서 Null 다루기 null 체크 null이 아닌 경우에만 호출되는 Safe call 사용 ex) str?.length (str이 null이면 null 리턴) Elvis 연산자 str?.length ?: 0 str이 null인 경우 0 리턴 코틀린에서 Type 다루기 기본 타입 Byte Short Int Long Float Double 부호 없는 정수들 기본 타입이 아닌 경우) is java에서의 instance of as..

Kotlin 2024.02.24 0

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

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

소프트웨어 개발 2024.02.23 0

[Redis] 레디스의 Transaction 명령어

Redis Transaction 여러 개의 명령을 내부 큐에 모아두고 트랜잭션 완료를 전달하면 일련의 명령을 한번에 처리한다. 트랜잭션 관련 명령어 MULTI 트랜잭션 시작 EXEC 트랜잭션으로 큐에 쌓여있던 명령 실행 DISCARD 트랜잭션 취소 WATCH 동시에 같은 키를 수정하는 상황이 일어났을 때 트랜잭션 취소 오류 발생 시 트랜잭션 내 모든 명령은 취소된다. 단 잘못된 인자 전달의 경우에는 해당 명령어만 에러 처리하고 정상 처리된다.

카테고리 없음 2024.02.22 0

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에서는 ..

소프트웨어 개발 2024.02.21 0

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

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

소프트웨어 개발 2024.02.20 0

카프카는 왜 빠를까?

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

소프트웨어 개발 2024.02.19 0

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

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

소프트웨어 개발 2024.02.18 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..

소프트웨어 개발 2024.02.17 0

웹 브라우저에 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 주소를 잠시동안 캐싱해둔..

소프트웨어 개발 2024.02.16 0

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

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

소프트웨어 개발 2024.02.15 0

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

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

소프트웨어 개발 2024.02.14 0

'NoSQL'에 대해 알아보자

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

소프트웨어 개발 2024.02.12 0

'파티셔닝, 샤딩, 레플리케이션'에 대해 알아보자

partitioning 파티셔닝이란 데이터베이스의 테이블을 더 작은 테이블로 나누는 것을 말한다. 파티셔닝의 종류는 크게 2가지로 나눌 수 있다. vertical partitioning > column을 기준으로 테이블을 나눈다. horizontal partitioning > row를 기준으로 테이블을 나눈다. vertical partitioning (column을 기준으로 테이블 분리) RDB를 설계하면서 데이터 중복을 제거하기 위해 사용하는 정규화 과정도 컬럼을 기준으로 테이블을 분리함으로 vertical partitioning이라고 할 수 있다. 정규화 이외에도 vertical partitioning은 다양한 상황에서 이용이 되는데 또 다른 예를 확인해 보자. 게시글에 대한 정보를 담고 있는 pos..

소프트웨어 개발 2024.02.11 0

'DB 인덱스'에 대해 알아보자

DB 쿼리 속도 최적화를 위한 '인덱스'에 대해서 많이 들어보았을 것이다. 오늘은 이 인덱스란 녀석에 대해서 알아보자. Index, 왜 중요할까? 100만 명이 등록되어 있는 user 테이블이 있다. 이때 이름을 기반으로 유저를 조회하려고 한다. select * from user where user_name = "hyunjun" hyunjun이라는 이름을 가진 계정을 찾기 위해서는 100만 개의 row를 모두 scan 해야 한다. (full scan, O(N)) 만약 user_name에 index를 걸어두었다면? B-tree index 기반으로 O(logN)의 시간 복잡도로도 충분히 찾을 수 있다. 정리하자면 index를 사용하는 이유는 특정 조건을 만족하는 데이터들을 빠르게 찾기 위함이다! 상황에 따라..

소프트웨어 개발 2024.02.10 1

테스트 코드, 왜 작성하는가

나는 왜 테스트 코드에 관심을 가졌는가 때때로 사이드 이펙트에 대한 두려움으로 인해 리팩토링을 포기하고 방치하게 되는 코드들이 존재했다. 서비스가 커질수록 코드 간의 의존성이 커지고 작은 부분의 수정으로도 영향을 받는 곳이 너무 많아 코드 수정이 부담스러워진다. 테스트 코드가 이러한 부담을 줄여줄 것으로 기대했다. 실무 프로젝트 1차 도전 신규 프로젝트인 만큼 서비스의 방향성이 자주 바뀌고는 했다. 큰맘 먹고 테스트 도입을 시도해 보았으나 기획이 바뀌어 개발해두었던 코드를 오히려 전부 걷어내거나 디비 구조가 대대적으로 변경되는 일들이 발생했다. 기능 개발에 여유가 있는 시점에 조금씩 도입을 해보았는데, 큰 변경 사항들이 생기자 테스트 코드를 관리할 여유가 없었고 본 코드가 사라진 테스트 코드들은 주인을 ..

소프트웨어 개발 2024.02.08 0