RocketMQ Commit Log 스토리지 프로토콜을 다시 이해합니다.

최근에 문득 많은 소프트웨어와 하드웨어가 디자인이 아닌 그 당시 그 장면의 요구를 해결하기 위해 근본적인 이유에서 설계되었다는 것을 느꼈습니다. 일단 이해하고 나면 마치 디자이너와 대화하고, 그들의 생각을 이해하고, 그들의 방법을 배우고, 같은 화면에서 생각하는 것처럼 느낄 것입니다.

문제적 사고

1. Consumer Queue Offset이 연속적입니까?이유는 무엇입니까?

2. Commit Log Offset이 연속적인가?이유는?

3. Java로 작성된 파일의 경우 기본값이 big-endian 또는 little-endian인 이유는 무엇입니까?

커밋 로그 실제 분포

모두가 생각하는 동안 커밋 로그가 어떻게 배포되는지 기억해 봅시다.

Broker가 구성한 저장소 루트 디렉터리에서 실제로 Broker가 생성한 커밋 로그 파일을 보면 다음과 같은 데이터 파일 분포를 확인할 수 있습니다.

브로커 실제 데이터 파일 저장 배포

실제 저장 파일이 여러 개 있음을 알 수 있으며, 각각의 파일 이름은 비슷한 숫자의 문자열을 사용하고 크기는 1G입니다.

실제 추상 모델은 다음과 같다는 것을 소스 코드에서 알 수 있습니다.

커밋 로그 저장 파일 배포 추상화

위의 그림에서 다음을 알 수 있습니다.

Commit Log는 파일 클래스의 이름으로 실제로 Commit Log 파일이 많이 있으며 각각 Commit Log 파일이라고 할 수 있습니다. 그림과 같이 총 T Commit Log 파일이 존재하며 과거부터 현재까지 생성된 시간에 따라 정리되어 있다.

각 Commit Log 파일은 메시지를 저장하고, 작성된 순서대로 저장하며, 항상 생성 시간이 가장 긴 파일을 작성하고 동시에 하나의 스레드만 작성합니다. 그림의 첫 번째 파일인 1, 2, 3, 4...는 이 파일에 있는 메시지의 개수를 나타내며, 1234번째 메시지가 첫 번째 Commit Log 파일의 마지막 메시지이고 1235번째 메시지임을 알 수 있다. 두 번째 커밋 로그의 첫 번째 메시지.

참고 1: 각 커밋 로그 파일의 모든 메시지가 차지하는 실제 저장 공간은 <=1G입니다. 이것이 왜 그런지 생각해 봅시다.

설명 2: RocketMQ는 커밋 로그가 기록될 때마다 잠깁니다. 코드 스니펫은 https://github.com/apache/rocketmq/blob/7676cd9366a3297925deabcf27bb590e34648645/store/src/main/java/org/apache/rocketmq/store/ 를 참조하세요. CommitLog.java#L676-L722

잠금 추가

Commit Log 파일에는 정해진 프로토콜에 따라 저장되는 많은 메시지가 있는데, 구체적인 프로토콜은 무엇이며 어떻게 알 수 있나요?

커밋 로그 스토리지 프로토콜

Commit Log 저장 프로토콜에 대해 ChatGPT에 물어봤더니 이렇게 답장이 왔는데, 틀렸지만 이 답글의 형식과 설명이 거의 답에 가깝습니다.

채팅GPT 답장

소스 코드 를 살펴보고 자세히 설명하겠습니다. CommitLog.java #L1547-L1587

커밋 로그 스토리지 프로토콜

정리하고 나니 이렇게 생겼습니다.

내가 이해하는 Commit Log 저장 프로토콜

설명 1: 내가 분류한 메시지 프로토콜의 번호가 코드와 일치하지 않습니다.코드는 순서를 나타낼 뿐이며 실제 물리적 파일의 스토리지 프로토콜은 더 자세히 설명됩니다. 설명 2: 내가 쓴 "RocketMQ 분산 메시지 미들웨어: 핵심 원칙 및 모범 사례"에서 이 그림에는 여기에 추가된 본문 콘텐츠가 부족하고 다른 데이터는 더 자세히 보완됩니다. 설명이 필요한 몇 가지 문제는 다음과 같습니다.

1. 바이너리 프로토콜에는 바이트 순서가 있으며 이를 종종 빅 엔디안 및 리틀 엔디안이라고 합니다. 크고 작은 끝은 여기에서 자세히 설명하지 않습니다.관심 있는 학생들은 Google을 검색하거나 ChatGPT에서 질문할 수 있습니다.답변은 분명히 내가 말한 것보다 낫습니다.

2. java에서 byte는 1byte, int는 4byte, short는 2byte, long은 8byte를 차지한다.

3. 호스트의 인코딩은 단순히 IP:Port를 문자열로 직접 바이트 배열로 변환하는 것이 아니라 각 숫자를 차례로 바이트로 인코딩합니다. 다음 섹션의 Golang 코드에서 설명하겠습니다.

4. 확장 정보의 인코딩에서 보이지 않는 문자를 세그먼테이션으로 사용하므로 확장 필드 키-값은 두 개의 보이지 않는 문자를 포함할 수 없습니다. 둘 중 어떤 건가요? 찾아주세요.

이 계약을 확인한 후 실제 파일이 이 계약에 따라 작성되었음을 어떻게 증명할 수 있습니까?

Golang을 사용하여 RocketMQ 커밋 로그 풀기

RocketMQ는 java로 작성되었으며 위에서 설명한 스토리지 프로토콜에 따라 Commit Log 및 Cosumer Queue를 잠금 해제할 수 있는 도구를 Golang으로 작성했습니다. 코드 주소: https://github.com/rmq-plus-plus/rocketmq -decoder .

이 도구는 현재 2가지 기능을 지원합니다.

1. 커밋 로그 사이트를 지정하고 커밋 로그의 메시지를 직접 구문 분석하고 인쇄합니다.

2. 소비 위치를 지정하고 먼저 소비자 대기열을 구문 분석하고 커밋 로그 오프셋을 가져온 다음 커밋 로그 오프셋에 따라 커밋 로그를 직접 구문 분석하고 인쇄합니다.

Golang에는 RocketMQ에 의존하는 코드가 없으며 프로토콜 디코딩에만 의존합니다.

골랑 가져오기

다음은 golang에서 커밋 로그 오프셋을 구문 분석하는 예입니다. 자바에서 이 오프셋은 8바이트를 차지하는 긴 유형입니다.

golang에서 일반적인 Commit Log Offset은 8바이트 데이터를 읽고 big endian 시퀀스에 따라 int64로 디코딩하여 얻을 수 있습니다.

Golang 데모참조용으로 데모 결과를 실행했습니다.

소비자 대기열 커밋 로그 읽기

원래 질문에 답하다

다음은 참고용으로 제 개인적인 의견입니다.

1. Consumer Queue Offset이 연속적입니까?이유는 무엇입니까?

연속적이다.

소비자 대기열 오프셋은 각 대기열에 있는 인덱스 메시지의 첨자를 나타내며 첨자는 물론 연속적입니다. 소비자는 또한 이러한 연속성을 활용하여 빈 소비 사이트를 제출하지 않도록 합니다.

각 인덱스 메시지는 20바이트로 같은 공간을 차지하며 구조는 다음과 같다.

소비자 대기열 인덱스 메시지 구조

여기서 물리적 위치는 Commit Log Offset입니다.

2. Commit Log Offset이 연속적인가?이유는?

연속되지 않습니다.

Commit Log Offset은 모든 Commit Log 파일에 있는 각 메시지의 바이트 오프셋을 말하며, 각 메시지의 크기는 불확실하므로 Commit Log Offset, 즉 바이트 오프셋이 달라야 합니다.

그리고 두 오프셋의 차이의 절대값은 이전 메시지의 총 메시지 바이트 길이임을 알 수 있다.

그리고 위의 그림 "커밋 로그 저장 파일 배포 추상화"에 오해가 있어 작은 사각형 하나하나의 크기가 실제로 다릅니다.

3. Java로 작성된 파일의 경우 기본값이 big-endian 또는 little-endian인 이유는 무엇입니까?

빅 엔디안. 빅 엔디안은 실제로 바이트 저장 순서와 네트워크 전송 순서가 있으며 자바의 기본 빅 엔디안 순서는 네트워크 전송과 동일하게 유지되므로 인코딩 및 디코딩에 편리합니다.

네트워크 전송 계층의 각 세그먼트에 있는 데이터 메시지의 첫 번째 바이트는 후속 데이터를 전송하는 데 사용되는 프로토콜을 표현하므로 데이터 수신자가 데이터를 수신할 때 먼저 바이트 순서에 따라 프로토콜을 구문 분석한 다음 디코딩합니다. 프로토콜에 따른 후속 데이터 인간이 생각하고 문제를 해결하는 방식과 일치하는 일련의 바이트.

토론 참고 사항解开 : RocketMQ의 일부 버전이 다를 수 있으므로 이 문서에서는 버전 4.9.3에서 설명합니다. 이 방법, 5.0 또는 다른 버전 및 다른 데이터 파일의 스토리지 프로토콜 형식을 참조할 수 있습니다 .

{{o.이름}}
{{이름}}

Supongo que te gusta

Origin my.oschina.net/u/4587289/blog/8806657
Recomendado
Clasificación