다음을 통해 공유


MQTT 브로커 상태 저장소 프로토콜

Important

Azure IoT 작업 미리 보기 - Azure Arc에서 지원되는 Azure IoT 작업은 현재 preview로 제공됩니다. 프로덕션 환경에서는 이 미리 보기 소프트웨어를 사용하면 안 됩니다.

일반적으로 릴리스되는 릴리스가 제공되면 새로운 Azure IoT 작업 설치를 배포해야 합니다. 미리 보기 설치는 업그레이드할 수 없습니다.

베타, 미리 보기로 제공되거나 아직 일반 공급으로 릴리스되지 않은 Azure 기능에 적용되는 약관은 Microsoft Azure 미리 보기에 대한 추가 사용 약관을 참조하세요.

MQ 상태 저장소는 Azure IoT Operations 클러스터 내의 분산 스토리지 시스템입니다. 상태 저장소는 MQTT 브로커의 MQTT 메시지와 동일한 고가용성을 보장합니다. MQTT5/RPC 프로토콜 지침에 따라 클라이언트는 MQTT5를 사용하여 MQ 상태 저장소와 상호 작용해야 합니다. 이 문서에서는 자체 MQTT 브로커 상태 저장소 클라이언트를 구현해야 하는 개발자를 위한 프로토콜 지침을 제공합니다.

상태 저장소 프로토콜 개요

MQ 상태 저장소는 다음 명령을 지원합니다.

  • SET<keyName><keyValue><setOptions>
  • GET<keyName>
  • DEL<keyName>
  • VDEL<keyName><keyValue> ## 해당 값이 <keyValue>인 경우에만 지정된 <keyName>을 삭제합니다.

프로토콜은 다음과 같은 요청-응답 모델을 사용합니다.

  • 요청. 클라이언트는 잘 정의된 상태 저장소 시스템 토픽에 대한 요청을 게시합니다. 요청을 게시하기 위해 클라이언트는 다음 섹션에 설명된 필수 속성과 페이로드를 사용합니다.
  • 응답. 상태 저장소 비동기는 클라이언트가 처음에 제공한 응답 토픽에 대한 요청과 응답을 처리합니다.

다음 다이어그램은 요청 및 응답의 기본 보기를 보여 줍니다.

상태 저장소 기본 요청 및 응답 프로세스를 보여 주는 다이어그램.

상태 저장소 시스템 토픽, QoS 및 필수 MQTT5 속성

상태 저장소와 통신하려면 클라이언트가 다음 요구 사항을 충족해야 합니다.

  • MQTT5를 사용합니다. 자세한 내용은 MQTT 5 사양을 참조하세요.
  • QoS 1(서비스 품질 수준 1)을 사용합니다. QoS 1은 MQTT 5 사양에 설명되어 있습니다.
  • MQTT 브로커 시계의 1분 이내의 시계가 있어야 합니다.

상태 저장소와 통신하려면 클라이언트가 시스템 토픽 statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invoke에 대한 요청을 PUBLISH해야 합니다. 상태 저장소는 Azure IoT Operations의 일부이므로 시작 시 이 토픽에 대해 암시적 SUBSCRIBE를 수행합니다.

요청을 빌드하려면 다음 MQTT5 속성이 필요합니다. 이러한 속성이 없거나 요청이 QoS 1 형식이 아닌 경우 요청이 실패합니다.

  • 응답 토픽. 상태 저장소는 이 값을 사용하여 초기 요청에 응답합니다. 가장 좋은 방법은 응답 토픽의 형식을 clients/{clientId}/services/statestore/_any_/command/invoke/response로 지정하는 것입니다. 응답 토픽을 statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invoke 또는 clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8로 시작하는 토픽으로 설정하는 것은 상태 저장소 요청에서 허용되지 않습니다. 상태 저장소는 잘못된 응답 토픽을 사용하는 MQTT 클라이언트의 연결을 끊습니다.
  • 상관 관계 데이터. 상태 저장소가 응답을 보낼 때 초기 요청의 상관 관계 데이터가 포함됩니다.

다음 다이어그램은 요청 및 응답의 확장된 보기를 보여 줍니다.

상태 저장소 확장 요청 및 응답 프로세스를 보여 주는 다이어그램.

지원되는 명령

SET, GETDEL 명령이 예상대로 작동합니다.

SET 명령이 설정하는 값과 GET 명령이 검색하는 값은 임의의 이진 파일 데이터입니다. 값의 크기는 최대 MQTT 페이로드 크기와 MQ 및 클라이언트의 리소스 제한 사항에 의해서만 제한됩니다.

SET 옵션

SET 명령은 기본 keyValuekeyName 외에 더 많은 선택적 플래그를 제공합니다.

  • NX. 키가 아직 존재하지 않는 경우에만 키를 설정할 수 있습니다.
  • NEX <value>. 키가 존재하지 않거나 키 값이 이미 <값>로 설정된 경우에만 키를 설정할 수 있습니다. NEX 플래그는 일반적으로 키의 만료(PX)를 갱신하는 클라이언트에 사용됩니다.
  • PX. 키가 만료되기 전에 지속되어야 하는 시간(밀리초)입니다.

VDEL 옵션

VDEL 명령은 DEL 명령의 특별한 경우입니다. DEL은 지정된 keyName을 무조건 삭제합니다. VDEL에는 keyValue라는 또 다른 인수가 필요합니다. VDEL은 동일한 keyValue가 있는 경우 지정된 keyName만 삭제합니다.

페이로드 형식

상태 저장소 PUBLISH 페이로드 형식은 Redis가 사용하는 기본 프로토콜인 RESP3에서 영감을 받았습니다. RESP3은 SET 또는 GET과 같은 동사와 keyNamekeyValue와 같은 매개 변수를 모두 인코딩합니다.

대/소문자 구분

클라이언트는 동사와 옵션을 모두 대문자로 보내야 합니다.

요청 형식

요청의 형식은 다음 예와 같습니다. RESP3 다음의 *은 배열의 항목 수를 나타냅니다. $ 문자는 후행 CRLF를 제외한 다음 줄의 문자 수입니다.

RESP3 형식으로 지원되는 명령은 GET, SET, DELVDEL입니다.

*{NUMBER-OF-ARGUMENTS}<CR><LF>
${LENGTH-OF-NEXT-LINE}<CR><LF>
{COMMAND-NAME}<CR><LF>
${LENGTH-OF-NEXT-LINE}<CR><LF> // This is always the keyName with the current supported verbs.
{KEY-NAME}<CR><LF>
// Next lines included only if command has additional arguments
${LENGTH-OF-NEXT-LINE}<CR><LF> // This is always the keyValue for set
{KEY-VALUE}<CR><LF>

다음 출력 예는 상태 저장소 RESP3 페이로드를 보여 줍니다.

*3<CR><LF>$3<CR><LF>set<CR><LF>$7<CR><LF>SETKEY2<CR><LF>$6<CR><LF>VALUE5<CR><LF>
*2<CR><LF>$3<CR><LF>get<CR><LF>$7<CR><LF>SETKEY2<CR><LF>
*2<CR><LF>$3<CR><LF>del<CR><LF>$7<CR><LF>SETKEY2<CR><LF>
*3<CR><LF>$4<CR><LF>vdel<CR><LF>$7<CR><LF>SETKEY2<CR><LF>$3<CR><LF>ABC<CR><LF>

참고 항목

버전 관리 및 하이브리드 논리 시계 섹션에 설명된 대로 SET에는 추가 MQTT5 속성이 필요합니다.

응답 형식

상태 저장소가 잘못된 RESP3 페이로드를 검색하면 여전히 요청자의 Response Topic에 대한 응답을 반환합니다. 잘못된 페이로드의 예로는 잘못된 명령, 잘못된 RESP3 또는 정수 오버플로가 있습니다. 잘못된 페이로드는 -ERR 문자열로 시작하며 자세한 내용을 포함합니다.

참고 항목

존재하지 않는 키에 대한 GET, DEL 또는 VDEL 요청은 오류로 간주되지 않습니다.

클라이언트가 잘못된 페이로드를 보내는 경우 상태 저장소는 다음 예와 같은 페이로드를 보냅니다.

-ERR syntax error

SET 응답

SET 요청이 성공하면 상태 저장소는 다음 페이로드를 반환합니다.

+OK<CR><LF>

키를 설정할 수 없음을 의미하는 NX 또는 NEX 집합 옵션에 지정된 조건 검사로 인해 SET 요청이 실패하면 상태 저장소는 다음 페이로드를 반환합니다.

-1<CR><LF>

GET 응답

존재하지 않는 키에 대해 GET 요청이 이루어지면 상태 저장소는 다음 페이로드를 반환합니다.

$-1<CR><LF>

키가 발견되면 상태 저장소는 다음 형식으로 값을 반환합니다.

${NumberOfBytes}<CR><LF>
{KEY-VALUE}

1234 값을 반환하는 상태 저장소의 출력은 다음 예와 같습니다.

$4<CR><LF>1234<CR><LF>

DELVDEL 응답

상태 저장소는 삭제 요청 시 삭제한 값의 수를 반환합니다. 현재 상태 저장소는 한 번에 하나의 값만 삭제할 수 있습니다.

:{NumberOfDeletes}<CR><LF> // Will be 1 on successful delete or 0 if the keyName is not present

다음 출력은 성공적인 DEL 명령의 예입니다.

:1<CR><LF>

지정된 값이 키와 연결된 값과 일치하지 않아 VDEL 요청이 실패하면 상태 저장소는 다음 페이로드를 반환합니다.

-1<CR><LF>

-ERR 응답

다음은 현재 오류 문자열 목록입니다. 클라이언트 애플리케이션은 상태 저장소에 대한 업데이트를 지원하기 위해 알 수 없는 오류 문자열을 처리해야 합니다.

상태 저장소에서 반환된 오류 문자열 설명
요청된 타임스탬프가 나중에 너무 멀리 있습니다. 클라이언트 및 브로커 시스템 클록이 동기화되었는지 확인합니다. 상태 저장소 및 클라이언트 시계로 인해 예기치 않은 요청된 타임스탬프가 동기화되지 않습니다.
이 요청에는 펜싱 토큰이 필요합니다. 키가 펜싱 토큰으로 표시되지만 클라이언트가 펜싱 토큰을 지정하지 않으면 오류가 발생합니다.
요청된 펜싱 토큰 타임스탬프가 앞으로 너무 멀리 있습니다. 클라이언트 및 브로커 시스템 클록이 동기화되었는지 확인합니다. 상태 저장소 및 클라이언트 클록으로 인한 예기치 않은 펜싱 토큰 타임스탬프가 동기화되지 않습니다.
요청된 펜싱 토큰은 리소스를 보호하는 펜싱 토큰의 하위 버전입니다. 요청된 펜싱 토큰 버전이 잘못되었습니다. 자세한 내용은 [버전 관리 및 하이브리드 논리 시계]를 참조하세요. (#versioning 및 하이브리드 논리 시계)
할당량을 초과했습니다. 상태 저장소에는 지정된 MQTT 브로커의 메모리 프로필을 기반으로 저장할 수 있는 키 수에 대한 할당량이 있습니다.
구문 오류 전송된 페이로드는 상태 저장소의 정의를 준수하지 않습니다.
권한이 없음 권한 부여 오류
알 수 없는 명령 명령이 인식되지 않습니다.
잘못된 인수 수 예상 인수의 수가 잘못되었습니다.
누락된 타임스탬프 클라이언트가 SET를 수행하는 경우 MQTT5 사용자 속성 __ts 해당 타임스탬프를 나타내는 HLC로 설정해야 합니다.
잘못된 형식의 타임스탬프 __ts 또는 펜싱 토큰의 타임스탬프는 합법적이지 않습니다.
키 길이가 0입니다. 키는 상태 저장소에서 길이가 0일 수 없습니다.

버전 관리 및 하이브리드 논리 시계

이 섹션에서는 상태 저장소가 버전 관리를 처리하는 방법을 설명합니다.

하이브리드 논리 시계 버전

상태 저장소는 저장하는 각 값에 대한 버전을 유지합니다. 상태 저장소는 버전을 유지하기 위해 단조롭게 증가하는 카운터를 사용할 수 있습니다. 대신 상태 저장소는 HLC(하이브리드 논리 시계)를 사용하여 버전을 나타냅니다. 자세한 내용은 HLC의 원래 디자인HLC의 의도에 대한 문서를 참조하세요.

상태 저장소는 다음 형식을 사용하여 HLC를 정의합니다.

{wallClock}:{counter}:{node-Id}

wallClock는 Unix epoch 이후의 밀리초 수입니다. counternode-Id는 일반적으로 HLC로 작동합니다.

클라이언트는 SET를 수행할 때 클라이언트의 현재 시간을 기반으로 MQTT5 사용자 속성 __ts를 해당 타임스탬프를 나타내는 HLC로 설정해야 합니다. 상태 저장소는 응답 메시지에 값의 버전을 반환합니다. 응답도 HLC로 지정되며 __ts MQTT5 사용자 속성도 사용합니다. 반환된 HLC는 항상 초기 요청의 HLC보다 큽니다.

값 버전 설정 및 검색의 예

이 섹션에서는 값의 버전을 설정하고 가져오는 예를 보여 줍니다.

클라이언트가 keyName=value를 설정합니다. 클라이언트 시계는 10월 3일 오후 11시 7분 5초(GMT)입니다. 시계 값은 Unix epoch 이후 1696374425000밀리초입니다. 상태 저장소의 시스템 클록이 클라이언트 시스템 시계과 동일하다고 가정합니다. 클라이언트는 이전에 설명한 대로 SET 명령을 수행합니다.

다음 다이어그램은 SET 명령을 보여 줍니다.

값의 버전을 설정하는 상태 저장소 명령을 보여 주는 다이어그램.

초기 집합의 __ts(타임스탬프) 속성에는 클라이언트 실제 수행 시간(Wall Clock) 1696374425000, 카운터 0, 해당 노드 ID CLIENT가 포함됩니다. 응답에서 상태 저장소가 반환하는 __ts 속성에는 wallClock, 1씩 증가하는 카운터, StateStore의 노드 ID가 포함됩니다. 상태 저장소는 HLC 업데이트 작동 방식에 따라 시계가 앞선 경우 더 높은 wallClock 값을 반환할 수 있습니다.

이 버전은 성공적인 GET, DELVDEL 요청에서도 반환됩니다. 이러한 요청에서 클라이언트는 __ts를 지정하지 않습니다.

다음 다이어그램은 GET 명령을 보여 줍니다.

값의 버전을 가져오는 상태 저장소의 다이어그램.

참고 항목

상태 저장소가 반환하는 타임스탬프 __ts는 첫 SET 요청에서 반환된 것과 동일합니다.

지정된 키가 나중에 새 SET로 업데이트되는 경우 프로세스는 유사합니다. 클라이언트는 현재 시계를 기준으로 요청 __ts를 설정해야 합니다. 상태 저장소는 HLC 업데이트 규칙에 따라 값의 버전을 업데이트하고 __ts를 반환합니다.

클록 스큐

상태 저장소는 상태 저장소의 로컬 시계보다 1분 이상 빠른 __ts(및 __ft)도 거부합니다.

상태 저장소는 상태 저장소 로컬 시계 뒤에 있는 __ts를 허용합니다. HLC 알고리즘에 지정된 대로 상태 저장소는 키 버전을 로컬 시계보다 높기 때문에 해당 로컬 시계로 설정합니다.

잠금 및 펜싱 토큰

이 섹션에서는 잠금 및 펜싱 토큰의 목적과 사용법을 설명합니다.

배경

상태 저장소를 사용하는 MQTT 클라이언트가 두 개 이상 있다고 가정합니다. 두 클라이언트 모두 지정된 키에 쓰기를 원합니다. 상태 저장소 클라이언트에는 한 번에 하나의 클라이언트만 특정 키를 수정할 수 있도록 키를 잠그는 메커니즘이 필요합니다.

이 시나리오의 예는 활성 및 대기 시스템에서 발생합니다. 동일한 작업을 수행하는 두 개의 클라이언트가 있을 수 있으며 작업에는 동일한 상태 저장소 키 집합이 포함될 수 있습니다. 지정된 시간에 클라이언트 중 하나는 활성 상태이고 다른 하나는 활성 시스템이 중단되거나 충돌하는 경우 즉시 인계받기 위해 대기합니다. 이상적으로는 지정된 시간에 하나의 클라이언트만 상태 저장소에 써야 합니다. 그러나 분산 시스템에서는 두 클라이언트가 모두 활성 상태인 것처럼 동작하고 동시에 동일한 키에 쓰려고 시도할 수 있습니다. 이 시나리오에서는 경쟁 조건이 발생합니다.

상태 저장소는 펜싱 토큰을 사용하여 이러한 경합 상태를 방지하는 메커니즘을 제공합니다. 펜싱 토큰 및 이를 방지하도록 설계된 경쟁 조건 클래스에 대한 자세한 내용은 이 문서를 참조하세요.

펜싱 토큰 획득

이 예에서는 다음 요소가 있다고 가정합니다.

  • Client1Client2. 이러한 클라이언트는 활성 및 대기 쌍으로 작동하는 상태 저장소 클라이언트입니다.
  • LockName. 잠금 역할을 하는 상태 저장소의 키 이름입니다.
  • ProtectedKey. 여러 작성자로부터 보호해야 하는 키입니다.

클라이언트는 첫 번째 단계로 잠금을 가져오려고 시도합니다. SET LockName {CLIENT-NAME} NEX PX {TIMEOUT-IN-MILLISECONDS}를 수행하여 잠금을 가져옵니다. 옵션 설정에서 NEX 플래그는 다음 조건 중 하나가 충족되는 경우에만 SET가 성공한다는 것을 의미합니다.

  • 키가 비어 있습니다.
  • 키 값은 이미 <값>으로 설정되어 있으며 PX는 시간 제한을 밀리초 단위로 지정합니다.

Client1SET LockName Client1 NEX PX 10000 요청과 함께 먼저 진행된다고 가정합니다. 이 요청은 10,000밀리초 동안 LockName의 소유권을 부여합니다. Client1이 잠금을 소유하고 있는 동안 Client2SET LockName Client2 NEX ...를 시도하는 경우, NEX 플래그는 Client2 요청이 실패했음을 의미합니다. Client1이 소유권을 계속 유지하려는 경우 Client1은 잠금을 획득하는 데 사용된 것과 동일한 SET 명령을 전송하여 이 잠금을 갱신해야 합니다.

참고 항목

SET NX는 개념적으로 AcquireLock()과 동등합니다.

SET 요청에 펜싱 토큰 사용

Client1LockName에서 SET("AquireLock")를 성공적으로 수행하면 상태 저장소는 MQTT5 사용자 속성 __ts의 HLC(하이브리드 논리 시계)로 LockName 버전을 반환합니다.

클라이언트가 SET 요청을 수행할 때 필요에 따라 MQTT5 사용자 속성 __ft를 포함하여 "펜싱 토큰"을 나타낼 수 있습니다. __ft은 HLC로 표시됩니다. 특정 키-값 쌍과 연결된 펜싱 토큰은 잠금 소유권 확인을 제공합니다. 펜싱 토큰은 어디에서나 가져올 수 있습니다. 이 시나리오의 경우 LockName 버전에서 가져와야 합니다.

다음 다이어그램은 Client1LockName에서 SET 요청을 수행하는 프로세스를 보여 줍니다.

잠금 이름 속성에 대한 집합 요청을 수행하는 클라이언트를 보여 주는 다이어그램.

다음으로, Client1은 수정되지 않은 __ts 속성(Property=1696374425000:1:StateStore)을 ProtectedKey 수정 요청에서 __ft 속성의 기초로 사용합니다. 모든 SET 요청과 마찬가지로 클라이언트는 ProtectedKey__ts 속성을 설정해야 합니다.

다음 다이어그램은 Client1ProtectedKey에서 SET 요청을 수행하는 프로세스를 보여 줍니다.

보호된 키 속성에 대한 집합 요청을 수행하는 클라이언트를 보여 주는 다이어그램.

요청이 성공하면 이 시점부터 ProtectedKeySET 요청에 지정된 것과 같거나 큰 펜싱 토큰이 필요합니다.

펜싱 토큰 알고리즘

상태 저장소는 값이 최대 시계 기울이기 내에 있는 경우 키-값 쌍의 __ts에 대한 HLC를 허용합니다. 그러나 펜싱 토큰의 경우에는 그렇지 않습니다.

펜싱 토큰의 상태 저장소 알고리즘은 다음과 같습니다.

  • 키-값 쌍에 연결된 펜싱 토큰이 없고 SET 요청이 __ft을 설정하는 경우 상태 저장소는 연결된 __ft을 키-값 쌍과 함께 저장합니다.
  • 키-값 쌍에 펜싱 토큰이 연결된 경우:
    • SET 요청이 __ft을 지정하지 않은 경우 요청을 거부합니다.
    • SET 요청이 키-값 쌍과 연결된 펜싱 토큰보다 오래된 HLC 값을 가진 __ft을 지정한 경우 요청을 거부합니다.
    • SET 요청이 키-값 쌍과 연결된 펜싱 토큰과 같거나 더 새로운 HLC 값을 갖는 __ft을 지정한 경우 요청을 수락합니다. 상태 저장소는 키-값 쌍의 펜싱 토큰이 최신인 경우 요청에 설정된 토큰으로 업데이트합니다.

키가 펜싱 토큰으로 표시된 후 요청이 성공하려면 DELVDEL 요청에 __ft 속성도 포함되어야 합니다. 키가 삭제되기 때문에 펜싱 토큰이 저장되지 않는다는 점을 제외하면 알고리즘은 이전 알고리즘과 동일합니다.

클라이언트 동작

이러한 잠금 메커니즘은 클라이언트의 올바른 행동에 의존합니다. 이전 예에서 오작동하는 Client2LockName을 소유할 수 없지만 ProtectedKey 토큰보다 최신 펜싱 토큰을 선택하여 SET ProtectedKey를 성공적으로 수행할 수 없습니다. 상태 저장소는 LockNameProtectedKey가 관계가 있다는 것을 인식하지 못합니다. 결과적으로 상태 저장소는 Client2가 실제로 값을 소유하는지 유효성을 검사를 수행하지 않습니다.

클라이언트가 실제로 잠금을 소유하지 않은 키를 쓸 수 있는 것은 바람직하지 않은 동작입니다. 클라이언트를 올바르게 구현하고 인증을 사용하여 신뢰할 수 있는 클라이언트로만 키에 대한 액세스를 제한함으로써 이러한 클라이언트 오작동으로부터 보호할 수 있습니다.

알림

클라이언트는 상태 저장소에 등록하여 수정 중인 키에 대한 알림을 받을 수 있습니다. 자동 온도 조절기에서 상태 저장소 키 {thermostatName}\setPoint를 사용하는 시나리오를 생각해 보세요. 다른 상태 저장소 클라이언트는 이 키의 값을 변경하여 자동 온도 조절기의 setPoint를 변경할 수 있습니다. 자동 온도 조절기는 변경 사항을 폴링하는 대신 상태 저장소에 등록하여 {thermostatName}\setPoint가 수정될 때 메시지를 받을 수 있습니다.

KEYNOTIFY 요청 메시지

상태 저장소 클라이언트는 KEYNOTIFY 메시지를 전송하여 상태 저장소 모니터에 지정된 keyName의 변경 사항을 요청합니다. 모든 상태 저장소 요청과 마찬가지로 클라이언트는 MQTT5를 통해 이 메시지와 함께 QoS1 메시지를 상태 저장 시스템 토픽 statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invoke에 게시(PUBLISH)합니다.

요청 페이로드의 형식은 다음과 같습니다.

KEYNOTIFY<CR><LF>
{keyName}<CR><LF>
{optionalFields}<CR><LF>

여기서

  • KEYNOTIFY는 명령을 지정하는 문자열 리터럴입니다.
  • {keyName}은 알림을 수신 대기할 키 이름입니다. 와일드카드는 현재 지원되지 않습니다.
  • {optionalFields} 현재 지원되는 선택 사항 필드 값은 다음과 같습니다.
    • {STOP} 이 요청과 동일한 keyNameclientId가 포함된 기존 알림이 있는 경우 상태 저장소는 이를 제거합니다.

다음 예시 출력은 SOMEKEY 키를 모니터링하는 KEYNOTIFY 요청을 보여줍니다.

*2<CR><LF>
$9<CR><LF>
KEYNOTIFY<CR><LF>
$7<CR><LF>
SOMEKEY<CR><LF>

KEYNOTIFY 응답 메시지

모든 상태 저장소 RPC 요청과 마찬가지로 상태 저장소는 Response Topic에 대한 응답을 반환하고 첫 요청에서 지정된 Correlation Data 속성을 사용합니다. KEYNOTIFY의 경우 성공적인 응답은 상태 저장소가 요청을 처리했음을 나타냅니다. 상태 저장소가 요청을 성공적으로 처리한 후에는 현재 클라이언트에 대한 키를 모니터링하거나 모니터링을 중지합니다.

성공 시 상태 저장소의 응답은 성공적인 SET와 동일합니다.

+OK<CR><LF>

클라이언트가 KEYNOTIFY SOMEKEY STOP 요청을 전송하지만 상태 저장소가 해당 키를 모니터링하지 않는 경우 상태 저장소의 응답은 존재하지 않는 키를 삭제하려고 시도하는 것과 같습니다.

:0<CR><LF>

다른 오류는 상태 저장소의 일반 오류 보고 패턴을 따릅니다.

-ERR: <DESCRIPTION OF ERROR><CR><LF>

KEYNOTIFY 알림 토픽 및 수명 주기

KEYNOTIFY를 통해 모니터링되는 keyName이 수정되거나 삭제되면 상태 저장소는 클라이언트에 알림을 보냅니다. 토픽은 규칙에 따라 결정됩니다. 클라이언트는 KEYNOTIFY 프로세스 중에 토픽을 지정하지 않습니다.

토픽은 다음 예에서 정의됩니다. clientIdKEYNOTIFY 요청을 시작한 클라이언트의 MQTT ClientId를 대문자 16진수로 인코딩한 표현이고 keyName은 변경된 키를 16진수로 인코딩한 표현입니다.

clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/{clientId}/command/notify/{keyName}

예를 들어 MQ는 수정된 키 이름 SOMEKEY를 사용하여 client-id1에 전송된 NOTIFY 메시지를 토픽에 게시합니다.

clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/636C69656E742D696431/command/notify/534F4D454B4559`

알림을 사용하는 클라이언트는 메시지가 손실되지 않도록 KEYNOTIFY 요청을 보내기 에 이 토픽을 SUBSCRIBE하고 SUBACK이 수신될 때까지 기다려야 합니다.

클라이언트의 연결이 끊어지면 KEYNOTIFY 알림 토픽을 다시 구독하고 계속 모니터링해야 하는 키에 대해 KEYNOTIFY 명령을 다시 보내야 합니다. 비정리 세션 전반에 걸쳐 지속될 수 있는 MQTT 구독과 달리 상태 저장소는 지정된 클라이언트 연결이 끊어지면 모든 KEYNOTIFY 메시지를 내부적으로 제거합니다.

KEYNOTIFY 알림 메시지 형식

KEYNOTIFY를 통해 모니터링되는 키가 수정되면 상태 저장소는 변경 등록된 상태 저장소 클라이언트에 대한 형식에 따라 알림 토픽에 메시지를 PUBLISH합니다.

NOTIFY<CR><LF>
{operation}<CR><LF>
{optionalFields}<CR><LF>

메시지에 포함되는 세부 정보는 다음과 같습니다.

  • NOTIFY는 페이로드의 첫 번째 인수로 포함된 문자열 리터럴로, 알림이 도착했음을 나타냅니다.
  • {operation}은 발생한 이벤트입니다. 현재 이러한 작업에는 다음이 있습니다.
    • SET 값이 수정되었습니다. 이 작업은 상태 저장소 클라이언트의 SET 명령 결과로만 발생할 수 있습니다.
    • DEL 값이 삭제되었습니다. 이 작업은 상태 저장소 클라이언트의 DEL 또는 VDEL 명령으로 인해 발생할 수 있습니다.
  • optionalFields
    • VALUE{MODIFIED-VALUE}. VALUE는 다음 필드인 {MODIFIED-VALUE}에 키가 변경된 값이 포함되어 있음을 나타내는 문자열 리터럴입니다. 이 값은 으로 인해 SET수정되는 키에 대한 응답으로만 전송됩니다.

다음 예시 출력은 첫 요청에서 GET 옵션을 지정했기 때문에 SOMEKEY 키가 abc 값으로 수정되고 VALUE가 포함된 경우 전송되는 알림 메시지를 보여줍니다.

*4<CR><LF>
$6<CR><LF>
NOTIFY<CR><LF>
$3<CR><LF>
SET<CR><LF>
$5<CR><LF>
VALUE<CR><LF>
$3<CR><LF>
abc<CR><LF>