OpenProxy

개요

OpenSQL 의 connection pooler, load-balancer, virtual-ip failover 기능을 담당하는 OpenProxy 의 설정 및 실행에 대해 설명한다.

환경 설정

해당 문서는 OpenProxy 실행될 때 설정할 수 있는 값들을 나열한다. OpenProxy를 원하는 설정 파일로 실행시키고 싶다면 OpenProxy 명령어 뒤에 설정 파일의 경로를 입력한다.

General Settings

[general] 에 선언되는 값들이다. general에 설정되는 값들은 port와 같은 네트워크 설정, OpenProxy의 admin 이름과 패스워드 등을 설정한다.

변수명
Type
Default
Description

host

String

0.0.0.0

OpenProxy 프로세스가 시작될 때 바인딩 되는 호스트 주소이다.

port

Number

6432

OpenProxy 프로세스가 시작될 때 바인딩 되는 port이다.

worker_threads

Number

5

실행 시 올라오는 비동기 런타임의 worker thread의 개수이다. 이것은 CPU core수와 맞도록 설정하는 것을 권장한다.

connect_timeout

Number

1000

PostgreSQL 서버와 연결할 때 적용되는 Timeout을 설정하며 단위는 밀리 초 (milliseconds) 이다.

idle_timeout

Number

600000

PostgreSQL 서버에 생성한 연결의 Idle Timeout을 지정하며 단위는 밀리 초 (milliseconds) 이다. 이 시간 동안 서버 연결이 사용되지 않으면 해당 Connection은 종료된다.

server_lifetime

Number

3600000

PostgreSQL 서버에 생성한 연결의 최대 Lifetime을 지정하며 단위는 밀리 초 (milliseconds) 이다. 생성된 연결이 이 시간만큼 지나면 사용 중이더라도 종료된다.

idle_client_in_transaction_timeout

Number

0

클라이언트 Transaction의 최대 Idle Timeout 값을 지정하며 단위는 밀리 초 (milliseconds) 이다. 0으로 설정한 경우 Timeout이 적용되지 않는다.

healthcheck_timeout

Number

1000

PostgreSQL 서버로 보내는 Healthcheck 메세지의 Timeout이며 단위는 밀리 초 (milliseconds) 이다. PostgreSQL 서버가 해당 시간 동안 응답하지 않으면 OpenProxy는 해당 서버를 Pool에서 추방 (Ban) 하고 쿼리를 보내지 않는다.

healthcheck_delay

Number

30000

PostgreSQL 서버에 Healthcheck를 수행할 간격을 지정하며 단위는 밀리 초 (milliseconds) 이다. 해당 시간 동안 아무런 활동이 없는 서버면 Healthcheck가 수행된다.

shutdown_timeout

Number

60000

OpenProxy 프로세스가 SIGINT 시그널을 받아 Gracefully Shutdown 되는 과정에서 연결 중인 Client가 있으면 해당 시간동안 클라이언트 연결이 종료되기를 기다리며 단위는 밀리 초 (milliseconds) 이다.

ban_time

Number

60

PostgreSQL 서버가 Healthcheck에 실패한 경우 해당 시간 동안 Pool에서 추방 (Ban) 되며 단위는 초 (seconds) 이다. 추방된 PostgreSQL 서버가 해당 시간만큼 지나면 다시 Pool에 포함되어 Healthcheck의 대상이 된다.

tcp_keepalives_idle

Number

5

PostgreSQL 서버로 생성한 연결을 유지할 TCP 소켓이 해당 시간동안 Idle한 경우 주기적으로 Keepalive 패킷을 보내 상태를 확인하기 시작한다. 단위는 초 (seconds) 이다.

tcp_keepalives_interval

Number

5

Keepalive 패킷을 보낼 주기로 단위는 초 (seconds) 이다.

tcp_keepalives_count

Number

5

PostgreSQL 서버로 주기적으로 보낸 Keepalive 패킷이 이 갯수만큼 응답을 받지 못하면 TCP 연결이 종료된다.

auth_type

Enum

md5

클라이언트 인증에 사용할 PostgreSQL 비밀번호 인증방식을 지정한다. md5 옵션과 scram-sha-256 옵션을 지원한다.

prepared_statements_cache_size

Number

0

Transaction 모드 Pooling을 사용하는 경우에만 유효하며 Client에서 보내는 Prepared Statement를 저장할 글로벌 Cache를 활성화하고 Cache의 크기를 지정한다. 이 옵션이 활성화되어야 Transaction pool 모드에서도 Prepared Statement를 처리할 수 있다. Prepared statements는 OpenProxy 메모리와 PostgreSQL 리소스를 사용하기 때문에 지나치게 큰 값으로 설정하지 않는 것이 권장된다.

admin_username

String

-

OpenProxy를 관리하기 위한 admin username이다.

admin_userpassword

String

-

OpenProxy를 관리할 때 사용하는 admin user의 password이다.

server_tls

Bool

false

OpenProxy에서 PostgreSQL server로의 TLS 연결이 활성화된다. PostgreSQL 또한 TLS 연결이 될 수 있도록 설정되어야 한다.

verify_server_certificate

Bool

false

만약 server_tls 가 활성화 상태라면, 서버 인증서가 유효한지 검증한다. Openproxy가 실행된 root stroe에 저장된 인증서가 아닌 “self signed certificates(자체 서명)”로의 연결을 비허용한다.

renew_interval

Number

5000

TOML 설정파일 리로딩 및 Patroni로 관리되는 Shard의 노드별 Primary / Replica 여부를 갱신하는 주기를 지정한다.

reload_toml

Bool

true

renew_interval 간격으로 TOML 설정파일을 다시 읽어 불러올 지 여부를 지정한다. false 로 설정된 경우 Patroni로 관리되는 Shard의 노드별 Role 만을 갱신한다.

dns_cache_enabled

Bool

false

활성화하면 Openproxy PostgreSQL server의 DNS를 resolve하고 cache한다.(overriding default TTL provided by system DNS servers.) 이것은 DNS로 PostgreSQL의 서버를 routing할 때 유용하다. 만약 DNS쿼리로 확인한 cache값이 이전과 변경된 경우 connection pool은 자동적으로 새로운 PostgreSQL server에 대해서 새로운 connection을 만든다.

dns_mas_ttl

Number

30

캐시 된 DNS 값을 저장하는 시간이다. 만약 만료되면 DNS 새로 고침이 시작된다.

Virtual Router

OpenProxy의 가상 IP 관련 기능을 활성화하고자 하는 경우에 [general.virtual_router] 섹션 밑에 설정한다. 사용하지 않는 경우에는 해당 섹션을 제거한다.

변수명
Type
Default
Description

interface

String

-

가상 IP를 등록할 호스트의 네트워크 인터페이스 이름.

router_id

Number

-

가상 라우터 ID로 1에서 255 까지의 값을 가질 수 있다. 동일 네트워크에서 가상 라우터 클러스터를 구분하기 위해 사용된다.

priority

Number

-

가상 라우터의 우선순위 값으로 0에서 255 사이의 값을 가진다.

advert_int

Number

-

Advert 인터벌로 단위는 초 (seconds) 이다. 해당 주기로 VRRP advertisement 패킷을 발송한다.

vip_addresses

Array

-

점유할 가상 IP 주소의 목록. [“192.168.35.200/24", "192.168.35.201/24"] 형태로 쉼표, 로 구분되며, 넷마스크 비트 길이를 포함한 IPv4 주소로 주어져야 한다.

pre_promote_script

String

-

Optional. BACKUPMASTER 승격이 일어날 때 가상 IP 점유에 앞서 실행할 OS 명령어를 지정할 수 있다.

pre_demote_script

String

-

Optional. MASTERBACKUP 강등이 일어날 때 가상 IP 해제에 앞서 실행할 OS 명령어를 지정할 수 있다.

unicast_peers

Array

-

Optional. 멀티캐스트가 지원되지 않는 네트워크 환경인 경우 VRRP 패킷을 유니캐스트 방식으로 보낼 수 있으며 모든 Peer 가상 라우터 노드의 IPv4 주소를 쉼표, 로 구분되는 배열 형태로 [“192.168.0.6", “192.168.0.8"] 처럼 기입한다.

Pools

[pools.{pool_name}]

새로운 connection을 추가하고 싶다면 [pools] 에 추가한다.

변수명
Type
Default
Description

pool_mode

Enum

transaction

OpenProxy의 Pooling 모드를 이 Pool 단위에서 설정하며 session 모드와 transaction 모드를 지원한다. session 모드에서는 하나의 Client 연결에 대하여 하나의 PostgreSQL 서버 연결이 제공되며 transaction 모드에서는 각 Client 트랜잭션이 여러 PostgreSQL 서버 연결에서 나누어 처리된다.

load_balancing_mode

Enum

random

Replica 노드들에 대하여 Load balancing할 알고리즘을 지정하며 randomloc 를 지원한다. random 은 random number generator로 어떤 replica를 사용할지 결정한다. loc 는 처리중인 Connection이 가장 적은 replica를 선택한다.

query_parser_enabled

Bool

false

Rust library인 sqlparser를 사용해서 OpenProxy 로 요청되는 모든 쿼리를 parsing 한다. 해당 변수는 pooler가 query가 read/write 를 분리하거나 sharding key를 추출하는 역할을 한다.

query_parser_read_write_splitting

Bool

false

query_parser_enabled 와 같이 활성화되면 read 쿼리는 standby, write 쿼리는 primary에 할당된다.

primary_reads_enabled

Bool

false

query_parser_enabled와 query_parser_read_write_splitting 을 같이 활성화하면, primary에도 replica와 같이 read쿼리를 분산한다.

idle_timeout

Number

-

General settings 의 idle_timeout 값을 이 Pool 단위에서 재 설정한다.

connect_timeout

Number

-

General settings 의 connect_timeout 값을 이 Pool 단위에서 재 설정한다.

Users

Openproxy의 Connection pool은 여러 사용자를 등록하여 사용할 수 있다.

사용자 구성을 사용하면 사용자별 설정과 일반 설정 및 풀 설정의 추가 재정의가 가능하다.

[pools.{pool_name}.users.0] 하위 항목에 사용자 관련 항목을 등록한다.

변수명
Type
Default
Description

username

String

-

사용자 이름이다.

password

String

-

사용자의 비밀번호이다. MD5 인증만 지원하므로 클라이언트 이에 맞는 비밀번호를 제공해야 한다.

pool_size

Number

-

PostgreSQL 의 최대 연결 수이다.

min_pool_size

Number

0

pool 에 열어 둘 PostgreSQL 의 최소 연결 개수이다. 이 값을 지정하면 새로운 클라이언트가 접속할 때 콜드 스타트 시간을 줄일 수 있다. 부하에 비해 큰 값으로 설정 시 PostgreSQL 연결 수 가 늘어나 서버 리소스가 낭비되고 다른 pool 이 이를 사용하지 못하고 차단될 수 있다.

statement_timeout

Number

0

클라이언트의 쿼리에 서버가 응답할 때까지 기다리는 최대 시간(millisecond) PostgreSQL 서버에 해당 기능이 구현되어 일반적인 경우에는 사용되지 않지만PostgreSQL 가 불안정한 경우 사용할 수 있다.

pool_mode

Enum

-

[pools.pool_name]의 pool_mode 값을 재설정한다.

server_lifetime

Number

-

General settings 의 server_lifetime 값을 재설정한다.

Shards

[pools.{pool_name}.shards.0] 하위 섹션에 접속할 database server 주소를 정의해야 한다.

변수명
Type
Default
Description

database

String

None

PostgreSQL 에 연결한 database 이름이다.

servers

Array

None

접속할 cluster db-server 주소 정보를 array 형태로 설정한다. host/IP, port, role(primary, replica, Auto) (예시)

servers = [

["10.0.0.1", 5432, "primary"],

["replica-1.internal-dns.net", 5432, "replica"],

]

use_patroni

Bool

false

vip-failover를 사용하려면 true 로 설정해야 한다.

Configuration 예제

[general]
port = 6432
admin_username = "postgres"
admin_password = "postgres"
autoreload = 5000
worker_threads = 3

[pools.postgres]
pool_mode = "transaction"
query_parser_enabled = true
query_parser_read_write_splitting = true

[pools.postgres.users.0]
username = "postgres"
password = "postgres"
server_username = "postgres"
server_password = "postgres"
pool_size = 10
statement_timeout = 0

[pools.postgres.shards.0]
database = "postgres"
servers = [
  ["172.176.0.2", 5432, "auto"],
  ["172.176.0.3", 5432, "auto"],
  ["172.176.0.4", 5432, "auto"]
]
use_patroni = true

## virtual-ip
[general.virtual_router]
interface = "eth0"
router_id = 50
priority = 50
advert_int = 3
vip_addresses = ["178.176.0.200/24"]

위 설정 예제는 다음과 같은 가정이 되어 있다.

  • 설정한 “my_database” pooler 는 PostgreSQL 과 같은 머신에서 수행

  • postgres database 가 정의되어 있다.

  • 사용자: developer , 비밀번호: very-security-passwordpostgres database 에 CONNECT 권한을 가지고 있다.


실행

CLI로 실행하기

설치한 openproxy 바이너리를 아래와 같이 실행한다. 인자로 toml 설정 파일의 경로를 지정할 수 있으며 값이 없는 경우는 실행 경로의 openproxy.toml 파일을 기본으로 참조한다.

$ ./openproxy /home/myUser/openproxy.toml

명령줄 인자로 지정할 수 있는 옵션들은 아래와 같다.

$ openproxy --help
OpenProxy: PostgreSQL pooler for OpenSQL - fork of pgCat

Usage: openproxy [OPTIONS] [CONFIG_FILE]

Arguments:
  [CONFIG_FILE]  [env: CONFIG_FILE=] [default: openproxy.toml]

Options:
      --log-target <LOG_TARGET>
          [env: LOG_TARGET=] [default: both] [possible values: file, stdout, both]
  -l, --log-level <LOG_LEVEL>
          [env: LOG_LEVEL=] [default: INFO]
      --max-logfile-num <MAX_LOGFILE_NUM>
          [env: MAX_LOGFILE_NUM=] [default: 5]
      --log-dir <LOG_DIR>
          [env: LOG_DIR=] [default: logs]
      --revision
          Print revision number
  -F, --log-format <LOG_FORMAT>
          [env: LOG_FORMAT=] [default: text] [possible values: text, structured, debug]
  -h, --help
          Print help
  -V, --version
          Print version
  • --log-target : OpenProxy 프로세스에서 작성할 로그 엔트리들을 출력할 타겟 파이프라인을 지정한다. file, stdout, both 옵션을 지원한다.

  • -l, --log-level : 작성할 로그 레벨을 정의한다. ERROR, WARN, INFO, DEBUG, TRACE 옵션을 지원한다.

  • --max-logfile-num : 보관할 로그 파일의 최대 갯수를 지정한다. 초과하는 로그 파일은 자동으로 디스크에서 삭제된다.

  • --log-dir : 로그 파일을 작성할 디렉토리 경로를 입력한다.

  • --log-format : 작성할 로그 엔트리의 형식을 지정한다. text, structured, debug 옵션을 지원한다.

위 옵션들은 환경 변수로도 정의할 수 있다. 환경 변수와 명령줄 옵션이 같이 주어진 경우 명령줄 옵션이 우선한다.

  • LOG_TARGET : 로그 타겟에 대응한다.

  • LOG_LEVEL : 로그 레벨 정의에 대응한다.

  • MAX_LOGFILE_NUM : 보관할 로그 파일의 최대 갯수에 대응한다.

  • LOG_DIR : 로그 파일을 작성할 디렉토리 경로에 대응한다.

  • LOG_FORMAT : 로그 엔트리 형식에 대응한다.

이 외에 도움말을 출력하거나 버전 정보 혹은 리비전 정보를 확인할 수 있다.

$ openproxy --help

$ openproxy --version
openproxy 0.0.2-OpenSQL-dev

$ openproxy --revision
revision number: 623

Systemd 서비스로 정의하기

[Unit]
Description=OpenProxy connection pooler - fork of postgresml's pgcat
After=network.target
StartLimitIntervalSec=0

[Service]
User=opensql
Type=simple
Restart=always
RestartSec=1
Environment=LOG_LEVEL=info
LimitNOFILE=65536
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
ExecStart=/usr/bin/openproxy /etc/openproxy.toml

[Install]
WantedBy=multi-user.target


조회 기능

OpenProxy 노드에 openproxy 데이터베이스 이름을 이용하여 admin 사용자로 PostgreSQL 연결을 맺으면 관리자 기능을 활용할 수 있다. Configuration 및 현재 활성화된 Pool 조회, Stat 정보 확인 등의 기능을 제공한다.

$ psql -h 127.0.0.1 -p 6432 -d openproxy -U postgres
openproxy=> SHOW HELP;
NOTICE:  Console usage
DETAIL:  
	SHOW HELP|CONFIG|DATABASES|POOLS|CLIENTS|SERVERS|USERS|VERSION
	SHOW LISTS
	SHOW STATS
	SET key = arg
	RELOAD
	PAUSE [<db>, <user>]
	RESUME [<db>, <user>]
	SHUTDOWN

Version 조회

openproxy=> SHOW VERSION;
         version         
-------------------------
 OpenProxy 1.0.0
(1 row)

Configuration 조회

openproxy=> SHOW CONFIG;
                       key                        |     value      | default | changeable 
--------------------------------------------------+----------------+---------+------------
 idle_client_in_transaction_timeout               | 30000          | -       | yes
 pools."postgres".users                           | postgres       | -       | yes
 prometheus_exporter_port                         | 9930           | -       | yes
 pools.postgres.query_parser_max_length           | unlimited      | -       | yes
 pools.postgres.load_balancing_mode               | random         | -       | yes
 pools."postgres".shard_count                     | 1              | -       | yes
 port                                             | 6432           | -       | no
 connect_timeout                                  | 1000           | -       | no
 healthcheck_timeout                              | 1000           | -       | yes
 pools.postgres.default_role                      | any            | -       | yes
 healthcheck_delay                                | 30000          | -       | yes
 pools.postgres.query_parser_read_write_splitting | true           | -       | yes
 pools.postgres.sharding_function                 | pg_bigint_hash | -       | yes
 ban_time                                         | 60             | -       | yes
 pools.postgres.pool_mode                         | transaction    | -       | yes
 shutdown_timeout                                 | 60000          | -       | yes
 host                                             | 0.0.0.0        | -       | no
 pools.postgres.primary_reads_enabled             | false          | -       | yes
 idle_timeout                                     | 600000         | -       | yes
 pools.postgres.query_parser_enabled              | true           | -       | yes
(20 rows)

Database 조회

openproxy=> SHOW DATABASES;
            name            |      host      | port | database | force_user | pool_size | min_pool_size | reserve_pool |  pool_mode  | max_connections | current_connections | paused | disabled 
----------------------------+----------------+------+----------+------------+-----------+---------------+--------------+-------------+-----------------+---------------------+--------+----------
 postgres_shard_0_primary   | 192.168.131.12 | 5432 | postgres | postgres   |      1100 |             0 |            0 | transaction |            1100 |                   0 |      0 |        0
 postgres_shard_0_replica_0 | 192.168.131.13 | 5432 | postgres | postgres   |      1100 |             0 |            0 | transaction |            1100 |                   0 |      0 |        0
 postgres_shard_0_replica_1 | 192.168.131.14 | 5432 | postgres | postgres   |      1100 |             0 |            0 | transaction |            1100 |                   0 |      0 |        0
(3 rows)

Pool 조회

openproxy=> SHOW POOLS;
 database  |    user     |  pool_mode  | cl_idle | cl_active | cl_waiting | cl_cancel_req | sv_active | sv_idle | sv_used | sv_tested | sv_login | maxwait | maxwait_us 
-----------+-------------+-------------+---------+-----------+------------+---------------+-----------+---------+---------+-----------+----------+---------+------------
 simple_db | simple_user | session     |       0 |         0 |          0 |             0 |         0 |       0 |       0 |         0 |        0 |       0 |          0
 postgres  | postgres    | transaction |       0 |         0 |          0 |             0 |         0 |       3 |       0 |         0 |        0 |       0 |          0
(2 rows)

Client 조회

openproxy=> SHOW CLIENTS;
 client_id  | database |   user   | application_name | state | transaction_count | query_count | error_count | age_seconds | maxwait | maxwait_us 
------------+----------+----------+------------------+-------+-------------------+-------------+-------------+-------------+---------+------------
 0x43332945 | postgres | postgres | openproxy        | idle  |                 8 |           8 |           0 |           9 |       0 |          8
 0x993A6EA2 | postgres | postgres | openproxy        | idle  |                10 |          10 |           0 |           9 |       0 |          8
 0x09CFDA65 | pgcat    | postgres | psql             | idle  |                 0 |           0 |           0 |         208 |       0 |          0
 0x1E5A084D | postgres | postgres | openproxy        | idle  |                10 |          10 |           0 |           4 |       0 |          9
(4 rows)

Server 조회

openproxy=> SHOW SERVERS;
 server_id  | database_name |   user   |        address_id        |           application_name           | state | transaction_count | query_count | bytes_sent | bytes_received | age_seconds | prepare_cache_hit | prepare_cache_miss | prepare_cache_eviction | prepare_cache_size 
------------+---------------+----------+--------------------------+--------------------------------------+-------+-------------------+-------------+------------+----------------+-------------+-------------------+--------------------+------------------------+--------------------
 0x342F491B | postgres      | postgres | postgres_shard_0_primary | DBeaver 22.3.4 - SQLEditor <Console> | idle  |                41 |          41 |      18760 |         302727 |          25 |               123 |                 82 |                      0 |                 41
(1 row)

User 조회

openproxy=> SHOW USERS;
   name   |  pool_mode  
----------+-------------
 postgres | transaction
(1 row)

List 조회

openproxy=> SHOW LISTS;
     list      | items 
---------------+-------
 databases     |     4
 users         |     2
 pools         |     4
 free_clients  |     4
 used_clients  |     0
 login_clients |     0
 free_servers  |     1
 used_servers  |     0
 dns_names     |     0
 dns_zones     |     0
 dns_queries   |     0
 dns_pending   |     0
(12 rows)

Stat 조회

openproxy=> SHOW STATS;
          instance          | database |   user   | total_xact_count | total_query_count | total_received | total_sent | total_xact_time | total_query_time | total_wait_time | total_errors | avg_xact_count | avg_query_count | avg_recv | avg_sent | avg_errors | avg_xact_time | avg_query_time | avg_wait_time 
----------------------------+----------+----------+------------------+-------------------+----------------+------------+-----------------+------------------+-----------------+--------------+----------------+-----------------+----------+----------+------------+---------------+----------------+---------------
 postgres_shard_0_primary   | postgres | postgres |               41 |                41 |         302727 |      18760 |               0 |               39 |           14152 |            0 |              0 |               0 |        0 |        0 |          0 |             0 |              0 |             0
 postgres_shard_0_replica_0 | postgres | postgres |                0 |                 0 |              0 |          0 |               0 |                0 |               0 |            0 |              0 |               0 |        0 |        0 |          0 |             0 |              0 |             0
 postgres_shard_0_replica_1 | postgres | postgres |                0 |                 0 |              0 |          0 |               0 |                0 |               0 |            0 |              0 |               0 |        0 |        0 |          0 |             0 |              0 |             0
(3 rows)

Last updated