Triển khai TimescaleDB trên Kubernetes
Đầu năm mới, chúc toàn thể Viblo-er một năm mới tấn tài, tấn lộc, tấn công được nhiều bug.
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
- Sử dụng Hypertables để xử lý time-series data
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 region để lấy dữ liệu và tự động chọn region 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 WAL này đối với cơ sở dữ liệu chính để đạ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 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ỏ và được gọi là Automatic Failover. Automatic Failover đề cập đến một cơ chế mà hệ thống phát hiện khi một primary database bị lỗi, nó sẽ bị loại bỏ hoàn toàn khỏi vòng quay, chuyển một bản sao read-only sang trạng thái primary ngay lập tức 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 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, Zookeeper, Consul và Kubernetes API được hỗ trợ bởi etcd, 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 short TTL đượ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. Những trường hợp có thể xảy ra:
- (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 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 TimescaleDB pod bạn cần chạy lệnh kubectl get sc
để kiểm tra xem Kubernetes đã có storage provisioner 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 apply -f dev-manifest.yaml
tạo 1 statefulset TimescaleDB
Chạy lệnh kubectl get pod
để check xem TimescaleDB pod đã running hay chưa
Truy cập vào trong TimescaleDB pod bằng lệnh:
kubectl exec -it ovng-timescaledb-0 -- /bin/bash
Kiểm tra xem TimescaleDB cluster đã có Leader hay chưa sử dụng patronictl
patronictl list
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:
psql -h 127.0.0.1 -U postgres
5. Phần kết luận
That’s all folks! Trong bài viết này mình đã chia sẻ cho các bạn về ưu điểm của TimescaleDB - Một cơ sở dữ liệu quan hệ dựa trên kiến trúc cloud-native hiện đại, được tối ưu cho xử lý time-series data. Mình cũng đã trình bày hướng dẫn chi tiết về cách triển khai Zalando PostgreSQL Operator trên Kubernetes. Mình hy vọng các bạn thấy bài viết này bổ ích.
All rights reserved