라이트 주제 만들기 및 관리

이 문서에서는 Pub/Sub Lite 주제를 생성, 확인, 삭제하는 방법을 설명합니다.

라이트 주제 개요

Pub/Sub Lite 서비스는 구독자가 메시지를 수신할 수 있도록 게시자가 메시지를 전송할 수 있는 주제가 필요합니다. Pub/Sub Lite 내에서는 영역 또는 리전 라이트 주제를 만들 수 있습니다.

영역 라이트 및 리전 라이트 주제는 데이터 복제 방식에서만 차이가 있습니다. 다른 주제 속성은 이 문서의 뒷부분에서 설명한 것과 동일합니다.

라이트 주제에서 데이터 복제

Pub/Sub 라이트 리전 주제는 단일 리전의 두 영역에 데이터를 저장합니다. Pub/Sub 라이트 영역 주제는 단일 영역 내에서만 데이터를 복제합니다. Pub/Sub 라이트는 데이터를 비동기식으로 복제합니다.

Pub/Sub 라이트의 가용성은 애플리케이션 프런트엔드 및 스토리지가 모두 포함된 기본 구성요소의 가용성에 따라 달라집니다.

Pub/Sub Lite 영역 주제의 가용성은 구성된 영역에서의 애플리케이션 프런트엔드 및 스토리지의 가용성에 따라 달라집니다. 애플리케이션 프런트엔드 또는 스토리지에 영역 오류가 발생하면 중단 기간 동안 영역 라이트 주제를 사용할 수 없습니다.

Pub/Sub Lite 리전 주제의 가용성은 구성된 리전에서 애플리케이션 프런트엔드 및 스토리지의 가용성에 따라 달라집니다. 다음 유형의 오류가 발생할 수 있습니다.

  • 애플리케이션 프런트엔드 또는 스토리지에 영역 오류가 발생해도 리전 라이트 주제는 사용 가능한 상태로 유지됩니다.

  • 애플리케이션 프런트엔드와 스토리지 모두 영역 오류가 발생하면 두 구성요소 모두 동시에 중단되지 않는 한 리전 라이트 주제가 사용 가능한 상태로 유지됩니다.

  • 애플리케이션 프런트엔드와 스토리지 모두 동시에 중단되면 해당 중단 기간 동안 리전 라이트 주제를 사용할 수 없습니다. 이 시간 중에는 클라이언트가 메시지를 게시하거나 소비하지 못할 수 있지만 여전히 올바른 순서로 메시지가 전달됩니다.

리전 라이트 주제는 대부분의 단일 영역 오류 유형에 대한 보호 기능을 제공합니다. 하지만 드물지만 일부 경우에는 복제의 비동기식 특성으로 인해 단일 영역에서 여러 구성요소에 대한 동시 오류가 발생할 수 있습니다. 따라서 리전 라이트 주제를 사용할 수 없게 됩니다.

라이트 주제의 속성

라이트 주제에는 다음과 같은 속성이 있습니다.

  • 파티션 개수. 파티션이란 Pub/Sub Lite에서 동시 로드의 기본 단위입니다. 라이트 주제는 하나 이상의 파티션을 포함할 수 있습니다.

  • 파티션 용량. 파티션 용량은 다음 세 가지 속성으로 기술됩니다.

    • 게시 처리량(MiBps). 메시지를 게시할 수 있는 최대 속도입니다.

    • 구독 처리량(MiBps). 메시지가 라이트 구독으로 전달되는 최대 속도입니다.

    • 스토리지(GiB). 파티션의 최대 메시지 크기입니다. 파티션의 최소 구성 가능 용량은 30GiB입니다.

  • 라이트 주제의 스토리지 용량. 라이트 주제의 모든 파티션은 동일하게 구성된 스토리지 용량을 갖습니다. 라이트 주제의 총 스토리지 용량은 해당 주제에서 총 파티션의 스토리지 용량 합계입니다. 예를 들어 라이트 주제에 8개 파티션이 있고 각 파티션 크기가 30GiB이면 라이트 주제의 총 스토리지 용량은 240GiB(8 x 30)입니다.

  • 라이트 주제의 처리량 용량. 처리량 용량은 라이트 주제에 있는 모든 파티션의 총 게시 및 구독 처리량 용량으로 구성됩니다. 모두 합해서 1GiBps의 게시 처리량을 지원할 수 있는 주제가 있더라도 실제로 처리량을 제한하는 것은 파티션별 게시 한도입니다.

  • 구독자 클라이언트 및 구독 한도. Pub/Sub Lite는 단일 파티션 및 단일 구독에 대한 단일 구독자 클라이언트를 지원합니다. 예를 들어 파티션이 5개 있는 주제에 대한 구독은 여기에서 메시지를 소비하는 구독자 클라이언트를 최대 5개까지만 포함할 수 있습니다. 구독자 클라이언트를 더 많이 구성하면, 여분의 클라이언트가 유휴 상태로 유지됩니다. 동일한 주제에 구독이 2개면 각 구독당 5개 클라인트씩 총 10개의 구독자 클라이언트가 포함될 수 있습니다.

  • 예약. 예약은 여러 주제에 대해 처리량 용량을 프로비저닝하고 관리할 수 있는 가장 쉬운 방법입니다. 예약을 통한 처리량 용량 프로비저닝은 리전 라이트의 경우 필수이고 영역 라이트 주제의 경우 선택사항입니다.

    영역 라이트 주제에 예약을 사용하지 않을 경우에는 주제에 대해 게시 및 구독 처리량 용량을 명시적으로 프로비저닝해야 합니다. 예약이 없으면 라이트 주제의 모든 파티션에 동일한 처리량 용량이 구성됩니다. 자세한 내용은 예약 없이 처리량 용량 구성을 참조하세요.

  • 스토리지 구성. 스토리지를 구성하려면 스토리지 용량과 선택사항인 메시지 보관 기간은 모두 지정해야 합니다.

    • 메시지 보관 기간. 라이트 주제가 메시지를 저장하는 최대 기간입니다. 메시지 보관 기간을 지정하지 않으면 스토리지 용량을 초과할 때까지 라이트 주제에 메시지가 저장됩니다.

    • 스토리지 용량. Pub/Sub Lite 주제 용량은 주제의 파티션 수와 각 파티션의 스토리지 용량에 따라 결정됩니다. 파티션당 스토리지는 각 파티션의 스토리지(바이트)입니다. 리전 라이트 주제는 게시된 각 바이트당 2바이트의 스토리지를 사용합니다. 영역 라이트 주제는 게시된 각 바이트당 1바이트의 스토리지를 사용합니다.

    스토리지 용량을 초과하는 경우 Pub/Sub Lite 서비스가 메시지를 계속 게시합니다. 하지만 더 많은 스토리지 용량을 만들기 위해 파티션에서 가장 오래된 메시지가 삭제됩니다. 메시지가 메시지 보관 기간 내에 있더라도 가장 오래된 메시지 삭제가 수행됩니다. 새로 게시되는 메시지의 공간 확보를 위해 제거가 필요한 경우가 아닌 한 TTL이 만료되기 전에는 서비스에서 메시지가 삭제되지 않습니다. 용량 가격에 대한 자세한 내용은 Pub/Sub Lite 가격 책정을 참조하세요.

주제 이름 지정 가이드라인

Pub/Sub 라이트 리소스 이름은 주제, 구독, 예약과 같은 Pub/Sub 라이트 리소스를 고유하게 식별합니다. 리소스 이름은 다음 형식이어야 합니다.

projects/project-identifier/collection/ID

  • project-identifier: Google Cloud 콘솔에서 사용 가능한 프로젝트 ID 또는 프로젝트 번호여야 합니다. 예를 들어 my-cool-project는 프로젝트 ID입니다. 123456789123은 프로젝트 번호입니다.

  • collection: topics, subscriptions, reservations 중 하나여야 합니다.

  • ID: 다음 가이드라인을 준수하세요.

    • goog 문자열로 시작하지 않도록 합니다.
    • 문자로 시작합니다.
    • 3~255자여야 합니다.
    • 다음 문자(글자 [A-Za-z], 숫자 [0-9], 대시 -, 밑줄 _, 마침표 ., 물결표 ~, 더하기 기호 +, 퍼센트 기호 %)만 포함해야 합니다.

    URL로 인코딩하지 않고 리소스 이름에 이전 목록의 특수문자를 사용할 수 있습니다. 하지만 다른 특수문자를 URL에 사용하는 경우 올바르게 암호화되거나 디코딩되었는지 확인해야 합니다. 예를 들어 mi-tópico는 잘못된 ID입니다. 그러나 mi-t%C3%B3pico는 유효합니다. 이 형식은 REST를 호출할 때 중요합니다.

라이트 주제의 처리량 용량 증가

라이트 예약을 사용하지 않는 경우 영역 라이트 주제의 각 파티션의 처리량 용량을 다음 한도로 설정된 값으로 설정할 수 있습니다.

  • 4~16MiBps 사이의 게시 처리량

  • 4~32MiBps 사이의 구독 처리량

이러한 한도는 라이트 예약과 연결된 파티션에도 적용됩니다. 예약을 사용할 경우 각 파티션에서 예약의 총 용량이 초과되지 않는 한 지정된 한도 내에서 모든 처리 용량을 사용할 수 있습니다. 선택적으로 파티션당 실제 처리량 한도를 낮게 설정해서 트래픽을 더 예측 가능하게 만들 수 있습니다.

수평 확장을 위해서는 주제에서 파티션 수를 늘릴 수 있습니다. 주제의 파티션 수는 줄일 수 없습니다.

파티션 수를 변경해도 메시지의 상대적 순서는 유지되지 않습니다. 내부적으로 메시지는 해시 함수를 사용하여 파티션에 할당됩니다. 주제에서 파티션 수를 업데이트하면 이 해시 함수가 변경됩니다. 파티션 수 업데이트 후 게시된 동일한 키를 가진 메시지는 업데이트 전에 게시된 것과 다른 파티션에 매핑될 수 있습니다.

또한 주제 크기 조정이 모든 게시자에 전달되는 데 몇 초 정도 걸립니다. 잠시 동안은 일부 게시자에 새 해시 함수가 사용되고 일부에서는 여전히 이전 항목이 사용됩니다.

라이트 주제의 스토리지 용량 늘리기

라이트 주제에서 스토리지를 늘리거나 줄일 수도 있습니다. 라이트 주제는 각 파티션에 동일한 양의 스토리지를 프로비저닝합니다. 스토리지를 60 GiB로 늘리면 각 파티션은 60 GiB의 스토리지를 얻게 됩니다.

라이트 주제의 스토리지 용량을 줄이면 Pub/Sub Lite 서비스가 가장 오래된 메시지를 먼저 삭제합니다.

용량 가격에 대한 자세한 내용은 Pub/Sub Lite 가격 책정을 참조하세요.

라이트 주제 만들기

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub Lite API를 사용하여 라이트 주제를 만들 수 있습니다.

사용 가능한 리전 및 영역 목록은 Pub/Sub 라이트 위치를 참조하세요.

콘솔

  1. 라이트 주제 페이지로 이동합니다.

    라이트 주제로 이동

  2. 라이트 주제 만들기를 클릭합니다.

    1. 영역 라이트 주제를 만들려면 리전과 리전 내에서 영역을 선택합니다.

    2. 영역 라이트 주제를 만들기 위해 리전을 선택합니다.

    주제가 생성된 후에는 위치를 업데이트할 수 없습니다.

  3. 이름 섹션에서 라이트 주제 ID를 입력합니다.

    라이트 주제 이름에는 라이트 주제 ID, 위치, 프로젝트 번호가 포함됩니다.

  4. 처리량 섹션에서 다음을 수행합니다.

    1. 예약을 선택하거나 만듭니다.

      이는 영역 라이트 주제의 경우 선택사항이며 리전 라이트 주제의 경우 필수입니다.

    2. 최대 게시 처리량과 최대 구독 처리량을 입력합니다.

      입력에 따라 파티션 수가 자동으로 설정됩니다. 주제를 저장한 후 이 숫자를 수정할 수 있습니다.

  5. 메시지 스토리지 섹션에서 다음을 수행합니다.

    1. 파티션당 스토리지를 입력합니다.

    2. 메시지 보관 기간에 대해 두 옵션 중 하나를 선택합니다.

  6. 변경사항을 검토하고 만들기를 클릭합니다.

gcloud

라이트 주제를 만들려면 gcloud pubsub lite-topics create 명령어를 사용합니다.

gcloud pubsub lite-topics create TOPIC_ID \
  --location=LOCATION \
  --partitions=NUMBER_OF_PARTITIONS \
  --per-partition-bytes=STORAGE_PER_PARTITION \
  [--throughput-reservation=RESERVATION_NAME \]
  [--message-retention-period=MESSAGE_RETENTION_PERIOD]

다음을 바꿉니다.

  • TOPIC_ID: 라이트 주제의 ID

  • LOCATION: Pub/Sub Lite가 지원하는 위치의 이름

  • NUMBER_OF_PARTITIONS: 라이트 주제의 파티션 수(정수)

  • STORAGE_PER_PARTITION: 각 파티션의 스토리지 용량(예: 30GiB)

  • RESERVATION_NAME: projects/123456789/locations/us-west1/reservations/my-reservation과 같은 라이트 예약의 정규화된 경로

  • MESSAGE_RETENTION_PERIOD: 라이트 주제에서 메시지를 저장하는 시간(예: 1d 또는 2w)

요청이 성공하면 명령줄에 확인 메시지가 표시됩니다.

Created [TOPIC_ID].

프로토콜

라이트 주제를 만들려면 다음과 같이 POST 요청을 보내세요.

POST https://REGION-pubsublite.googleapis.com/v1/admin/projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
Authorization: Bearer $(gcloud auth print-access-token)

다음을 바꿉니다.

요청 본문에 다음 필드를 지정합니다.

{
  "partitionConfig": {
       "count": NUMBER_OF_PARTITIONS,
       "capacity": {
         "publishMibPerSec": publish_CAPACITY,
         "subscribeMibPerSec": subscribe_CAPACITY,
       }
  },
  "retentionConfig": {
       "perPartitionBytes": STORAGE_PER_PARTITION,
       "period": MESSAGE_RETENTION_PERIOD,
  },
  "reservationConfig": {
       "throughputReservation": RESERVATION_NAME
  }
}

다음을 바꿉니다.

  • NUMBER_OF_PARTITIONS: 라이트 주제의 파티션 수(정수)

  • STORAGE_PER_PARTITION: 각 파티션의 스토리지 용량(예: 30GiB)

  • publish_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • subscribe_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • MESSAGE_RETENTION_PERIOD: 라이트 주제에서 메시지를 저장하는 시간(예: 1d 또는 2w)

  • RESERVATION_NAME: projects/123456789/locations/us-west1/reservations/my-reservation과 같은 라이트 예약의 정규화된 경로

요청이 성공하는 경우 응답은 JSON 형식의 라이트 주제입니다.

{
  "name": projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID,
  "partitionConfig": {
       "count": NUMBER_OF_PARTITIONS,
       "capacity": {
         "publishMibPerSec": publish_CAPACITY,
         "subscribeMibPerSec": subscribe_CAPACITY,
       }
  },
  "retentionConfig": {
       "perPartitionBytes": STORAGE_PER_PARTITION,
       "period": MESSAGE_RETENTION_PERIOD,
  },
  "reservationConfig": {
       "throughputReservation": RESERVATION_NAME
  }
}

Go

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Go 설정 안내를 따르세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsublite"
)

func createTopic(w io.Writer, projectID, region, location, topicID, reservation string) error {
	// projectID := "my-project-id"
	// region := "us-central1" // see https://cloud.google.com/pubsub/lite/docs/locations
	// NOTE: location can be either a region ("us-central1") or a zone ("us-central1-a")
	// For a list of valid locations, see https://cloud.google.com/pubsub/lite/docs/locations.
	// location := "us-central1"
	// topicID := "my-topic"
	// reservation := "projects/my-project-id/reservations/my-reservation"
	ctx := context.Background()
	client, err := pubsublite.NewAdminClient(ctx, region)
	if err != nil {
		return fmt.Errorf("pubsublite.NewAdminClient: %w", err)
	}
	defer client.Close()

	const gib = 1 << 30

	topicPath := fmt.Sprintf("projects/%s/locations/%s/topics/%s", projectID, location, topicID)
	// For ranges of fields in TopicConfig, see https://pkg.go.dev/cloud.google.com/go/pubsublite/#TopicConfig
	topic, err := client.CreateTopic(ctx, pubsublite.TopicConfig{
		Name:                       topicPath,
		PartitionCount:             2, // Must be >= 1 and cannot decrease after creation.
		PublishCapacityMiBPerSec:   4,
		SubscribeCapacityMiBPerSec: 8,
		PerPartitionBytes:          30 * gib,
		RetentionDuration:          pubsublite.InfiniteRetention,
		ThroughputReservation:      reservation,
	})
	if err != nil {
		return fmt.Errorf("client.CreateTopic got err: %w", err)
	}
	fmt.Fprintf(w, "Created topic: %#v\n", topic)
	return nil
}

자바

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 자바 설정 안내를 따르세요.

import com.google.api.gax.rpc.AlreadyExistsException;
import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.CloudRegionOrZone;
import com.google.cloud.pubsublite.CloudZone;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.ReservationName;
import com.google.cloud.pubsublite.ReservationPath;
import com.google.cloud.pubsublite.TopicName;
import com.google.cloud.pubsublite.TopicPath;
import com.google.cloud.pubsublite.proto.Topic;
import com.google.cloud.pubsublite.proto.Topic.PartitionConfig;
import com.google.cloud.pubsublite.proto.Topic.PartitionConfig.Capacity;
import com.google.cloud.pubsublite.proto.Topic.ReservationConfig;
import com.google.cloud.pubsublite.proto.Topic.RetentionConfig;
import com.google.protobuf.util.Durations;
import java.util.concurrent.ExecutionException;

public class CreateTopicExample {

  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String cloudRegion = "your-cloud-region";
    char zoneId = 'a';
    String topicId = "your-topic-id";
    String reservationId = "your-reservation-id";
    long projectNumber = Long.parseLong("123456789");
    int partitions = 1;
    // True if using a regional location. False if using a zonal location.
    // https://cloud.google.com/pubsub/lite/docs/topics
    boolean regional = false;

    createTopicExample(
        cloudRegion, zoneId, projectNumber, topicId, reservationId, partitions, regional);
  }

  public static void createTopicExample(
      String cloudRegion,
      char zoneId,
      long projectNumber,
      String topicId,
      String reservationId,
      int partitions,
      boolean regional)
      throws Exception {

    ReservationPath reservationPath =
        ReservationPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(CloudRegion.of(cloudRegion))
            .setName(ReservationName.of(reservationId))
            .build();

    CloudRegionOrZone location;
    if (regional) {
      location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
    } else {
      location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
    }

    TopicPath topicPath =
        TopicPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(location)
            .setName(TopicName.of(topicId))
            .build();

    Topic topic =
        Topic.newBuilder()
            .setPartitionConfig(
                PartitionConfig.newBuilder()
                    // Set throughput capacity per partition in MiB/s.
                    .setCapacity(
                        Capacity.newBuilder()
                            // Must be 4-16 MiB/s.
                            .setPublishMibPerSec(4)
                            // Must be 4-32 MiB/s.
                            .setSubscribeMibPerSec(8)
                            .build())
                    .setCount(partitions))
            .setRetentionConfig(
                RetentionConfig.newBuilder()
                    // How long messages are retained.
                    .setPeriod(Durations.fromDays(1))
                    // Set storage per partition to 30 GiB. This must be 30 GiB-10 TiB.
                    // If the number of bytes stored in any of the topic's partitions grows
                    // beyond this value, older messages will be dropped to make room for
                    // newer ones, regardless of the value of `period`.
                    .setPerPartitionBytes(30 * 1024 * 1024 * 1024L))
            .setReservationConfig(
                ReservationConfig.newBuilder()
                    .setThroughputReservation(reservationPath.toString())
                    .build())
            .setName(topicPath.toString())
            .build();

    AdminClientSettings adminClientSettings =
        AdminClientSettings.newBuilder().setRegion(CloudRegion.of(cloudRegion)).build();

    try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
      Topic response = adminClient.createTopic(topic).get();
      if (regional) {
        System.out.println(response.getAllFields() + " (regional topic) created successfully.");
      } else {
        System.out.println(response.getAllFields() + " (zonal topic) created successfully.");
      }
    } catch (ExecutionException e) {
      try {
        throw e.getCause();
      } catch (AlreadyExistsException alreadyExists) {
        System.out.println("This topic already exists.");
      } catch (Throwable throwable) {
        throwable.printStackTrace();
      }
    }
  }
}

Python

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Python 설정 안내를 따르세요.

from google.api_core.exceptions import AlreadyExists
from google.cloud.pubsublite import AdminClient, Topic
from google.cloud.pubsublite.types import (
    CloudRegion,
    CloudZone,
    ReservationPath,
    TopicPath,
)
from google.protobuf.duration_pb2 import Duration

# TODO(developer):
# project_number = 1122334455
# cloud_region = "us-central1"
# zone_id = "a"
# topic_id = "your-topic-id"
# reservation_id = "your-reservation-id"
# num_partitions = 1
# regional = True

cloud_region = CloudRegion(cloud_region)
reservation_path = ReservationPath(project_number, cloud_region, reservation_id)

topic_path = None
if regional:
    #  A regional topic.
    topic_path = TopicPath(project_number, cloud_region, topic_id)
else:
    #  A zonal topic
    topic_path = TopicPath(
        project_number, CloudZone(cloud_region, zone_id), topic_id
    )

topic = Topic(
    name=str(topic_path),
    partition_config=Topic.PartitionConfig(
        # A topic must have at least one partition.
        count=num_partitions,
        # Set throughput capacity per partition in MiB/s.
        capacity=Topic.PartitionConfig.Capacity(
            # Set publish throughput capacity per partition to 4 MiB/s. Must be >= 4 and <= 16.
            publish_mib_per_sec=4,
            # Set subscribe throughput capacity per partition to 4 MiB/s. Must be >= 4 and <= 32.
            subscribe_mib_per_sec=8,
        ),
    ),
    retention_config=Topic.RetentionConfig(
        # Set storage per partition to 30 GiB. This must be in the range 30 GiB-10TiB.
        # If the number of byptes stored in any of the topic's partitions grows beyond
        # this value, older messages will be dropped to make room for newer ones,
        # regardless of the value of `period`.
        per_partition_bytes=30 * 1024 * 1024 * 1024,
        # Allow messages to be retained for 7 days.
        period=Duration(seconds=60 * 60 * 24 * 7),
    ),
    reservation_config=Topic.ReservationConfig(
        throughput_reservation=str(reservation_path),
    ),
)

client = AdminClient(cloud_region)
try:
    response = client.create_topic(topic)
    if regional:
        print(f"{response.name} (regional topic) created successfully.")
    else:
        print(f"{response.name} (zonal topic) created successfully.")
except AlreadyExists:
    print(f"{topic_path} already exists.")

라이트 주제를 만든 후에는 파티션당 처리량과 스토리지 용량을 확장할 수 있습니다. 파티션 수 또한 늘릴 수 있지만 줄일 수는 없습니다.

라이트 주제 업데이트

라이트 주제의 다음 속성을 업데이트할 수 있습니다.

  • 라이트 주제와 연관된 예약

  • 주제의 파티션 수(증가만 가능)

  • 게시 및 구독 처리량 용량 한도

  • 파티션당 스토리지

  • 메시지 보관 유형

주제의 처리량 용량 또는 스토리지 용량을 확장하기 전에 처리량 용량 확장스토리지 용량 확장을 참조하세요.

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub Lite API를 사용하여 라이트 주제를 업데이트할 수 있습니다.

콘솔

  1. 라이트 주제 페이지로 이동합니다.

    라이트 주제로 이동

  2. 라이트 주제 ID를 클릭합니다.

  3. 수정을 클릭합니다.

  4. 다음 업데이트 중 일부 또는 모두를 수행할 수 있습니다.

    • 다른 예약을 사용합니다. 영역 주제의 경우 예약을 사용하지 않도록 선택할 수 있습니다.
    • 파티션 수를 입력합니다. 이 값을 늘릴 수 있지만, 줄일 수는 없습니다.
    • 최대 허용되는 게시 및 구독 처리량을 사용 설정 또는 사용 중지합니다.
    • 영역 주제의 경우 예약된 게시 및 구독 처리량을 업데이트합니다. 예약이 연결된 주제의 경우 업데이트된 처리량에 새로운 최대 한도가 반영됩니다.
    • 파티션당 스토리지 용량을 수정합니다.
    • 메시지 보관 기간을 수정합니다.
  5. 업데이트를 클릭합니다.

gcloud

라이트 주제를 업데이트하려면 gcloud pubsub lite-topics update 명령어를 사용합니다.

gcloud pubsub lite-topics update TOPIC_ID \
  --location=LOCATION \
  --partitions=NUMBER_OF_PARTITIONS \
  --per-partition-publish-mib=publish_CAPACITY \
  --per-partition-subscribe-mib=subscribe_CAPACITY \
  --per-partition-bytes=STORAGE_PER_PARTITION \
  --message-retention-period=MESSAGE_RETENTION_PERIOD

다음을 바꿉니다.

  • TOPIC_ID: 라이트 주제의 ID

  • LOCATION: 라이트 주제가 있는 위치의 이름

  • NUMBER_OF_PARTITIONS: 라이트 주제를 위해 구성할 파티션 수

  • publish_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • subscribe_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • STORAGE_PER_PARTITION: 각 파티션의 스토리지 용량(예: 30GiB)

  • MESSAGE_RETENTION_PERIOD: 라이트 주제에서 메시지를 저장하는 시간(예: 1d 또는 2w)

요청이 성공하면 명령줄에 라이트 주제가 표시됩니다.

name: projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
partitionConfig:
  count: NUMBER_OF_PARTITIONS
  capacity:
    publishMibPerSec: publish_CAPACITY
    subscribeMibPerSec: subscribe_CAPACITY
retentionConfig:
  perPartitionBytes: STORAGE_PER_PARTITION
  period: MESSAGE_RETENTION_PERIOD

프로토콜

라이트 주제를 업데이트하려면 다음과 같이 PATCH 요청을 보내세요.

PATCH https://REGION-pubsublite.googleapis.com/v1/admin/projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID?updateMask=partitionConfig.capacity,retentionConfig.perPartitionBytes,retentionConfig.period,partitionConfig.count
Authorization: Bearer $(gcloud auth print-access-token)

다음을 바꿉니다.

  • REGION: 라이트 주제가 있는 리전

  • PROJECT_NUMBER: 라이트 주제가 있는 프로젝트의 프로젝트 번호

  • LOCATION: 라이트 주제가 있는 위치의 이름

  • TOPIC_ID: 라이트 주제의 ID

요청 본문에 다음 필드를 지정합니다.

{
  "partitionConfig": {
      "count": NUMBER_OF_PARTITIONS,
      "capacity": {
         "publishMibPerSec": publish_CAPACITY,
         "subscribeMibPerSec": subscribe_CAPACITY,
      }
   },
   "retentionConfig": {
       "perPartitionBytes": STORAGE_PER_PARTITION,
       "period": MESSAGE_RETENTION_PERIOD,
   },
}

다음을 바꿉니다.

  • publish_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • subscribe_CAPACITY: 각 파티션의 게시 처리량 용량(정수)

  • STORAGE_PER_PARTITION: 각 파티션의 스토리지 용량(예: 30GiB)

  • MESSAGE_RETENTION_PERIOD: 라이트 주제에서 메시지를 저장하는 시간(예: 1d 또는 2w)

  • NUMBER_OF_PARTITIONS: 라이트 주제를 위해 구성할 파티션 수

요청이 성공하는 경우 응답은 JSON 형식의 라이트 주제입니다.

{
  "name": projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID,
  "partitionConfig": {
      "count": NUMBER_OF_PARTITIONS,
      "capacity": {
         "publishMibPerSec": publish_CAPACITY,
         "subscribeMibPerSec": subscribe_CAPACITY,
      }
   },
   "retentionConfig": {
       "perPartitionBytes": STORAGE_PER_PARTITION,
       "period": MESSAGE_RETENTION_PERIOD,
   },
}

Go

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Go 설정 안내를 따르세요.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/pubsublite"
)

func updateTopic(w io.Writer, projectID, region, location, topicID, reservation string) error {
	// projectID := "my-project-id"
	// region := "us-central1"
	// NOTE: location can be either a region ("us-central1") or a zone ("us-central1-a")
	// For a list of valid locations, see https://cloud.google.com/pubsub/lite/docs/locations.
	// location := "us-central1"
	// topicID := "my-topic"
	// reservation := "projects/my-project-id/reservations/my-reservation"
	ctx := context.Background()
	client, err := pubsublite.NewAdminClient(ctx, region)
	if err != nil {
		return fmt.Errorf("pubsublite.NewAdminClient: %w", err)
	}
	defer client.Close()

	topicPath := fmt.Sprintf("projects/%s/locations/%s/topics/%s", projectID, location, topicID)
	// For ranges of fields in TopicConfigToUpdate, see https://pkg.go.dev/cloud.google.com/go/pubsublite/#TopicConfigToUpdate
	config := pubsublite.TopicConfigToUpdate{
		Name:                       topicPath,
		PartitionCount:             3, // Partition count cannot decrease.
		PublishCapacityMiBPerSec:   8,
		SubscribeCapacityMiBPerSec: 16,
		PerPartitionBytes:          60 * 1024 * 1024 * 1024,
		RetentionDuration:          24 * time.Hour,
		ThroughputReservation:      reservation,
	}
	updatedCfg, err := client.UpdateTopic(ctx, config)
	if err != nil {
		return fmt.Errorf("client.UpdateTopic got err: %w", err)
	}
	fmt.Fprintf(w, "Updated topic: %v\n", updatedCfg)
	return nil
}

자바

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 자바 설정 안내를 따르세요.

import com.google.api.gax.rpc.NotFoundException;
import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.CloudRegionOrZone;
import com.google.cloud.pubsublite.CloudZone;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.ReservationName;
import com.google.cloud.pubsublite.ReservationPath;
import com.google.cloud.pubsublite.TopicName;
import com.google.cloud.pubsublite.TopicPath;
import com.google.cloud.pubsublite.proto.Topic;
import com.google.cloud.pubsublite.proto.Topic.PartitionConfig;
import com.google.cloud.pubsublite.proto.Topic.PartitionConfig.Capacity;
import com.google.cloud.pubsublite.proto.Topic.ReservationConfig;
import com.google.cloud.pubsublite.proto.Topic.RetentionConfig;
import com.google.protobuf.FieldMask;
import com.google.protobuf.util.Durations;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;

public class UpdateTopicExample {

  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String cloudRegion = "your-cloud-region";
    char zoneId = 'b';
    String topicId = "your-topic-id";
    String reservationId = "your-reservation-id";
    long projectNumber = Long.parseLong("123456789");
    // True if using a regional location. False if using a zonal location.
    // https://cloud.google.com/pubsub/lite/docs/topics
    boolean regional = true;

    updateTopicExample(cloudRegion, zoneId, projectNumber, topicId, reservationId, regional);
  }

  public static void updateTopicExample(
      String cloudRegion,
      char zoneId,
      long projectNumber,
      String topicId,
      String reservationId,
      boolean regional)
      throws Exception {

    CloudRegionOrZone location;
    if (regional) {
      location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
    } else {
      location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
    }

    TopicPath topicPath =
        TopicPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(location)
            .setName(TopicName.of(topicId))
            .build();

    ReservationPath reservationPath =
        ReservationPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(CloudRegion.of(cloudRegion))
            .setName(ReservationName.of(reservationId))
            .build();

    Iterable<String> iterablePaths =
        Arrays.asList(
            "partition_config.scale",
            "retention_config.per_partition_bytes",
            "retention_config.period",
            "reservation_config.throughput_reservation");

    FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(iterablePaths).build();

    Topic topic =
        Topic.newBuilder()
            .setPartitionConfig(
                PartitionConfig.newBuilder()
                    .setCapacity(
                        Capacity.newBuilder()
                            .setPublishMibPerSec(16)
                            .setSubscribeMibPerSec(32)
                            .build())
                    .build())
            .setRetentionConfig(
                RetentionConfig.newBuilder()
                    // Set storage per partition to 32 GiB. This must be 30 GiB-10 TiB.
                    // If the number of bytes stored in any of the topic's partitions grows
                    // beyond this value, older messages will be dropped to make room for
                    // newer ones, regardless of the value of `period`.
                    // Be careful when decreasing storage per partition as it may cause
                    // lost messages.
                    .setPerPartitionBytes(32 * 1024 * 1024 * 1024L)
                    .setPeriod(Durations.fromDays(7)))
            .setReservationConfig(
                ReservationConfig.newBuilder()
                    .setThroughputReservation(reservationPath.toString())
                    .build())
            .setName(topicPath.toString())
            .build();

    AdminClientSettings adminClientSettings =
        AdminClientSettings.newBuilder().setRegion(CloudRegion.of(cloudRegion)).build();

    try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
      Topic topicBeforeUpdate = adminClient.getTopic(topicPath).get();
      System.out.println("Before update: " + topicBeforeUpdate.getAllFields());

      Topic topicAfterUpdate = adminClient.updateTopic(topic, fieldMask).get();
      System.out.println("After update: " + topicAfterUpdate.getAllFields());
    } catch (ExecutionException e) {
      try {
        throw e.getCause();
      } catch (NotFoundException notFound) {
        System.out.println("This topic is not found.");
      } catch (Throwable throwable) {
        throwable.printStackTrace();
      }
    }
  }
}

Python

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Python 설정 안내를 따르세요.

from google.api_core.exceptions import NotFound
from google.cloud.pubsublite import AdminClient, Topic
from google.cloud.pubsublite.types import (
    CloudRegion,
    CloudZone,
    ReservationPath,
    TopicPath,
)
from google.protobuf.duration_pb2 import Duration
from google.protobuf.field_mask_pb2 import FieldMask

# TODO(developer):
# project_number = 1122334455
# cloud_region = "us-central1"
# zone_id = "a"
# topic_id = "your-topic-id"
# reservation_id = "your-reservation-id"
# regional = True

location = None
if regional:
    #  A region.
    location = CloudRegion(cloud_region)
else:
    #  A zone.
    location = CloudZone(CloudRegion(cloud_region), zone_id)

topic_path = TopicPath(project_number, location, topic_id)
reservation_path = ReservationPath(project_number, cloud_region, reservation_id)

# Defines which topic fields to update.
field_mask = FieldMask(
    paths=[
        "partition_config.capacity",
        "retention_config.per_partition_bytes",
        "retention_config.period",
        "reservation_confing.throughput_reservation",
    ]
)

# Defines how to update the topic fields.
topic = Topic(
    name=str(topic_path),
    partition_config=Topic.PartitionConfig(
        capacity=Topic.PartitionConfig.Capacity(
            publish_mib_per_sec=16,
            subscribe_mib_per_sec=32,
        )
    ),
    retention_config=Topic.RetentionConfig(
        # Set storage per partition to 32 GiB. This must be in the range 30 GiB-10TiB.
        # If the number of byptes stored in any of the topic's partitions grows beyond
        # this value, older messages will be dropped to make room for newer ones,
        # regardless of the value of `period`.
        # Be careful when decreasing storage per partition as it may cuase lost messages.
        per_partition_bytes=32 * 1024 * 1024 * 1024,
        # Allow messages to be stored for 14 days.
        period=Duration(seconds=60 * 60 * 24 * 14),
    ),
    reservation_config=Topic.ReservationConfig(
        throughput_reservation=str(reservation_path),
    ),
)

client = AdminClient(cloud_region)
try:
    response = client.update_topic(topic, field_mask)
    print(f"{response.name} updated successfully.")
except NotFound:
    print(f"{topic_path} not found.")

라이트 주제 세부정보 보기

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub Lite API를 사용하여 라이트 주제에 대한 세부정보를 가져올 수 있습니다.

콘솔

  1. 라이트 주제 페이지로 이동합니다.

    라이트 주제로 이동

  2. 라이트 주제 ID를 클릭합니다.

gcloud

라이트 주제에 대한 세부정보를 가져오려면 gcloud pubsub lite-topics describe 명령어를 사용합니다.

gcloud pubsub lite-topics describe TOPIC_ID \
--location=LOCATION

다음을 바꿉니다.

  • TOPIC_ID: 라이트 주제의 ID

  • LOCATION: 라이트 주제가 있는 위치의 이름

요청이 성공하면 명령줄에 라이트 주제가 표시됩니다.

name: projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
partitionConfig:
  count: NUMBER_OF_PARTITIONS
  capacity:
    publishMibPerSec: publish_CAPACITY
    subscribeMibPerSec: subscribe_CAPACITY
retentionConfig:
  perPartitionBytes: STORAGE_PER_PARTITION
  period: MESSAGE_RETENTION_PERIOD

프로토콜

라이트 주제에 대한 세부정보를 가져오려면 다음과 같이 GET 요청을 보냅니다.

GET https://REGION-pubsublite.googleapis.com/v1/admin/projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
Authorization: Bearer $(gcloud auth print-access-token)

다음을 바꿉니다.

  • REGION: 라이트 주제가 있는 리전

  • PROJECT_NUMBER: 라이트 주제가 있는 프로젝트의 프로젝트 번호

  • LOCATION: 라이트 주제가 있는 위치의 이름

  • TOPIC_ID: 라이트 주제의 ID

요청이 성공하는 경우 응답은 JSON 형식의 라이트 주제입니다.

{
  "name": projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID,
  "partitionConfig": {
      "count": NUMBER_OF_PARTITIONS,
      "capacity": {
         "publishMibPerSec": publish_CAPACITY,
         "subscribeMibPerSec": subscribe_CAPACITY,
      }
   },
   "retentionConfig": {
       "perPartitionBytes": STORAGE_PER_PARTITION,
       "period": MESSAGE_RETENTION_PERIOD,
   },
}

Go

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Go 설정 안내를 따르세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsublite"
)

func getTopic(w io.Writer, projectID, region, location, topicID string) error {
	// projectID := "my-project-id"
	// region := "us-central1"
	// NOTE: location can be either a region ("us-central1") or a zone ("us-central1-a")
	// For a list of valid locations, see https://cloud.google.com/pubsub/lite/docs/locations.
	// location := "us-central1"
	// topicID := "my-topic"
	ctx := context.Background()
	client, err := pubsublite.NewAdminClient(ctx, region)
	if err != nil {
		return fmt.Errorf("pubsublite.NewAdminClient: %w", err)
	}
	defer client.Close()

	topicPath := fmt.Sprintf("projects/%s/locations/%s/topics/%s", projectID, location, topicID)
	topic, err := client.Topic(ctx, topicPath)
	if err != nil {
		return fmt.Errorf("client.Topic got err: %w", err)
	}
	fmt.Fprintf(w, "Got topic: %#v\n", *topic)
	return nil
}

자바

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 자바 설정 안내를 따르세요.

import com.google.api.gax.rpc.NotFoundException;
import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.CloudRegionOrZone;
import com.google.cloud.pubsublite.CloudZone;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.TopicName;
import com.google.cloud.pubsublite.TopicPath;
import com.google.cloud.pubsublite.proto.Topic;
import java.util.concurrent.ExecutionException;

public class GetTopicExample {

  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String cloudRegion = "your-cloud-region";
    char zoneId = 'b';
    // Choose an existing topic.
    String topicId = "your-topic-id";
    long projectNumber = Long.parseLong("123456789");
    // True if using a regional location. False if using a zonal location.
    // https://cloud.google.com/pubsub/lite/docs/topics
    boolean regional = true;

    getTopicExample(cloudRegion, zoneId, projectNumber, topicId, regional);
  }

  public static void getTopicExample(
      String cloudRegion, char zoneId, long projectNumber, String topicId, boolean regional)
      throws Exception {

    CloudRegionOrZone location;
    if (regional) {
      location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
    } else {
      location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
    }

    TopicPath topicPath =
        TopicPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(location)
            .setName(TopicName.of(topicId))
            .build();

    AdminClientSettings adminClientSettings =
        AdminClientSettings.newBuilder().setRegion(CloudRegion.of(cloudRegion)).build();

    try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
      Topic topic = adminClient.getTopic(topicPath).get();
      long numPartitions = adminClient.getTopicPartitionCount(topicPath).get();
      System.out.println(topic.getAllFields() + "\nhas " + numPartitions + " partition(s).");
    } catch (ExecutionException e) {
      try {
        throw e.getCause();
      } catch (NotFoundException notFound) {
        System.out.println("This topic is not found.");
      } catch (Throwable throwable) {
        throwable.printStackTrace();
      }
    }
  }
}

Python

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Python 설정 안내를 따르세요.

from google.api_core.exceptions import NotFound
from google.cloud.pubsublite import AdminClient
from google.cloud.pubsublite.types import CloudRegion, CloudZone, TopicPath

# TODO(developer):
# project_number = 1122334455
# cloud_region = "us-central1"
# zone_id = "a"
# topic_id = "your-topic-id"
# regional = True

location = None
if regional:
    #  A region.
    location = CloudRegion(cloud_region)
else:
    #  A zone.
    location = CloudZone(CloudRegion(cloud_region), zone_id)

topic_path = TopicPath(project_number, location, topic_id)

client = AdminClient(cloud_region)
try:
    response = client.get_topic(topic_path)
    num_partitions = client.get_topic_partition_count(topic_path)
    print(f"{response.name} has {num_partitions} partition(s).")
except NotFound:
    print(f"{topic_path} not found.")

라이트 주제 나열

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub Lite API를 사용하여 프로젝트의 라이트 주제를 나열할 수 있습니다.

콘솔

gcloud

gcloud pubsub lite-topics list \
  --location=LOCATION

LOCATION을 라이트 주제가 있는 위치의 이름으로 바꿉니다.

요청이 성공하면 명령줄에 라이트 주제가 표시됩니다.

---
name: projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
partitionConfig:
  count: NUMBER_OF_PARTITIONS
  capacity:
    publishMibPerSec: publish_CAPACITY
    subscribeMibPerSec: subscribe_CAPACITY
retentionConfig:
  perPartitionBytes: STORAGE_PER_PARTITION
  period: MESSAGE_RETENTION_PERIOND
---
name: projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
partitionConfig:
  count: NUMBER_OF_PARTITIONS
  capacity:
    publishMibPerSec: publish_CAPACITY
    subscribeMibPerSec: subscribe_CAPACITY
retentionConfig:
  perPartitionBytes: STORAGE_PER_PARTITION
  period: MESSAGE_RETENTION_PERIOND

프로토콜

프로젝트의 라이트 주제를 나열하려면 다음과 같이 GET 요청을 보냅니다.

GET https://REGION-pubsublite.googleapis.com/v1/admin/projects/PROJECT_NUMBER/topics
Authorization: Bearer $(gcloud auth print-access-token)

다음을 바꿉니다.

  • REGION: 라이트 주제가 있는 리전

  • PROJECT_NUMBER: 라이트 주제가 있는 프로젝트의 프로젝트 번호

요청이 성공하는 경우 응답은 JSON 형식의 라이트 주제 목록입니다.

{
  "topics": [
      {
          "name": "projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID",
      },
      {
          "name": "projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID",
      }
  ]
}

Go

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Go 설정 안내를 따르세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsublite"
	"google.golang.org/api/iterator"
)

func listTopics(w io.Writer, projectID, region, zone string) error {
	// projectID := "my-project-id"
	// region := "us-central1"
	// zone := "us-central1-a"
	ctx := context.Background()
	client, err := pubsublite.NewAdminClient(ctx, region)
	if err != nil {
		return fmt.Errorf("pubsublite.NewAdminClient: %w", err)
	}
	defer client.Close()

	parent := fmt.Sprintf("projects/%s/locations/%s", projectID, zone)
	topicIter := client.Topics(ctx, parent)
	for {
		topic, err := topicIter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("topicIter.Next got err: %w", err)
		}
		fmt.Fprintf(w, "Got topic: %#v\n", topic)
	}
	return nil
}

자바

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 자바 설정 안내를 따르세요.

import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.CloudRegionOrZone;
import com.google.cloud.pubsublite.CloudZone;
import com.google.cloud.pubsublite.LocationPath;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.proto.Topic;
import java.util.List;

public class ListTopicsExample {

  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String cloudRegion = "your-cloud-region";
    char zoneId = 'b';
    long projectNumber = Long.parseLong("123456789");
    // True if using a regional location. False if using a zonal location.
    // https://cloud.google.com/pubsub/lite/docs/topics
    boolean regional = true;

    listTopicsExample(cloudRegion, zoneId, projectNumber, regional);
  }

  public static void listTopicsExample(
      String cloudRegion, char zoneId, long projectNumber, boolean regional) throws Exception {

    AdminClientSettings adminClientSettings =
        AdminClientSettings.newBuilder().setRegion(CloudRegion.of(cloudRegion)).build();

    CloudRegionOrZone location;
    if (regional) {
      location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
    } else {
      location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
    }

    LocationPath locationPath =
        LocationPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(location)
            .build();

    try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
      List<Topic> topics = adminClient.listTopics(locationPath).get();
      for (Topic topic : topics) {
        System.out.println(topic.getAllFields());
      }
      System.out.println(topics.size() + " topic(s) listed.");
    }
  }
}

Python

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Python 설정 안내를 따르세요.

from google.cloud.pubsublite import AdminClient
from google.cloud.pubsublite.types import CloudRegion, CloudZone, LocationPath

# TODO(developer):
# project_number = 1122334455
# cloud_region = "us-central1"
# zone_id = "a"
# regional = True

location = None
if regional:
    #  A region.
    location = CloudRegion(cloud_region)
else:
    #  A zone.
    location = CloudZone(CloudRegion(cloud_region), zone_id)

location_path = LocationPath(project_number, location)

client = AdminClient(cloud_region)
response = client.list_topics(location_path)

for topic in response:
    print(topic)

print(f"{len(response)} topic(s) listed in your project and location.")

라이트 주제 삭제

Google Cloud 콘솔, Google Cloud CLI, Pub/Sub Lite API를 사용하여 라이트 주제를 삭제할 수 있습니다.

콘솔

  1. 라이트 주제 페이지로 이동합니다.

    라이트 주제로 이동

  2. 라이트 주제 ID를 클릭합니다.

  3. 주제 세부정보 페이지에서 삭제를 클릭합니다.

  4. 표시되는 필드에 delete를 입력하여 라이트 주제를 삭제할지 여부를 확인합니다.

  5. 삭제를 클릭합니다.

gcloud

라이트 주제를 삭제하려면 gcloud pubsub lite-topics delete 명령어를 사용합니다.

  1. delete 명령어를 실행합니다.

    gcloud pubsub lite-topics delete TOPIC_ID \
     --location=LOCATION
    

    다음을 바꿉니다.

    • TOPIC_ID: 라이트 주제의 ID

    • LOCATION: 라이트 주제가 있는 위치의 이름

  2. 확인하려면 Y를 입력합니다.

요청이 성공하면 응답은 다음과 같습니다.

Deleted topic [TOPIC_ID].

프로토콜

라이트 주제를 삭제하려면 다음과 같이 DELETE 요청을 보냅니다.

DELETE https://REGION-pubsublite.googleapis.com/v1/admin/projects/PROJECT_NUMBER/locations/LOCATION/topics/TOPIC_ID
Authorization: Bearer $(gcloud auth print-access-token)

다음을 바꿉니다.

  • REGION: 라이트 주제가 있는 리전

  • PROJECT_NUMBER: 라이트 주제가 있는 프로젝트의 프로젝트 번호

  • LOCATION: 라이트 주제가 있는 위치의 이름

  • TOPIC_ID: 라이트 주제의 ID

요청이 성공하면 응답은 빈 JSON 객체입니다.

Go

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Go 설정 안내를 따르세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsublite"
)

func deleteTopic(w io.Writer, projectID, region, location, topicID string) error {
	// projectID := "my-project-id"
	// region := "us-central1"
	// NOTE: location can be either a region ("us-central1") or a zone ("us-central1-a")
	// For a list of valid locations, see https://cloud.google.com/pubsub/lite/docs/locations.
	// location := "us-central1"
	// topicID := "my-topic"
	ctx := context.Background()
	client, err := pubsublite.NewAdminClient(ctx, region)
	if err != nil {
		return fmt.Errorf("pubsublite.NewAdminClient: %w", err)
	}
	defer client.Close()

	topicPath := fmt.Sprintf("projects/%s/locations/%s/topics/%s", projectID, location, topicID)
	err = client.DeleteTopic(ctx, topicPath)
	if err != nil {
		return fmt.Errorf("client.DeleteTopic got err: %w", err)
	}
	fmt.Fprint(w, "Deleted topic\n")
	return nil
}

자바

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 자바 설정 안내를 따르세요.

import com.google.api.gax.rpc.NotFoundException;
import com.google.cloud.pubsublite.AdminClient;
import com.google.cloud.pubsublite.AdminClientSettings;
import com.google.cloud.pubsublite.CloudRegion;
import com.google.cloud.pubsublite.CloudRegionOrZone;
import com.google.cloud.pubsublite.CloudZone;
import com.google.cloud.pubsublite.ProjectNumber;
import com.google.cloud.pubsublite.TopicName;
import com.google.cloud.pubsublite.TopicPath;
import java.util.concurrent.ExecutionException;

public class DeleteTopicExample {

  public static void main(String... args) throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String cloudRegion = "your-cloud-region";
    char zoneId = 'b';
    // Choose an existing topic.
    String topicId = "your-topic-id";
    long projectNumber = Long.parseLong("123456789");
    // True if using a regional location. False if using a zonal location.
    // https://cloud.google.com/pubsub/lite/docs/topics
    boolean regional = false;

    deleteTopicExample(cloudRegion, zoneId, projectNumber, topicId, regional);
  }

  public static void deleteTopicExample(
      String cloudRegion, char zoneId, long projectNumber, String topicId, boolean regional)
      throws Exception {

    CloudRegionOrZone location;
    if (regional) {
      location = CloudRegionOrZone.of(CloudRegion.of(cloudRegion));
    } else {
      location = CloudRegionOrZone.of(CloudZone.of(CloudRegion.of(cloudRegion), zoneId));
    }

    TopicPath topicPath =
        TopicPath.newBuilder()
            .setProject(ProjectNumber.of(projectNumber))
            .setLocation(location)
            .setName(TopicName.of(topicId))
            .build();

    AdminClientSettings adminClientSettings =
        AdminClientSettings.newBuilder().setRegion(CloudRegion.of(cloudRegion)).build();

    try (AdminClient adminClient = AdminClient.create(adminClientSettings)) {
      adminClient.deleteTopic(topicPath).get();
      if (regional) {
        System.out.println(topicPath.toString() + " (regional topic) deleted successfully.");
      } else {
        System.out.println(topicPath.toString() + " (zonal topic) deleted successfully.");
      }
    } catch (ExecutionException e) {
      try {
        throw e.getCause();
      } catch (NotFoundException notFound) {
        System.out.println("This topic is not found.");
      } catch (Throwable throwable) {
        throwable.printStackTrace();
      }
    }
  }

Python

이 샘플을 실행하기 전에 Pub/Sub Lite 클라이언트 라이브러리의 Python 설정 안내를 따르세요.

from google.api_core.exceptions import NotFound
from google.cloud.pubsublite import AdminClient
from google.cloud.pubsublite.types import CloudRegion, CloudZone, TopicPath

# TODO(developer):
# project_number = 1122334455
# cloud_region = "us-central1"
# zone_id = "a"
# topic_id = "your-topic-id"
# regional = True

cloud_region = CloudRegion(cloud_region)
topic_path = None
if regional:
    #  A regional topic.
    topic_path = TopicPath(project_number, cloud_region, topic_id)
else:
    #  A zonal topic
    topic_path = TopicPath(
        project_number, CloudZone(cloud_region, zone_id), topic_id
    )

client = AdminClient(cloud_region)
try:
    client.delete_topic(topic_path)
    if regional:
        print(f"{topic_path} (regional topic) deleted successfully.")
    else:
        print(f"{topic_path} (zonal topic) deleted successfully.")
except NotFound:
    print(f"{topic_path} not found.")

라이트 주제를 삭제하면 라이트 주제에 메시지를 게시할 수 없습니다. 라이트 주제에 대한 라이트 구독이 여전히 존재하지만 라이트 구독에서 메시지를 받을 수 없습니다.

다음 단계