1. TimescaleDB là gì?
TimescaleDB là một tiện ích mở rộng của PostgreSQL nhằm cải thiện 3 điểm chính sau đây:
- Hiệu suất tốt hơn khi scale trên quy mô lớn
- Chi phí lưu trữ thấp hơn
- Bao gồm một thư viện với hơn 100 Hyperfuntions
Bên cạnh các ưu điểm này, TimescaleDB gần như giống PostgreSQL thông thường. Đó là bởi vì TimescaleDB là một tiện ích mở rộng, không phải là một nhánh rẽ. Điều này có nghĩa, bạn vẫn có thể cài đặt các tiện ích mở rộng PostgreSQL khác, tận dụng toàn bộ hệ thống sẵn có và hưởng lợi từ hệ sinh thái PostgreSQL đa dạng.
2. High Availability trong TimescaleDB
Nếu bạn đang làm việc với cơ sở dữ liệu, bạn đã biết rằng High Availability (HA) là một yêu cầu đối với bất kỳ hệ thống đáng tin cậy nào. Thiết lập HA phù hợp giúp loại bỏ vấn đề về single point-of-failure bằng cách cung cấp nhiều nơi để lấy cùng một dữ liệu và cách tự động chọn vị trí thích hợp để đọc và ghi dữ liệu. PostgreSQL thường đạt được HA bằng cách replicating dữ liệu trên primary database thành một hoặc nhiều bản sao read-only.
Streaming replication là phương pháp replication chính được hỗ trợ bởi TimescaleDB. Nó hoạt động bằng cách để máy chủ cơ sở dữ liệu chính truyền thông các write-ahead log (WAL) tới các bản sao cơ sở dữ liệu của nó. Sau đó, mỗi bản sao sẽ truyền thông lại các mục nhật ký này đối với primary database để đạt đến trạng thái nhất quán với cơ sở dữ liệu chính.
Thật không may, chỉ riêng việc Streaming replication như vậy không đảm bảo rằng người dùng không gặp phải tình trạng mất thời gian hoạt động (“High Availability”) khi máy chủ gặp sự cố. Nếu nút chính bị lỗi hoặc không thể truy cập được, thì cần phải có một phương pháp để thúc đẩy một trong các bản sao chỉ có quyền đọc trở thành nút Leader mới. Và quá trình Automatic Failover này xảy ra càng nhanh thì thời gian trống mà người dùng phải đợi sẽ càng nhỏ. Một cách tiếp cận đơn giản để thúc đẩy quá trình promotion là thực hiện thủ công thông qua một số lệnh PostgreSQL. Mặt khác, Automatic Failover đề cập đến một cơ chế mà hệ thống phát hiện khi một bản sao chính bị lỗi, loại bỏ hoàn toàn nó khỏi vòng quay, chuyển một bản sao read-only sang trạng thái primary và đảm bảo phần còn lại nhận biết được của trạng thái mới của hệ thống.
Có một số giải pháp của bên thứ ba cung cấp HA và Automatic Failover cho PostgreSQL, nhiều giải pháp trong số đó hoạt động tốt với TimescaleDB vì chúng tận dụng khả năng streaming replication. Trong bài viết này mình chọn Patroni vì kiến trúc đơn giản và thực hiện cân bằng tải theo hướng tiếp cận theo mô-đun hóa. Patroni thực hiện health checks trên các nút PostgreSQL và cho phép bạn sử dụng Kubernetes, AWS ELB, HA Proxy hoặc một giải pháp proxy khác để xử lý cân bằng tải.
3. Tìm hiểu về Patroni
Core architecture của Patroni như sau:
Mỗi nút PostgreSQL có một bot Patroni được triển khai trên đó. Các bot có khả năng vừa quản lý cơ sở dữ liệu PostgreSQL vừa cập nhật hệ thống đồng thuận phân tán (etcd trong trường hợp này mặc dù Zookeeper, Consul và Kubernetes API, được hỗ trợ bởi etcd, cũng là những tùy chọn hoàn toàn tốt). etcd phải được triển khai theo thuật toán đồng thuận dựa trên Raft. Điều này yêu cầu triển khai tối thiểu 3 nút etcd.
Bầu chọn nút Leader được thực hiện bằng cách tạo expiring key trong etcd. Nút PostgreSQL đầu tiên tạo· khóa etcd thông qua bot Patroni của nó sẽ trở thành primary. Tất cả các nút khác sẽ thấy rằng một nút chính đã được chọn và các bot Patroni sẽ thiết lập các phiên bản PostgreSQL dưới dạng bản sao.
primary key có một TTL ngắn được đính kèm với nó. Bot Patroni primary phải liên tục kiểm tra tình trạng phiên bản PostgreSQL của nó và cập nhật primary key. Nếu điều này không xảy ra vì:
- (a) nút mất kết nối
- (b) cơ sở dữ liệu bị lỗi
- (c) bot chết, khóa sẽ hết hạn
Điều này sẽ khiến primary key bị xóa hoàn toàn khỏi cụm. Khi các bản sao thấy rằng không có khóa chính, mỗi bản sao sẽ cố gắng trở thành khóa chính thông qua trao đổi thông tin giữa các bot Patroni. Sau đó, các bot sẽ chọn một ứng cử viên rõ ràng để thăng hạng hoặc cả hai sẽ chạy đua để được thăng hạng Primary.
Bạn có thể xem ví dụ minh họa ở đây:
4. Triển khai Patroni TimescaleDB trên Kubernetes
Trước khi bắt đầu với triển khai, chúng ta cần chuẩn bị Git repository:
git clone https://github.com/zalando/postgres-operator.git
cd postgres-operator
Tạo file values dev-values.yaml
với nội dung sau:
configGeneral: docker_image: registry.opensource.zalan.do/acid/spilo-14:2.1-p3
configKubernetes: enable_pod_antiaffinity: true watched_namespace: "default"
Dùng helm để install chart postgres-operator
với file values đã tạo:
helm install postgres-operator ./charts/postgres-operator -f dev-values.yaml
Chạy lệnh kubectl get pod
để check xem operator pod đã running hay chưa
Tiếp theo, để tạo các pod TimescaleDB bạn cần chạy lệnh kubectl get sc
để kiểm tra xem Kubernetes đã có storage providers hay chưa
Tạo file values dev-manifest.yaml
với nội dung sau:
apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata: name: dev-timescaledb namespace: default
spec: dockerImage: registry.opensource.zalan.do/acid/spilo-14:2.1-p3 teamId: "dev" volume: size: 10Gi storageClass: local-path numberOfInstances: 1 enableConnectionPooler: false # enable/disable connection pooler deployment postgresql: version: "14" parameters: # Expert section max_connections: "200" timescaledb.max_background_workers: "16" timescaledb.license: "timescale" max_parallel_workers: "16" max_worker_processes: "32" patroni: pg_hba: - local all all trust - hostssl all +zalandos 127.0.0.1/32 pam - host all all 0.0.0.0/0 md5 - hostssl all +zalandos ::1/128 pam - host all all ::1/128 md5 - local replication standby trust - hostssl replication standby all md5 - hostssl all +zalandos all pam - hostssl all all all md5
Chạy lệnh kubectl get pod
để check xem TimescaleDB pod đã running hay chưa
Exec vào trong pod TimescaleDB bằng lệnh
kubectl exec -it ovng-timescaledb-0 -- /bin/bash
Verifying xem PostgreSQL đã cài đúng version và có Leader hay chưa sử dụng patronictl
Lấy mật khẩu TimescaleDB bằng lệnh
kubectl get secret/postgres.dev-timescaledb.credentials.postgresql.acid.zalan.do -o yaml
.
Bạn có thể dùng một số web-based tool để decode password Ở đây
Truy cập vào database và tạo một testdb