기본 콘텐츠로 건너뛰기

개발 공부 - 공부를 위한 kafka 관련 회고

 오랜만에 면접을 보고, 거의 Producer 역할을 개발했던 Kafka에 대해 회고해 본다.

금일 면접은 퇴사 사유를 너무 정직하게 말해서 조금 반성하는 점이 있다.
그렇지만 계약 사항 준수는 중요하다고 생각하고... 사실 거짓말 해도 인사팀끼리 커넥션을 통해 진실을 알지 않을까? 싶어서 정직하게 말했다...
(그러나 Kafka 관련 회고를 할 수 있어서 좋은 경험!)

어쨌든 카프카의 중복 컨슘에 관해 면접 질의가 와서, 회고 및 부족 사항을 R&D 해보기로 했다!
퇴사한 회사에서는 MSA 구조 내에서 해결 할 수 있는 방식이었는데, Kafka 단독으로 할 수 있는 방식이 구글링하니 많이 나와서 알아두기로 했다.

일단 트렌디하게 chatgpt에게 외주를 줘본다.



1. 메시지 오프셋 관리: 카프카는 각 토픽의 파티션에 대해 메시지의 오프셋(offset)을 관리합니다. Consumer가 메시지를 처리할 때마다 해당 오프셋을 커밋하도록 설정하면, 이미 처리된 메시지는 중복으로 처리되지 않습니다.

2. 고유 식별자 사용: Consumer가 메시지를 처리하기 전에 메시지에 대한 고유 식별자를 추출하고, 이미 처리된 메시지인지 확인하는 방법을 사용할 수 있습니다. 이를 통해 중복 메시지를 감지하고 처리할 수 있습니다.

3. 메시지 상태 관리: Consumer가 처리한 메시지의 상태를 추적하여 중복 처리를 방지할 수 있습니다. 예를 들어, 메시지를 처리하기 전에 상태를 변경하고, 이미 처리된 메시지인 경우 처리하지 않도록 로직을 작성할 수 있습니다.

4. 더 높은 수준의 추상화 사용: Apache Kafka의 고수준 Consumer 라이브러리를 사용하면 중복 메시지 소비를 방지할 수 있는 내장 기능을 제공합니다. 예를 들어, Kafka Streams나 Apache Flink와 같은 스트리밍 처리 프레임워크를 사용하면 중복 처리를 관리하는 기능을 제공합니다.

- chatgpt가 정리해 준 걸 보고 내 언어로 풀고, 알아서 공부를 해 보기로 한다 - 


이게 기존 회사는 0~14일 동안 바라봐야 하는 id가 있어서 그거 때문에 오프셋 정보를 또 다시 저장해야 하는 oracle db를 가지고 있는 조금 이상한 형태였는데(면접에 설명을 했으나 중개 시스템이 너무 난해해서 설명 하기가 어려운 형태이다...), 그것을 배제하고 생각해보겠다.

작년에 개발 할 때 정리해 놨던 것

*. SI를 위한 카프카 간단 정리 
1. 프로듀서가 브로커(의 토픽)한테 메시지를 줌
2. 브로커가 카프카에서 메시지를 저장함
3. 컨슈머가 토픽(브로커=카프카 애플리케이션 서버 (아니면 노드일 수도 있음))에 저장된 메시지를 가져옴
4. 근데 컨슈머가 메시지 가져올 때 여러 가지 할 수 있음 (카프카 설정 or 동작 설정)

프로듀서 : 카프카로 메시지 보내는 클라이언트
컨슈머 : 카프카에서 메시지 가져가는 클라이언트
브로커 : 카프카 애플리케이션이 설치된 서버

자바에서 아파치 라이브러리 사용해서 kafka 붙일 수 있음
브로커는 고객사에서 설치 해 줌 (2개라  알아서 이중화 하면 됨)
이중화는 인메모리 DB로 개발 필요함 (kafka 서버 이중화 사용 하지 않을 경우)

역시 이 때도 나는 프로듀서 쪽의 개발 역할이라. send 해주고 retry 해주는 부분 처리 해 놓은 정도였으며, 중복 처리보다는 각각 처리 메시지 위치 추적이 더 중요했다.

중복 처리를 하거나 메시지가 아예 누락 될 때에는 Kafka의 offset 개념이 들어가는데, 오프셋은 포인터 같은 거다! (자세한 사항은 검색 해 보세요.)
이게 같은 오프셋 값을 바라볼 수도 있고, 아니면 아예 서로 따로 오프셋을 관리할수도 있다.

컨슈머는 컨슈머 그룹에 속할 수 있는데, 이게 동일한 토픽의 파티션을 처리할 경우에는 동일한 오프셋을 참조한다.
그래서 한 컨슈머가 메시지를 처리하면 그 오프셋이 커밋되고, 다른 컨슈머가 같은 오프셋을 처리하지 않도록 한다.

그런데 (내가 개발할 것과 같이) 컨슈머들이 독립적으로 오프셋 관리를 할 때는 이게 컨슈머 그룹을 관리하지 않도록 한 경우라, 오프셋 커밋이 해당 컨슈머에서만 수행되게 설정할 수 있다! 그리고 또 파티션 수랑 컨슈머 수가 일치하지 않으면, 토픽 각 파티션이 병렬적으로 처리 될 수 있고, 동일한 토픽을 여러 컨슈머가 구독해 갈 때도, 각각 컨슈머가 해당 파티션에 대한 오프셋을 독립적으로 관리하게 할 수 있다.

이렇게 할 때 단점이 있다.
첫 번째 경우 : 중복 처리를 주의해야 한다.
두 번째 경우 : 메시지 순서가 보장이 안 되는데, 요걸 질문 해 주셨다.


첫 번째 경우는 자주 일어나는 일인데, 메시지가 오토커밋으로 설정되어 있을 때, 자주 나는 일인데, 오토 커밋 간격을 조정하거나, 메시지에 식별자를 사용하는 방식 등이 있다.
하나의 트랜잭션으로 묶어서 처리하는 방법도 있는데, 사실 오토 커밋 간격을 조금 더 길게 설정하면 될 것 같지만 많은 검색 결과가 나오는 이유가 있다...
어쨌든 검색 해보니 트랜잭션으로 묶어서 처리 + 수동 커밋 사용으로 극복 하는 방식을 추천하나 보다.
이게 컨슈머 쪽 처리라 내가 관심이 낮았던 것인데 ↓ 이 블로그를 참조하면 되겠다.
사실 이것도 리밸런스가 되면 또 다시 컨슘하게 되서 중복 처리 되는 일이 있을 수 있긴 하다...
리밸런스는 컨슈머 그룹 구성원 간에서 파티션의 할당을 재조정하는 과정인데, 이게 파티션 할당이 변경될 때 컨슈머 인스턴스가 동일한 메시지를 중복 처리할수가 있다.
그래서 또 이것도! 메시지에 고유한 식별자를 포함해서 중복 처리하는 과정이 로직상에 들어간다! (속도 저하 요인 - 해결 하느라 shit my self 였음. - 근데 또 이 과정을 넣으면 kafka를 쓰는 이유가 없다고 해서 이상하게 해결 하긴 했는데 보통 동일하게 처리 하나 보다. - https://colinch4.github.io/2023-11-16/21-27-11-312101-%EC%B9%B4%ED%94%84%EC%B9%B4%EC%99%80-%EC%9E%90%EB%B0%94%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A4%91%EB%B3%B5-%EC%A0%9C%EA%B1%B0/ ← 이런 식으로 한다.)
어쨌든 논리적으로 해결하는 방식이 필요하다.

두 번째 경우는 메시지 순서 보장의 건인데, 이게 내가 해결한 방식은 serializable을 사용해서 키값으로 동일한 키 값을 가지는 메시지 = 동일한 파티션에 배치한다- 였고, 보통 파티션 단위로 메시지 순서를 보장해서, 동일한 파티션에 속한 메시지가 순서대로 처리하는 방식으로 진행한다. 또, 메시지에 타임스탬프를 찍어서 그 기준으로 메시지 처리를 하는 로직을 구현 하는 방식도 있고, 이미지와 같이 워터마크 등을 사용해서 메시지 순서 추적을 하는 방식으로 구현 할 수도 있다.
이게 사실 카프카 파티션이 1개면 순서가 보장 되는게 쉽긴 할 텐데, n개인 상태에서 실시간 보장이 되어야 하는 상황이면 여러가지를 고려 해야 할 것이다.
구현했던 방식은 n개 + 실시간 보장이 안 되어도 됨 + 일단 발송 되지 않고 UI 내에서만 순서 보장이 되면 됨 이었다.

아무튼 요게 스트리밍을 위해서는 카프카를 썼는데, redis를 붙였다가 떼었던 경험이 있다!

1. Kafka 와 redis 같이 쓴 이유
레디스를 같이 써야 캐싱이 빨랐다.
레디스가 인메모리 데이터 스토어가 있어서, 빠르게 실시간으로 서비스 할 수 있었다.
레디스에 저장된 데이터로 데이터 파이프라인 구축이 용이했다.

2. Kafka 에서 redis 제거 한 이유
잘못된 기존 설계로 오히려 성능이 저하 되었다! (큰 이슈!)
ㄴ 개발 - 테스트 - 배포 서버가 있었는데, 테스트 서버에서 죽었다!
데이터가 일관성이 떨어져서 논리적이지 못한 처리가 되었다!
사장님이 퍼포먼스가 저하 되어도 비용을 어떻게든 줄이라고 했다! (제일 큰 이슈!)

였는데, 일반적인지는 모르겠다... (경험에 기반한 활동)






댓글

이 블로그의 인기 게시물

Ebook - 전자책 drm 상관 없이 pdf로 만들기

yes24와 교보문고에서 ebook을 구매 해야 했는데 너무 불편하고, 필기가 매우 화날 정도로 안 좋아서 원시적으로 사용하기로 했다. 1. 목적 : ebook에서 필기 및 사용이 불편하여 pdf로 변환  2. 용도 : 개인 사용 목적이며 화질이 다소 저하되어도 필기만 용이하면 상관 없음 3. 방법 1) 휴대폰 및 카메라로 동영상을 촬영했다. DRM 때문에 프로그램으로는 촬영이 안 되는 것을 확인했다. (사실 개인 사용 목적이면 기본 화면 캡쳐를 사용해도 된다...) 2) 마우스 클릭 해주는 매크로를 사용했다. (1) key_macro.exe > https://blog.daum.net/pg365/250 듀얼 모니터에서 위치 이탈 현상이 있긴 해도 괜찮았다. (2) AutoClick.exe > http://bestsoftwarecenter.blogspot.com/2011/02/autoclick-22.html 이 걸로 잘 사용했다. 3초마다 한 번 클릭하도록 사용했다. 3) 동영상을 이미지로 변경해주는 프로그램을 사용했다. Free Video to JPG Converter > https://www.dvdvideosoft.com/products/dvd/Free-Video-to-JPG-Converter.htm (240826: 다운로드 시 정상적으로 되지 않아서 URL 수정) 일 하면서 듀얼 모니터에 켜 놨는데 속도가 괜찮았다. * Every frame 으로 사용해야 한다. 4) 중복 사진 제거해주는 프로그램을 사용했다. VlsiPics  > http://www.visipics.info/index.php?title=Main_Page 생각보다 느리니 퇴근시에 걸어놓고 가면 된다. 한번 play가 끝나면 Auto-select 하고 Delete 하면 된다. 5) 이미지를 일괄 Crop 작업 해주는 프로그램을 사용했다. JPEGCrops > https://jpegcrops.softonic.kr/ *...

개발 공부 - json JSONObject 사용 시 백슬래시(\), 원화 표시(\) 제거 및 치환

import org.json.simple.JSONObject; String dataString = new String(authData.toJSONString()); dataString = dataString.replaceAll("\\\\", ""); String 으로 안 바뀌는 가 싶어서 String 으로 변환 해 주고 작업 하였다. 사실 toJSONString 해도 정상 동작 해야 하는데 이유를 잘 모르겠음. 그리고 나서 다시 이클립스 구동 하니 toString 도 먹은 걸로 봐서 이상하다고 생각! String dataString = authData.toString(); dataString = dataString.replaceAll("\\\\", ""); 어쨌든 백 슬래시 제거를 해줘야 하는데 \\ 도 아니고 \\\\를 해야 변환이 가능했다는 결말이었습니다. 참고 : https://stackoverflow.com/questions/15450519/why-does-string-replace-not-work/15450539 test =test.replace("KP", "");  replace 후에 담아 주지 않으면 적용이 안 됩니다!

개발 공부 - OracleXETNSListener 서비스가 로컬 컴퓨터에서 시작했다가 중지되었습니다.

여러 가지 요인이 있지만 PC 이름 변경시 OracleXETNSListener 서비스 시작이 불가능합니다. 고치는 법은 C:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN 와 같은 설치 경로에서 listener.ora와 tnsnames.ora 의 pc명을 바꾼 PC명으로 바꿔주면 됩니다. 그래도 안 된다면 cmd 창에서 services.msc 를 입력 후 OracleXETNSListener 서비스를 시작 시키면 됩니다. 오류명: OracleXETNSListener 서비스가 로컬 컴퓨터에서 시작했다가 중지되었습니다. 일부 서비스는 다른 서비스 또는 프로그램에서 사용되지 않으면 자동으로 중지됩니다. 참고한 사이트들 1. http://blog.naver.com/visioner7/120165951652 2. http://database.sarang.net/?inc=read&aid=6819&criteria=oracle&subcrit=&id=&limit=20&keyword=ora-12560&page=5 이런 걸 보면 오라클은 앙칼진 시골 아가씨야