+4

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: patroni.jpeg

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: image.png

4. Triển khai Patroni TimescaleDB trên Kubernetes

image.png

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 image.png

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 image.png

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 image.png

Truy cập vào trong TimescaleDB pod bằng lệnh:

kubectl exec -it ovng-timescaledb-0 -- /bin/bash

image.png

Kiểm tra xem TimescaleDB cluster đã có Leader hay chưa sử dụng patronictl patronictl list image.png

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 image.png

Truy cập vào database và tạo một testdb: psql -h 127.0.0.1 -U postgres image.png

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí