mirror of
https://github.com/postgresml/pgcat.git
synced 2026-03-27 18:56:30 +00:00
Handle SIGTERM. Add docker-compose.yml (#59)
* docker-compsoe * remove statsd config * readme
This commit is contained in:
@@ -29,9 +29,6 @@ healthcheck_timeout = 100
|
|||||||
# For how long to ban a server if it fails a health check (seconds).
|
# For how long to ban a server if it fails a health check (seconds).
|
||||||
ban_time = 60 # Seconds
|
ban_time = 60 # Seconds
|
||||||
|
|
||||||
# Stats will be sent here
|
|
||||||
statsd_address = "127.0.0.1:8125"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# User to use for authentication against the server.
|
# User to use for authentication against the server.
|
||||||
[user]
|
[user]
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ COPY --from=builder /app/target/release/pgcat /usr/bin/pgcat
|
|||||||
COPY --from=builder /app/pgcat.toml /etc/pgcat/pgcat.toml
|
COPY --from=builder /app/pgcat.toml /etc/pgcat/pgcat.toml
|
||||||
WORKDIR /etc/pgcat
|
WORKDIR /etc/pgcat
|
||||||
ENV RUST_LOG=info
|
ENV RUST_LOG=info
|
||||||
ENTRYPOINT ["/usr/bin/pgcat"]
|
CMD ["pgcat"]
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover support.
|
Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover support.
|
||||||
|
|
||||||
**Alpha**: looking for alpha testers, see [#35](https://github.com/levkk/pgcat/issues/35).
|
**Beta**: looking for beta testers, see [#35](https://github.com/levkk/pgcat/issues/35).
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
| **Feature** | **Status** | **Comments** |
|
| **Feature** | **Status** | **Comments** |
|
||||||
@@ -24,8 +24,16 @@ Meow. PgBouncer rewritten in Rust, with sharding, load balancing and failover su
|
|||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
See `Dockerfile` for example deployment using Docker. The pooler is configured to spawn 4 workers so 4 CPUs are recommended for optimal performance.
|
See `Dockerfile` for example deployment using Docker. The pooler is configured to spawn 4 workers so 4 CPUs are recommended for optimal performance. That setting can be adjusted to spawn as many (or as little) workers as needed.
|
||||||
That setting can be adjusted to spawn as many (or as little) workers as needed.
|
|
||||||
|
For quick local example, use the Docker Compose environment provided:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up
|
||||||
|
|
||||||
|
# In a new terminal:
|
||||||
|
psql -h 127.0.0.1 -p 6432 -c 'SELECT 1'
|
||||||
|
```
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
|
|
||||||
|
|||||||
16
docker-compose.yml
Normal file
16
docker-compose.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
version: "3"
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:13
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: md5
|
||||||
|
pgcat:
|
||||||
|
build: .
|
||||||
|
command:
|
||||||
|
- "pgcat"
|
||||||
|
- "/etc/pgcat/pgcat.toml"
|
||||||
|
volumes:
|
||||||
|
- "${PWD}/examples/docker/pgcat.toml:/etc/pgcat/pgcat.toml"
|
||||||
|
ports:
|
||||||
|
- "6432:6432"
|
||||||
105
examples/docker/pgcat.toml
Normal file
105
examples/docker/pgcat.toml
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#
|
||||||
|
# PgCat config example.
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# General pooler settings
|
||||||
|
[general]
|
||||||
|
|
||||||
|
# What IP to run on, 0.0.0.0 means accessible from everywhere.
|
||||||
|
host = "0.0.0.0"
|
||||||
|
|
||||||
|
# Port to run on, same as PgBouncer used in this example.
|
||||||
|
port = 6432
|
||||||
|
|
||||||
|
# How many connections to allocate per server.
|
||||||
|
pool_size = 15
|
||||||
|
|
||||||
|
# Pool mode (see PgBouncer docs for more).
|
||||||
|
# session: one server connection per connected client
|
||||||
|
# transaction: one server connection per client transaction
|
||||||
|
pool_mode = "transaction"
|
||||||
|
|
||||||
|
# How long to wait before aborting a server connection (ms).
|
||||||
|
connect_timeout = 5000
|
||||||
|
|
||||||
|
# How much time to give `SELECT 1` health check query to return with a result (ms).
|
||||||
|
healthcheck_timeout = 1000
|
||||||
|
|
||||||
|
# For how long to ban a server if it fails a health check (seconds).
|
||||||
|
ban_time = 60 # Seconds
|
||||||
|
|
||||||
|
#
|
||||||
|
# User to use for authentication against the server.
|
||||||
|
[user]
|
||||||
|
name = "postgres"
|
||||||
|
password = "postgres"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Shards in the cluster
|
||||||
|
[shards]
|
||||||
|
|
||||||
|
# Shard 0
|
||||||
|
[shards.0]
|
||||||
|
|
||||||
|
# [ host, port, role ]
|
||||||
|
servers = [
|
||||||
|
[ "postgres", 5432, "primary" ],
|
||||||
|
[ "postgres", 5432, "replica" ],
|
||||||
|
# [ "127.0.1.1", 5432, "replica" ],
|
||||||
|
]
|
||||||
|
# Database name (e.g. "postgres")
|
||||||
|
database = "postgres"
|
||||||
|
|
||||||
|
[shards.1]
|
||||||
|
# [ host, port, role ]
|
||||||
|
servers = [
|
||||||
|
[ "postgres", 5432, "primary" ],
|
||||||
|
[ "postgres", 5432, "replica" ],
|
||||||
|
# [ "127.0.1.1", 5432, "replica" ],
|
||||||
|
]
|
||||||
|
database = "postgres"
|
||||||
|
|
||||||
|
[shards.2]
|
||||||
|
# [ host, port, role ]
|
||||||
|
servers = [
|
||||||
|
[ "postgres", 5432, "primary" ],
|
||||||
|
[ "postgres", 5432, "replica" ],
|
||||||
|
# [ "127.0.1.1", 5432, "replica" ],
|
||||||
|
]
|
||||||
|
database = "postgres"
|
||||||
|
|
||||||
|
|
||||||
|
# Settings for our query routing layer.
|
||||||
|
[query_router]
|
||||||
|
|
||||||
|
# If the client doesn't specify, route traffic to
|
||||||
|
# this role by default.
|
||||||
|
#
|
||||||
|
# any: round-robin between primary and replicas,
|
||||||
|
# replica: round-robin between replicas only without touching the primary,
|
||||||
|
# primary: all queries go to the primary unless otherwise specified.
|
||||||
|
default_role = "any"
|
||||||
|
|
||||||
|
|
||||||
|
# Query parser. If enabled, we'll attempt to parse
|
||||||
|
# every incoming query to determine if it's a read or a write.
|
||||||
|
# If it's a read query, we'll direct it to a replica. Otherwise, if it's a write,
|
||||||
|
# we'll direct it to the primary.
|
||||||
|
query_parser_enabled = false
|
||||||
|
|
||||||
|
# If the query parser is enabled and this setting is enabled, the primary will be part of the pool of databases used for
|
||||||
|
# load balancing of read queries. Otherwise, the primary will only be used for write
|
||||||
|
# queries. The primary can always be explicitely selected with our custom protocol.
|
||||||
|
primary_reads_enabled = true
|
||||||
|
|
||||||
|
# So what if you wanted to implement a different hashing function,
|
||||||
|
# or you've already built one and you want this pooler to use it?
|
||||||
|
#
|
||||||
|
# Current options:
|
||||||
|
#
|
||||||
|
# pg_bigint_hash: PARTITION BY HASH (Postgres hashing function)
|
||||||
|
# sha1: A hashing function based on SHA1
|
||||||
|
#
|
||||||
|
sharding_function = "pg_bigint_hash"
|
||||||
@@ -29,9 +29,6 @@ healthcheck_timeout = 1000
|
|||||||
# For how long to ban a server if it fails a health check (seconds).
|
# For how long to ban a server if it fails a health check (seconds).
|
||||||
ban_time = 60 # Seconds
|
ban_time = 60 # Seconds
|
||||||
|
|
||||||
# Stats will be sent here
|
|
||||||
statsd_address = "127.0.0.1:8125"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# User to use for authentication against the server.
|
# User to use for authentication against the server.
|
||||||
[user]
|
[user]
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ pub struct General {
|
|||||||
pub connect_timeout: u64,
|
pub connect_timeout: u64,
|
||||||
pub healthcheck_timeout: u64,
|
pub healthcheck_timeout: u64,
|
||||||
pub ban_time: i64,
|
pub ban_time: i64,
|
||||||
pub statsd_address: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for General {
|
impl Default for General {
|
||||||
@@ -116,7 +115,6 @@ impl Default for General {
|
|||||||
connect_timeout: 5000,
|
connect_timeout: 5000,
|
||||||
healthcheck_timeout: 1000,
|
healthcheck_timeout: 1000,
|
||||||
ban_time: 60,
|
ban_time: 60,
|
||||||
statsd_address: String::from("127.0.0.1:8125"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,10 +196,6 @@ impl From<&Config> for std::collections::HashMap<String, String> {
|
|||||||
config.general.healthcheck_timeout.to_string(),
|
config.general.healthcheck_timeout.to_string(),
|
||||||
),
|
),
|
||||||
("ban_time".to_string(), config.general.ban_time.to_string()),
|
("ban_time".to_string(), config.general.ban_time.to_string()),
|
||||||
(
|
|
||||||
"statsd_address".to_string(),
|
|
||||||
config.general.statsd_address.to_string(),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"default_role".to_string(),
|
"default_role".to_string(),
|
||||||
config.query_router.default_role.to_string(),
|
config.query_router.default_role.to_string(),
|
||||||
|
|||||||
14
src/main.rs
14
src/main.rs
@@ -205,16 +205,14 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup shut down sequence
|
let mut term_signal = unix_signal(SignalKind::terminate()).unwrap();
|
||||||
match signal::ctrl_c().await {
|
|
||||||
Ok(()) => {
|
|
||||||
info!("Shutting down...");
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(err) => {
|
tokio::select! {
|
||||||
error!("Unable to listen for shutdown signal: {}", err);
|
_ = signal::ctrl_c() => (),
|
||||||
}
|
_ = term_signal.recv() => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
info!("Shutting down...");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format chrono::Duration to be more human-friendly.
|
/// Format chrono::Duration to be more human-friendly.
|
||||||
|
|||||||
Reference in New Issue
Block a user