컨슈머가 poll() 메서드를 호출할 때마다 컨슈머는 컨슈머 그룹에서 배정된 파티션에서 아직 읽지 않은 메시지를 가져온다.이렇게 동작 할 수 있는 것은 컨슈머 그룹이 파티션에서 읽은 지점까지의 위치값을 저장하기 때문에 알 수 있다.
- 컨슈머 그룹의 컨슈머들은 각각의 파티션에 자신이 가져간 메시지의 위치 정보 오프셋을 기록한다.
- 각 파티션에 대해 읽어간 메시지들의 위치를 갱신하는 동작을 커밋이라고 한다.
오프셋 저장 (커밋정보)
초기 카프카는 이 오프셋 정보를 주기커에 저장했지만 주키퍼의 write 오버헤드로 인해서 최신 버전(0.9 이후)에서는 카프카 내부 토픽 (__consumer_offsets)에 오프셋 정보를 저장한다.
리밸런스에 의해 컨슈머들이 새로운 파티션에 배정되어도 이전에 기록된 오프셋 정보를 이용해서 그 이후 메시지를 가져오게 된다.
자동 커밋
자동커밋은 enable.auto.commit=true 컨슈어 옵션으로 사용할 수 있다.
- 자동커밋을 사용하게 되면
auto.commit.interval.ms로 주어진 주기(디폴트: 5초)로 poll() 을 호출할때 가장 마지막 오프셋을 커밋하게 된다.
- 컨슈머는 poll()을 요청할 때마다 커밋할 시간인지 아닌지 체크하여 가져온 메시지의 가장 마지막 오프셋을 커밋한다.
단, 아래와 같은 상황에서 메시지 중복 처리가 발생할 수 있다.
- 컨슈머 1에서 메시지를 한번에 두개씩 가져오고 있다.
- 컨슈머 1에서 오프셋 4번까지 커밋하고, 5번/6번 두개의 메시지를 가져왔지만 아직 커밋 주기가 되지 않아서 커밋되지는 않은 상황 (즉, 메시지는 6번까지 가져왔지만 오프셋은 아직 4번인 상황)
- 이 상황에서 컨슈머 1에게 문제가 발생하여 리밸런싱 되었고 컨슈머 2가 해당 파티션에 배정되면 5번 메시지부터 처리를 하게 된다.
- 즉, 5번 6번 메시지는 중복 처리할 가능성이 있다.
- 커밋 주기를 짧게 하더라도 가능성을 완벽히 제거하는 것은 어렵다. (카프카는 적어도 한번을 보장한다 - 중복이 있을 수 있지만 손실은 없음을 보장)

수동 커밋
만약 메시지 처리가 완료될 때 까지 메시지를 가져온 것으로 간주되어서는 안되는 경우에는 수동 커밋을 사용하여 제어할 수도 있다.
- commitSync() 메서드를 사용하여 수동 커밋을 할 수 있다. (카프카는 적어도 한번을 보장한다 - 중복이 있을 수 있지만 손실은 없음을 보장)
특정 오프셋부터 가져오기