작성
·
334
0
안녕하세요, 철민님.
항상 좋은 강의 감사드립니다. 한 가지 질문 드리고 싶은 부분이 있어서 글을 작성했습니다.
BACKWARD, FORWARD 호환성 같은 것들을 이야기 해주셨을 때... 프로듀서 / 컨슈머가 먼저 스키마를 업데이트 한 후에 이후에 컨슈머 / 프로듀서가 스키마를 업데이트 하는 식이 되었다고 설명을 해주셨습니다. 실제 동작에서는 어떻게 될지 궁금합니다.
예를 들어 Source 커넥터, Sink 커넥터가 둘다 v1 스키마를 사용하고 있는 상황이라고 가정해보겠습니다.
이 때, Source System에서 DB 컬럼 변경이 있어 Source Connector에서 스키마 변경이 발생되었습니다. 그럼 이 때, Source Connector, Sink Connector에서는 각각 스키마 업데이트가 어떻게 진행이 될까요? 제가 생각하는 순서는 아래와 같습니다.
Source쪽 Coneverter에서 메세지를 보내려고 했을 때, 캐싱된 스키마에서 현재 스키마를 찾을 수 없음
Source쪽 Converter는 스키마 레지스트리에 REST API를 보냄. 이 때, subject 명이 동일한 것을 확인하고 스키마 레지스트리는 그 스키마를 저장하고 version + id를 새로 생성해서 그 값을 리턴해 줌.
Source쪽 Converter는 version + id + 스키마 정보를 로컬 캐싱한 후, 스키마 Id + 메세지를 카프카에 보냄.
Sink쪽 Converter는 카프카에서 메세지를 읽어왔는데 로컬 캐시에 저장되지 않은 스키마 ID를 확인함
스키마 레지스트리에 스키마 ID에 대응되는 스키마를 요청해서, 받아온 스키마를 바탕으로 역직렬화 + 메세지를 생성함.
Sink System으로 넣어줌.
제가 생각했을 때는, Avro에 스키마 ID만 들어가는 상태이기 때문에... 프로듀서 / 컨슈머가 각각 캐싱하고 있는 스키마 ID가 없다면 항상 스키마 레지스트리에 요청해서 데이터를 가져올 것으로 보이는데... 이 경우는 스키마 호환성이라기 보다는 필요할 때 마다 항상 look up해서 사용하는 느낌이 아닌가 싶습니다.
혹시 제가 잘못알고 있는 부분이 있다면.. 알려주실 수 있으실까요?
항상 감사드립니다
좋은 하루 되세요!
답변 1
0
안녕하십니까,
먼저, 적어 주신대로 source와 sink connector가 스키마가 update되었을 때 스키마 레지스트리에 스키마ID와 스키마 정보를 등록하는 1 ~6번 로직은 다 맞습니다.
그리고 적어주신,
Avro에 스키마 ID만 들어가는 상태이기 때문에... 프로듀서 / 컨슈머가 각각 캐싱하고 있는 스키마 ID가 없다면 항상 스키마 레지스트리에 요청해서 데이터를 가져올 것으로 보이는데
=> 이것도 맞습니다.
그런데, 아래 질문은 잘 이해가 안되는 군요.
이 경우는 스키마 호환성이라기 보다는 필요할 때 마다 항상 look up해서 사용하는 느낌이 아닌가 싶습니다.
=> 스키마 호환성과 스키마 레지스트리에서 정보를 가져오는 일반적인 로직을 비교하신것 같은데, 이건 약~간 비교가 다릅니다.
스키마 호환성은 기존 메시지와 다르게 신규 메시지가 변경되었을 때 이를 기존 메시지 스키마의 연장선에서 신규 메시지 스키마의 변경을 어떻게 받아 들일 것인가의 문제 입니다. 특정 스키마 호환성을 토픽에 설정할 경우 해당 토픽에 대해서 설정된 스키마 호환성에 어긋나는 스키마 변경은 아예 스키마 레지스트리에서 받아들이지 않습니다.
즉 스키마 호환성이 특정 토픽에 설정되었다면 스키마 레지스트리는 스키마 변경이 일어났을 때 적절한 변경인지 확인한 후 신규 스키마 ID를 부여합니다. 스키마 호환성에 어긋나는 변경이라면 스키마 레지스트리는 오류를 발생 시킵니다.
원하시는 답변이 아니시면 다시 글 부탁드립니다.
그런데, 벌써 스키마 레지스트리를 학습하시다니,,,, 지난번 강의도 진도가 빠르시던데,,, 훌륭한 학습력을 가지고 계시는군요(부럽습니다 ^^)
감사합니다.
스키마 호환성 정책의 적용 결과는 스키마 레지스트리가 새로운 스키마가 들어왔을 때 저장하느냐, 하지 않느냐로 나타난다.
=> 네 맞습니다. 새로운 스키마가 스키마 호환성에 맞다면 스키마 레지스트리는 대상 Topic의 스키마에 새로운 스키마 아이디로 스키마를 저장하게 되고, 스키마 호환성에 맞지 않다면 호출 클라이언트에 오류를 반환하게 됩니다.
Consumer, Producer는 스키마 호환성 정책을 신경 쓰지 않고 스키마 레지스트리에 요청했을 때 받는 스키마 ID로만 메세지를 랩핑하거나, 언랩핑한다.
=> 네, 맞습니다.
스키마 호환성 정책을 신경 쓰지 않다기 보다는 Consumer, Producer의 역할 자체가 다릅니다. Consumer, Producer는 메시지를 읽거나 전달하는 역할을 수행합니다. 보통 connector에서는 converter에서 메시지를 포맷팅할 때 스키마 호환성과 관련한 인터페이스를 스키마 레지스트리와 수행하게 됩니다.
선생님이 잘 가르쳐주시니 학생이 잘 따라갈 수 있는 것 아닐까요 ㅎㅎ
다 이해하고 넘어가는 것은 아니고 찍먹 후... 나중에 한바퀴 전체 살짝 돌려보려고 힘내고 있습니다 :)
음... 질문이 약간 모호했을 수도 있고, 답변 해주신 것이 모호한 것 같기도 합니다. 철민님께서 답변해주신 내용으로 제가 이해해보면 BACKWARD, FORWARD 같은 스키마 호환성의 판단 주체는 Consumer / Producer가 아니라 스키마 레지스트리 인 것처럼 이해가 됩니다.
그래서 추정해보건데.. 이런 결론이 아닐까 싶습니다. 틀린 이야기일까요?
애초에 Consumer나 Producer가 스키마 호환성을 염두해두고 개발된 녀석이 아니기 때문에 이 녀석들에게는 현재 스키마와 이전 스키마의 호환성을 판단하는 로직은 없습니다. 대신에 그 책임은 스키마 레지스트리가 가져갑니다.
스키마 레지스트리는 스키마 호환성 정책의 적용 결과로 스키마를 등록하거나 하지 않습니다. 비단 프로듀서가 아니더라도, REST API로 특정 Subject로 스키마를 등록한다면 이 때 스키마 레지스트리는 그 subject / global config를 통해서 스키마 호환성 전략을 확인하고, 호환성 전략을 만족하는 스키마만 스키마 레지스트리에 등록하고 아닌 경우에는 스키마를 등록하지 않습니다.
바꿔 이야기하면 Consumer / Producer는 이미 스키마 호환성을 고려해서 등록된 스키마 ID를 받아서 그것을 가져다 쓰기만 하는 역할을 합니다.
이래저래 말이 길어져서 다시 짧게 줄이면 이렇습니다
스키마 호환성 정책의 적용 결과는 스키마 레지스트리가 새로운 스키마가 들어왔을 때 저장하느냐, 하지 않느냐로 나타난다.
Consumer, Producer는 스키마 호환성 정책을 신경 쓰지 않고 스키마 레지스트리에 요청했을 때 받는 스키마 ID로만 메세지를 랩핑하거나, 언랩핑한다.
이렇게 이해를 하면 될까요...? 혹시 다르다면... 죄송하지만 다시 한번 알려주시면 감사하겠습니다..!