OpenProxy
개요
OpenSQL 의 connection pooler, load-balancer, virtual-ip failover 기능을 담당하는 OpenProxy 의 설정 및 실행에 대해 설명한다.
환경 설정
해당 문서는 OpenProxy 실행될 때 설정할 수 있는 값들을 나열한다. OpenProxy를 원하는 설정 파일로 실행시키고 싶다면 OpenProxy 명령어 뒤에 설정 파일의 경로를 입력한다.
General Settings
[general] 에 선언되는 값들이다. general에 설정되는 값들은 port와 같은 네트워크 설정, OpenProxy의 admin 이름과 패스워드 등을 설정한다.
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]
섹션 밑에 설정한다. 사용하지 않는 경우에는 해당 섹션을 제거한다.
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. BACKUP
→ MASTER
승격이 일어날 때 가상 IP 점유에 앞서 실행할 OS 명령어를 지정할 수 있다.
pre_demote_script
String
-
Optional. MASTER
→ BACKUP
강등이 일어날 때 가상 IP 해제에 앞서 실행할 OS 명령어를 지정할 수 있다.
unicast_peers
Array
-
Optional. 멀티캐스트가 지원되지 않는 네트워크 환경인 경우 VRRP 패킷을 유니캐스트 방식으로 보낼 수 있으며 모든 Peer 가상 라우터 노드의 IPv4 주소를 쉼표,
로 구분되는 배열 형태로 [“192.168.0.6", “192.168.0.8"]
처럼 기입한다.
Pools
[pools.{pool_name}]
새로운 connection을 추가하고 싶다면 [pools] 에 추가한다.
pool_mode
Enum
transaction
OpenProxy의 Pooling 모드를 이 Pool 단위에서 설정하며 session
모드와 transaction
모드를 지원한다. session
모드에서는 하나의 Client 연결에 대하여 하나의 PostgreSQL 서버 연결이 제공되며 transaction
모드에서는 각 Client 트랜잭션이 여러 PostgreSQL 서버 연결에서 나누어 처리된다.
load_balancing_mode
Enum
random
Replica 노드들에 대하여 Load balancing할 알고리즘을 지정하며 random
과 loc
를 지원한다. 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] 하위 항목에 사용자 관련 항목을 등록한다.
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 주소를 정의해야 한다.
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-password
는postgres
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