- 개념

Kafka는 Kafka cluster로 운영되고, cluster는 브로커의 집합이다.

브로커는 프로듀서에게 메세지를 받아서 저장하고, 컨슈머는 메세지를 차례대로 꺼내간다. 

브로커가 여럿일 경우, 일련의 메세지를 파티션으로 나누어 분산 처리할 수 있다.

k개의 브로커에 대해 파티션 x번은 x%k번째 브로커가 리더로서 저장한다.(모든 브로커가 저장하긴 한다.)

그러나 파티션 별로 ordering이 보장이 될 뿐이라, 일련의 메세지를 순서대로 재구성하려면 파티션을 사용하면 안된다.

 

 - exactly-once

메세지를 주고받을때, at least once / at most once / exactly once라는 semantic 종류가 있다.

Kafka 초기 버전은 at least once를 보장하여 네트워크 장애로 인해 중복되는 메세지를 막을 방법이 없었다.

그러나 1.0.0 부터인가 enable.idempotence 기능이 추가되면서 exactly once가 보장되기 시작한다.

또한, 0.11.0 부터 transactional messaging 기능이 추가되었기에, 이를 사용하면 producer 측에서도 exactly once를 보장할 수 있을 것이다. 이는 아래에서 자세히 설명한다.

enable.idempotence는 정확히 말하면 Kafka에서 exactly-once를 보장한다는 의미인데, producer와 consumer는 알아서 application에서 잘 처리해서 exactly-once를 만들어야 된다. 해당 기능은 연결되는 producer마다 PID(producer ID, 32bit)를 부여하고 메세지마다 serial number(64bit)를 붙여서 네트워크 장애로 인해 여러번 메세지가 와도 broker가 중복을 막을 수 있다는 말이다. producer는 죽었다가 재연결하면 PID가 새로 발급되기 때문에, producer가 죽었다가 재연결한 뒤 같은 메세지를 보내면 이는 중복을 막을 수 없다. 만약 PID와 serial number를 producer application이 설정할 수 있다면 그나마 쉽게 producer측 exactly-once를 구현할 수 있을텐데, 약간 아쉬운 기능이다.

 ※ 참고로 ogg-bd의 kafka handler는 자기네 옵션 중 blocking send(ack=all), tx mode(=tx)를 켜면 exactly-once를 지원한다고 한다. 즉, 아마 ogg-bd 또한 idempotence 기능과 transactional messaging을 사용해서 구현할 것이다.

 

 - producer / consumer의 exactly-once 구현

producer는 메세지를 보내는 동시에(atomic하게) 자신의 디스크에 워터마크를 쓸 수 없기 때문에 producer application의 exactly-once는 만들기 어려운 감이 있다. consumer는 읽어서 처리한 후에 워터마크를 찍어놓고 죽었다가 다시 켜면 확인하도록 해서 (producer보단 쉽게?)exactly-once가 된다.

producer의 exactly-once는 다음과 같이 구현할 수 있다. 메세지 하나에 오라클의 scn같은 serial number를 붙이면서, 같은 tx에 serial number 값을 producer만 보는 토픽 t로 보내서 저장하면 producer가 죽었다가 다시 깨어나도 kafka가 어디까지 받았는지 토픽 t를 통해 알 수 있기 때문이다.(producer application이 토픽 t를 consume한다는 가정이다.)

추가적인 방법으로는, 메세지가 멱등 연산만을 보내도록 제한하는 방법이다. 메세지가 중복되어 수신자가 두 개의 같은 메세지를 보고 똑같이 어떤 함수를 실행해도, 멱등 연산이라면 최종적인 결과에는 영향이 없기 때문이다. 다만 보내려는 메세지를 멱등 연산으로 만들려면 추가적인 정보(ex 연산에 대한 UUID)가 필요하기도 하는 등 섬세한 설계가 필요하다.

 

 

참고자료:

idempotence producer features: https://www.cloudkarafka.com/blog/2019-04-10-apache-kafka-idempotent-producer-avoiding-message-duplication.html

tx msg 한글 설명: https://gunju-ko.github.io/kafka/2018/03/31/Kafka-Transaction.html

kafka 공식 producer API: https://kafka.apache.org/20/javadoc/org/apache/kafka/clients/producer/KafkaProducer.html

 

 

'backend' 카테고리의 다른 글

oracle golden gate 19c 예제  (0) 2020.08.28
DB transaction isolation level  (0) 2020.04.03
분산 데이터베이스의 CAP 이론  (0) 2019.08.31
Load Balancer  (0) 2019.08.03
Posted by sjo200
,

SGA - DB buffer cache

Oracle DB 2019. 9. 3. 14:20

https://docs.oracle.com/en/database/oracle/oracle-database/18/cncpt/memory-architecture.html#GUID-093B7282-1A44-4E29-9E9A-B8511F4267C9

 

/* SGA = shared pool + large pool + db buffer cache + redo log buffer + ... */

 

1. 목적: IO 최적화(redo log buffer 사용), data block 캐싱(flash disk 사용 시 가능)

 

2. buffer state: 1) Unused: 한 번도 안씀, 2) Clean: 썼다 지움, 3) Dirty: 아직 disk에 안씀(ckpt 되어야 clean 가능)

 

3. buffer mode: current mode, consistent mode에 따라 캐시의 내용을 undo data 사용해서 주냐 안주냐 차이이다.

 

4. buffer IO: LRU 알고리즘 or Temperature based, object-level replacement algo. 를 사용해서 data block을 교체하는데, 보통 LRU 씀. pinned 된 버퍼에는 touch count라는 개념을 쓰기도 하는데, 최근 3초내에 한 번 이상 사용되었으면 +1이 된다. touch count가 높은데 cold end에 있는 block이라면 hot end로 옮겨준다. DBWR는 주기적으로 cold, dirty 버퍼를 디스크에 써준다. 새 버퍼 블록이 필요한데 clean block이 없거나, threshold 이하 개수로 떨어지면 쓰고, LRU cold의 끝에 다다른 블록 또한 써준다. 특이한 상황으로는 checkpoint로 instance recovery를 진행해야할 경우, tablespace가 read-only로 되거나 offline으로 전환될 때 버퍼를 디스크에 쓴다.

 

flash cache를 사용하는 경우 buffer load 방식은 다른건 다 비슷한데, buffer cache, flash cache 둘다 미스나면 디스크에서 가져와서 둘 다에 등록하는 점이 주목할 만 하다.

 

5. buffer pools: 버퍼들의 집합이다. 또한 DB 버퍼 캐시는 여러 개의 버퍼 풀로 구성된다. 버퍼 풀은 Default pool(보통 블록들이 캐시되는 곳), Keep pool(자주 사용하는 블록들 담을 캐시, 공간 부족으로 block이 aged out이 될 수도 있다.), Recycle pool(한 번만 쓰고 재사용할 블록들을 모아둔 캐시)가 있다.

 

6. full table scans: 풀 테이블 스캔 시 작은 테이블은 SGA에 로드하고, 큰 테이블은 PGA에 바로 로드시킨다. 중간 사이즈는 SGA에 로드시킬 경우, 블록을 LRU의 마지막 우선순위에 넣어서 캐시 용량을 많이 사용하지 않도록 한다.

'Oracle DB' 카테고리의 다른 글

DBMS의 LOB 저장 구조  (0) 2020.04.09
DB에 redo log가 필요한 이유  (0) 2020.04.06
SGA - large pool, java pool, fixed SGA  (0) 2019.09.03
SGA - shared pool  (0) 2019.08.31
기본 구조  (0) 2019.08.31
Posted by sjo200
,

/* SGA = shared pool + large pool + db buffer cache + redo log buffer + ... */

 

1. Large pool = UGA 할당, 메세지 버퍼 할당, I/O 버퍼 할당, shared pool보다 큰 메모리만 할당해서 fragmentation 방지한다. shared pool의 메모리는 LRU로 관리되지만 large pool은 세션이 존재하는 동안 메모리는 계속 유지된다.

 

  1.1 shared server에서 사용하는 UGA 할당

  1.2 Oracle XA interface

  1.3 statement 병렬 실행(query coordinator)을 위한 메세지 버퍼 할당

  1.4 RMAN I/O slave를 위한 I/O 버퍼 할당

 

 

2. Java pool = JVM의 java code, data 올리는 곳.

 

  2.1 dedicated server: JVM의 session specific한 java code와 data, 그리고 vector같은 read only class를 올리는 메모리이다. 세션 별 java 상태는 안올림.

 

  2.2 shared server: 클래스끼리 공유되는 부분, 그리고 세션에 사용되는 UGA의 일부분을 메모리에 올린다.

 

 

3. fixed SGA = DB 내부 관리구역이다. background process가 알아야하는 DB / instance 상태, lock 정보를 저장한다.

 

'Oracle DB' 카테고리의 다른 글

DB에 redo log가 필요한 이유  (0) 2020.04.06
SGA - DB buffer cache  (0) 2019.09.03
SGA - shared pool  (0) 2019.08.31
기본 구조  (0) 2019.08.31
참고 사이트  (0) 2019.08.18
Posted by sjo200
,