자습서: 탄력적 클러스터를 사용하는 마이크로 서비스 디자인

이 자습서에서는 여러 마이크로 서비스에 대한 스토리지 백 엔드로 Azure Database for PostgreSQL을 사용합니다. 이 자습서에서는 이러한 클러스터의 샘플 설정 및 기본 작업을 보여 줍니다. 알아보기:

  • 필수 조건
  • 마이크로 서비스에 대한 역할 만들기
  • psql 유틸리티를 사용하여 역할 및 분산 스키마 만들기
  • 샘플 서비스에 대한 테이블 만들기
  • 서비스 구성
  • 서비스 실행
  • 데이터베이스 탐색

필수 조건

다음 방법 중 하나로 탄력적 클러스터를 만듭니다.

마이크로 서비스에 대한 역할 만들기

분산 스키마를 탄력적 클러스터 내에 동적으로 배치할 수 있습니다. 시스템은 사용 가능한 노드에서 전체 단위로 균형을 조정할 수 있으므로 수동 할당 없이 클러스터 리소스 전체에서 효율성을 향상시킬 수 있습니다.

마이크로 서비스 디자인 패턴에 스키마 분할을 적용할 때 각 해당 마이크로 서비스에 대한 데이터베이스 스키마를 만듭니다. 또한 데이터베이스에 연결할 때 각 마이크로 서비스에 대해 고유한 ROLE을 사용합니다. 각 사용자가 연결할 때 해당 역할 이름은 search_path 시작 부분에 표시됩니다. 역할 이름이 스키마 이름과 일치하는 경우 올바른 search_path 설정하기 위해 추가 애플리케이션을 변경할 필요가 없습니다.

이 예제에서는 세 개의 마이크로 서비스를 사용합니다.

  • 사용자
  • time
  • ping

각 서비스에 대한 데이터베이스 역할을 만듭니다.

CREATE USER user_service;
CREATE USER time_service;
CREATE USER ping_service;

psql 유틸리티를 사용하여 분산 스키마 만들기

psql을 사용하여 탄력적 클러스터에 연결한 후 몇 가지 기본 작업을 완료할 수 있습니다.

스키마는 다음 두 가지 방법으로 배포할 수 있습니다.

  • 수동으로 citus_schema_distribute(schema_name) 함수를 호출합니다.
CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

SELECT citus_schema_distribute('user_service');
SELECT citus_schema_distribute('time_service');
SELECT citus_schema_distribute('ping_service');

이 메서드를 사용하면 기존 일반 스키마를 분산 스키마로 변환할 수도 있습니다.

비고

분산 테이블 및 참조 테이블이 포함되지 않은 스키마만 배포할 수 있습니다.

  • 구성 변수를 citus.enable_schema_based_sharding 사용하도록 설정합니다. 현재 세션의 변수를 변경하거나 코디네이터 노드 매개 변수에서 영구적으로 변경할 수 있습니다. 매개 변수를 ON으로 설정하면 생성된 모든 스키마가 기본적으로 배포됩니다.
SET citus.enable_schema_based_sharding TO ON;

CREATE SCHEMA AUTHORIZATION user_service;
CREATE SCHEMA AUTHORIZATION time_service;
CREATE SCHEMA AUTHORIZATION ping_service;

다음 명령을 실행하여 현재 분산된 스키마를 나열합니다.

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             5 | 0 bytes     | user_service
 time_service |             6 | 0 bytes     | time_service
 ping_service |             7 | 0 bytes     | ping_service
(3 rows)

샘플 서비스에 대한 테이블 만들기

이제 모든 마이크로 서비스에 대한 탄력적 클러스터에 연결할 수 있습니다. 다음 예제에서 탄력적 클러스터 데이터베이스의 이름은 Citus입니다. psql 세션에서 \c 명령을 사용하여 다른 사용자로 교환할 수 있습니다.

\c citus user_service
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);
\c citus time_service
CREATE TABLE query_details (
    id SERIAL PRIMARY KEY,
    ip_address INET NOT NULL,
    query_time TIMESTAMP NOT NULL
);
\c citus ping_service
CREATE TABLE ping_results (
    id SERIAL PRIMARY KEY,
    host VARCHAR(255) NOT NULL,
    result TEXT NOT NULL
);

서비스 구성

이 자습서에서는 간단한 서비스 집합을 사용합니다. 다음 공용 리포지토리를 복제하여 가져올 수 있습니다.

git clone https://github.com/citusdata/citus-example-microservices.git
$ tree
.
├── LICENSE
├── README.md
├── ping
│   ├── app.py
│   ├── ping.sql
│   └── requirements.txt
├── time
│   ├── app.py
│   ├── requirements.txt
│   └── time.sql
└── user
    ├── app.py
    ├── requirements.txt
    └── user.sql

서비스를 실행하기 전에 user/app.py, ping/app.py, 및 time/app.py 파일을 편집하여 탄력적 클러스터에 대한 연결 구성을 제공합니다.

# Database configuration
db_config = {
    'host': 'EXAMPLE.postgres.database.azure.com',
    'database': 'postgres',
    'password': 'SECRET',
    'user': 'ping_service',
    'port': 5432
}

변경 후 수정된 파일을 모두 저장하고 서비스 실행의 다음 단계로 이동합니다.

서비스 실행

모든 앱 디렉터리로 변경하고 자체 Python 환경에서 실행합니다.

cd user
pipenv install
pipenv shell
python app.py

시간 및 ping 서비스에 대한 명령을 반복한 후 API를 사용할 수 있습니다.

일부 사용자를 만듭니다.

curl -X POST -H "Content-Type: application/json" -d '[
  {"name": "John Doe", "email": "john@example.com"},
  {"name": "Jane Smith", "email": "jane@example.com"},
  {"name": "Mike Johnson", "email": "mike@example.com"},
  {"name": "Emily Davis", "email": "emily@example.com"},
  {"name": "David Wilson", "email": "david@example.com"},
  {"name": "Sarah Thompson", "email": "sarah@example.com"},
  {"name": "Alex Miller", "email": "alex@example.com"},
  {"name": "Olivia Anderson", "email": "olivia@example.com"},
  {"name": "Daniel Martin", "email": "daniel@example.com"},
  {"name": "Sophia White", "email": "sophia@example.com"}
]' http://localhost:5000/users

만들어진 사용자를 나열합니다.

curl http://localhost:5000/users

현재 시간 가져오기:

Get current time:

example.com에 대해 ping을 실행합니다.

curl -X POST -H "Content-Type: application/json" -d '{"host": "example.com"}' http://localhost:5002/ping

데이터베이스 탐색

이제 일부 API 함수를 호출했으므로 데이터가 저장되었으며, citus_schemas이 예상한 대로 반영되었는지 확인할 수 있습니다.

SELECT * FROM citus_schemas;
 schema_name | colocation_id | schema_size | schema_owner
-------------+---------------+-------------+--------------
 user_service |             1 | 112 kB      | user_service
 time_service |             2 | 32 kB       | time_service
 ping_service |             3 | 32 kB       | ping_service
(3 rows)

스키마를 만들 때 스키마를 만들 컴퓨터를 지정하지 않았습니다. 자동으로 수행되었습니다. 다음 쿼리를 사용하면 각 스키마가 어디에 있는지 확인할 수 있습니다.

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
nodename  | nodeport |         table_name         | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
 localhost |     7002 | ping_service.ping_results  | 32 kB

이 페이지의 예제 출력의 간결성을 위해, nodename을 IP 주소 대신 localhost로 대체했습니다. localhost:7001을 노드 1, localhost:7002를 노드 2라고 가정합니다.

시간 서비스가 localhost:7001 노드에 할당되고, 사용자 및 ping 서비스가 두 번째 노드 localhost:7002에서 함께 실행되는 것을 확인할 수 있습니다. 예제 앱은 단순하며 여기에 있는 데이터 크기는 중요하지 않지만 노드 간의 균일하지 않은 스토리지 공간 사용률의 영향을 받는다고 가정해 보겠습니다. 큰 사용자 서비스가 자체 노드에 있는 동안 두 개의 더 작은 시간과 ping 서비스가 한 노드에 상주하도록 하는 것이 더 합리적입니다.

디스크 크기에 따라 클러스터의 균형을 쉽게 리밸런싱할 수 있습니다.

SELECT citus_rebalance_start();
NOTICE:  Scheduled 1 moves as job 1
DETAIL:  Rebalance scheduled as background job
HINT:  To monitor progress, run: SELECT * FROM citus_rebalance_status();
 citus_rebalance_start
-----------------------
                     1
(1 row)

완료되면 새 레이아웃이 어떻게 보이는지 확인할 수 있습니다.

  SELECT nodename,nodeport, table_name, pg_size_pretty(sum(shard_size))
  FROM citus_shards
  GROUP BY nodename,nodeport, table_name;
 nodename  | nodeport |         table_name        | pg_size_pretty
-----------+----------+---------------------------+----------------
 localhost |     7001 | time_service.query_details | 32 kB
 localhost |     7001 | ping_service.ping_results  | 32 kB
 localhost |     7002 | user_service.users         | 112 kB
(3 rows)

예상대로 스키마가 이동되었으며, 클러스터가 보다 균형 있게 구성되었습니다. 이 작업은 애플리케이션에 투명하게 처리됩니다. 다시 시작할 필요도 없고 쿼리를 계속 제공합니다.

다음 단계