Postgres có tính sẵn sàng cao với Patroni/ Spilo (Phần 1)
Bất kỳ hệ thống nào, cho dù là Ứng dụng, Trang web, Công nhân/Người tiêu dùng, Cơ sở dữ liệu, … khi được xem là quan trọng thì công việc cần đảm bảo tính sẵn sàng cao (Tính sẵn sàng cao) vẫn luôn là tiêu chuẩn được đưa ra mỗi khi khai triển. Ngày hôm nay, mình muốn nói về High Availability cho Postgres bởi vì:
- Postgres chưa được hỗ trợ chính thức cho High Availability
- Có rất nhiều công cụ hỗ trợ của bên thứ 3 để xây dựng hệ thống Tính sẵn sàng cao cho Postgres
Trong khoảng thời gian gần đây, cô ấy đã tìm thấy một bài toán liên quan đến Postgres và yêu cầu bài toán là xây dựng phương án, giải pháp cho công việc Postgres có thể lăn ra dừng hoạt động bất cứ lúc nào. Sau khi tham khảo ý kiến của anh em System/ Cloud Engineer hay Devops thì mình thấy công việc sử dụng Patroni (Spilo) là một giải pháp hoàn thiện để xây dựng hệ thống High Availability cho Postgres.
Vậy thì cách phát triển khai báo và kết nối ở đây như thế nào?
1. Patroni/ Spilo là gì?
Theo như tài liệu thì Patroni được mô tả như sau:
Patroni là mẫu dành cho các giải pháp PostgreSQL có tính sẵn sàng cao (HA) sử dụng Python. Patroni có nguồn gốc là một nhánh của Thống đốc , một dự án từ Compose. Nó bao gồm nhiều tính năng mới
và Spilo được mô tả như sau:
Để biết ví dụ về triển khai dựa trên Docker với Patroni, hãy xem Spilo , hiện đang được sử dụng tại Zalando.
Tóm tắt lại, Patroni được sử dụng để phát triển HA cho Postgres. Tuy nhiên, theo đánh giá của mình thì Spilo nên được lựa chọn là phương án phát triển mà chúng ta ưu tiên sử dụng.
2. Khai báo Mô hình phát triển
Dưới đây là mô hình mà mình sẽ thực hiện phát triển khai:
in which:
- ETCD là thành phần khóa phân phối được sử dụng cho Patroni và được cấu hình kết nối với nhau như một cụm ETCD
Các thành phần Postgres, Patroni & ETCD được cài đặt cùng nhau trên một máy chủ nhắm mục tiêu cho việc phức hợp hóa mô hình hệ thống và tiết kiệm chi phí, giảm thiểu rủi ro phát hiện sinh học trong tương lai.
2. Cấu hình
2.1 Khởi tạo ban đầu
- Sau khi chúng tôi cài đặt cụm ETCD và Postgres thành công. Chúng ta có thể cài đặt bảo trợ như sau:
apt -y install python3 python3-pip python3-dev libpq-dev pip3 install setuptools psycopg2>=3.0.0 patroni[etcd3,raft]
- Tạo dịch vụ tập tin
/lib/systemd/system/patroni.service
cho người bảo trợ[Unit] Description=Runners to orchestrate a high-availability PostgreSQL After=network.target ConditionPathExists=/etc/patroni/config.yml [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=~ # Pre-commands to start watchdog device # Uncomment if watchdog is part of your patroni setup #ExecStartPre=-/usr/bin/sudo /sbin/modprobe softdog #ExecStartPre=-/usr/bin/sudo /bin/chown postgres /dev/watchdog # Start the patroni process ExecStart=/usr/bin/patroni /etc/patroni/config.yml # Send HUP to reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # only kill the patroni process, not it's children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=30 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target
Tạo file config
/etc/patroni/config.yml
cho người bảo trợ như saubootstrap: dcs: failsafe_mode: true loop_wait: 15 maximum_lag_on_failover: 33554432 postgresql: parameters: archive_command: test ! -f /var/lib/postgresql/data/wal_archive/%f && cp %p /var/lib/postgresql/data/wal_archive/%f archive_mode: 'on' archive_timeout: 1800s datestyle: iso, mdy default_text_search_config: pg_catalog.english effective_cache_size: 512MB hot_standby: 'on' lc_messages: en_US.UTF-8 lc_monetary: en_US.UTF-8 lc_numeric: en_US.UTF-8 lc_time: en_US.UTF-8 log_destination: stderr log_directory: /var/log/postgresql log_file_mode: 384 log_filename: postgresql.log log_line_prefix: '%t [%p]: [%l-1] %c %x %d %u %a %h ' log_rotation_age: 1d log_rotation_size: 100MB log_timezone: Etc/UTC log_truncate_on_rotation: 'on' logging_collector: 'on' max_connections: 200 max_wal_size: 1GB min_wal_size: 80MB timezone: Etc/UTC update_process_title: 'off' wal_keep_size: 1600MB wal_log_hints: 'on' use_pg_rewind: true use_slots: true retry_timeout: 15 ttl: 45 initdb: - encoding: UTF8 - locale: en_US.UTF-8 - data-checksums etcd3: hosts: - ETCD_IPAddress1:2379 - ETCD_IPAddress2:2379 - ETCD_IPAddress3:2379 log: dir: /var/log/postgresql postgresql: authentication: replication: password: <password> username: replicator rewind: password: <password> username: replicator superuser: password: <password> username: superuser connect_address: <IPAddress>:5432 bin_dir: /usr/lib/postgresql/15/bin config_dir: /etc/postgresql/15/main data_dir: /var/lib/postgresql/15/main listen: '*:5432' name: <node_name> parameters: listen_addresses: '*' log_autovacuum_min_duration: 0 log_checkpoints: false log_connections: false log_disconnections: false max_stack_depth: 7MB port: 5432 shared_buffers: 102MB unix_socket_directories: /var/run/postgresql wal_buffers: -1 wal_sync_method: fsync pg_hba: - local all postgres trust - local replication postgres trust - local all all trust - local replication replicator trust - host all all ::1/128 md5 - host all postgres 127.0.0.1/32 trust - host all postgres ::1/128 trust - host all postgres all reject - host replication replicator 0.0.0.0/0 md5 - hostnossl all postgres all reject - hostssl all +cloud 127.0.0.1/32 pam - hostssl all +cloud ::1/128 pam - hostssl all +cloud all pam - hostssl all all all md5 - hostssl replication replicator 0.0.0.0/0 md5 pgpass: /run/postgresql/pgpass use_unix_socket: true use_unix_socket_repl: true restapi: authentication: password: <pasword> username: postgres connect_address: <IPAddress>:8008 listen: :8008 scope: postgres-patroni
Lưu ý :
- bạn cần phải tạo các người dùng/vai trò tương ứng trong cơ sở dữ liệu với thông báo khai báo thông tin ở:
postgresql.authentication
. Chi tiết về các tùy chọn cấu hình có thể tìm thấy ở đây . Thông tin về người dùng/ vai trò trên các nút phải giống nhau - cần phải khai báo giá trị đúng của
postgresql.bin_dir
,postgresql.data_dir
&postgresql.config_dir
đang có trên máy chủ thực thi - Cần thay đổi địa chỉ IP tương ứng của các nút
IPAddress
- bạn cần phải tạo các người dùng/vai trò tương ứng trong cơ sở dữ liệu với thông báo khai báo thông tin ở:
- Thực hiện bắt đầu bảo trợ
systemctl daemon-reload systemctl start patroni systemctl enable patroni
- Lúc này, họ đã khởi động được một nhóm trưởng
patronictl --config-file /etc/patroni/config.yml list + Cluster: postgres-patroni ------------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | +-----------------------------+---------------+---------+---------+----+-----------+ | postgres-patroni-cb5o3izc | 10.20.161.208 | Leader | running | 1 | | +-----------------------------+---------------+---------+---------+----+-----------+
2.2 Khởi tạo Postgres Cluster
Trên các nút vẫn thực hiện tương tự như bước 2.1 ở trên nhưng lưu ý, chúng ta cần phải cấu hình giống nhau về postgresql.authentication
và scope
. Tuy nhiên, để có thể khởi tạo cụm và kết nối các nút với nhau, chúng ta cần phải đảm bảo các thư mục data_dir
giống nhau. Chúng tôi có thể thực hiện xóa thư mục này hoặc sao chép từ nút trưởng sang. Ví dụ:
rm -rf /var/lib/postgresql/15/main
Khi khởi động máy chủ, máy chủ sẽ thực hiện sao lưu và đồng bộ hóa thư mục này với lệnh thông qua nút lãnh đạo pg_basebackup
.
Để kiểm tra xem cài đặt thành công hay không, chúng tôi có thể sử dụng lệnh sau:
patronictl --config-file /etc/patroni/config.yml list + Cluster: postgres-patroni ------------------+---------+---------+----+-----------+ | Member | Host | Role | State | TL | Lag in MB | +-----------------------------+---------------+---------+---------+----+-----------+ | postgres-patroni-cb5o3izc | 10.20.161.208 | Leader | running | 1 | | | postgres-patroni-jubx88ye-1 | 10.20.161.253 | Replica | running | 1 | 0 | | postgres-patroni-jubx88ye-2 | 10.20.161.174 | Replica | running | 1 | 0 | +-----------------------------+---------------+---------+---------+----+-----------+
Như vậy, cơ bản, chúng tôi đã cấu hình xong High Availability cho Postgres.
2.3 Kiểm tra chuyển đổi dự phòng
Khi chúng tôi dừng một máy chủ cơ sở dữ liệu bất kỳ đang làm lãnh đạo, ngay lập tức sẽ có một nút cơ sở dữ liệu khác được tự động thúc đẩy làm mới lãnh đạo. Lúc này, chúng ta cần phải cập nhật lại cấu hình của ứng dụng để thay đổi cấu hình địa chỉ cho DB.
Như vậy, chúng tôi đã có được Tính sẵn sàng cao cho Cơ sở dữ liệu nhưng chưa được sử dụng cho ứng dụng. Làm cách nào để có thể thực hiện được điều này? Chúng ta sẽ theo dõi phần tiếp theo Postgres có tính sẵn sàng cao với Patroni/ Spilo (Phần 2)