Xử lý lỗi kết nối và xác thực phổ biến
Khắc phục lỗi Connection Refused
Lỗi này xảy ra khi Debezium Connector không thể thiết lập kết nối TCP với PostgreSQL. Nguyên nhân thường là do firewall chặn cổng 5432 hoặc PostgreSQL đang chỉ lắng nghe trên localhost.
Bước 1: Kiểm tra xem PostgreSQL có đang lắng nghe trên giao diện mạng (0.0.0.0) hay không.
Chạy lệnh kiểm tra trạng thái lắng nghe:
sudo netstat -tlnp | grep 5432
Kết quả mong đợi: Bạn thấy dòng output chứa 0.0.0.0:5432 hoặc 127.0.0.1:5432. Nếu chỉ thấy 127.0.0.1, cần cấu hình lại.
Bước 2: Sửa file cấu hình PostgreSQL để cho phép kết nối từ xa.
Mở file /etc/postgresql/16/main/postgresql.conf (thay 16 bằng version của bạn). Tìm và sửa dòng listen_addresses:
listen_addresses = '*'
Kết quả mong đợi: PostgreSQL sẽ lắng nghe trên tất cả các giao diện mạng sau khi restart.
Bước 3: Cập nhật file /etc/postgresql/16/main/pg_hba.conf để cho phép xác thực từ IP của Debezium.
host all all 0.0.0.0/0 scram-sha-256
Kết quả mong đợi: Connector có thể handshake thành công với DB.
Bước 4: Restart dịch vụ PostgreSQL để áp dụng thay đổi.
sudo systemctl restart postgresql@16-main
Kết quả mong đợi: Dịch vụ lên lại và không báo lỗi trong log.
Khắc phục lỗi Authentication Failed
Lỗi này xảy ra khi username hoặc password trong connector config không khớp với quyền truy cập của PostgreSQL, hoặc cơ chế xác thực (SCRAM-SHA-256 vs md5) không tương thích.
Bước 1: Kiểm tra lại cơ chế xác thực trong /etc/postgresql/16/main/pg_hba.conf.
Đảm bảo dòng cho phép host sử dụng scram-sha-256 (mặc định của Postgres 10+). Nếu dùng md5, Debezium có thể báo lỗi.
host all all 10.0.0.0/8 scram-sha-256
Kết quả mong đợi: Cơ chế xác thực khớp với cấu hình của Debezium.
Bước 2: Kiểm tra quyền của user trong PostgreSQL. User dùng cho CDC cần quyền REPLICATION và SELECT.
Đăng nhập vào PostgreSQL và chạy lệnh:
sudo -u postgres psql -c "ALTER USER debezium WITH REPLICATION SUPERUSER PASSWORD 'new_secure_password';"
Kết quả mong đợi: Câu lệnh trả về ALTER ROLE.
Bước 3: Cập nhật lại password trong config của Connector (dưới dạng biến môi trường hoặc file secrets tùy cách deploy).
Ví dụ cập nhật biến môi trường trong file /etc/kafka/connect-distributed.properties hoặc khi gọi API:
database.password=new_secure_password
Kết quả mong đợi: Connector reconnect thành công và bắt đầu log dòng "Connector started".
Giải quyết vấn đề Log và Tái tạo Offset
Xử lý Log bị đầy (Log Full)
PostgreSQL WAL (Write-Ahead Log) bị đầy sẽ khiến DB ngừng ghi dữ liệu, làm Debezium bị treo. Điều này xảy ra khi wal_level chưa đúng hoặc archive_mode bị lỗi.
Bước 1: Kiểm tra lượng WAL đang tích tụ.
sudo -u postgres psql -c "SELECT pg_walfile_name(pg_current_wal_lsn());"
Kết quả mong đợi: Trả về tên file WAL hiện tại.
Bước 2: Kiểm tra cấu hình max_wal_size trong /etc/postgresql/16/main/postgresql.conf.
max_wal_size = 2GB
Kết quả mong đợi: Giá trị này phải đủ lớn để chịu tải. Nếu quá nhỏ, tăng lên 4GB hoặc 8GB.
Bước 3: Nếu log đã đầy, cần tăng dung lượng disk hoặc cấu hình archive_command để tự động archive WAL.
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/16/main/pg_wal_archive/%f'
Kết quả mong đợi: PostgreSQL tự động dọn dẹp các file WAL cũ, giải phóng disk.
Bước 4: Restart PostgreSQL để áp dụng.
sudo systemctl restart postgresql@16-main
Kết quả mong đợi: Disk usage giảm và DB hoạt động bình thường.
Tái tạo Offset (Reset Offset)
Khi Debezium mất track offset (do reset DB hoặc lỗi Kafka), bạn cần reset offset để bắt đầu lại từ đầu hoặc từ một checkpoint cụ thể.
Bước 1: Xóa topic offset của Debezium trong Kafka. Topic này thường có tên debezium-server-offsets hoặc connector-offsets tùy cấu hình.
kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic debezium-server-offsets
Kết quả mong đợi: Topic bị xóa thành công.
Bước 2: Cập nhật config connector để reset snapshot.
curl -X PUT http://localhost:8083/connectors/postgres-connector/config \
-H "Content-Type: application/json" \
-d '{
"name": "postgres-connector",
"config": {
"name": "postgres-connector",
"connector.class": "io.debezium.connector.postgresql.PostgresqlConnector",
"database.hostname": "localhost",
"database.port": "5432",
"database.user": "debezium",
"database.password": "password",
"database.dbname": "postgres",
"database.server.name": "my-server",
"table.include.list": "public.users",
"slot.name": "debezium_slot",
"publication.name": "debezium_publication",
"snapshot.mode": "initial",
"snapshot.locking.mode": "none",
"offset.storage.topic": "debezium-server-offsets"
}
}'
Kết quả mong đợi: Connector thực hiện snapshot mới từ đầu (initial mode) và tạo lại offset mới.
Tối ưu hóa tham số hiệu năng
Tinh chỉnh batch.size và poll.interval
Mặc định Debezium có thể không tối ưu cho workload cao. batch.size kiểm soát số lượng sự kiện gửi một lần, poll.interval kiểm soát thời gian chờ giữa các lần lấy dữ liệu.
Bước 1: Xác định giá trị tối ưu. Với workload cao, tăng batch size để giảm overhead mạng.
Cập nhật config connector:
curl -X PUT http://localhost:8083/connectors/postgres-connector/config \
-H "Content-Type: application/json" \
-d '{
"batch.size": "1000",
"poll.interval.ms": "100"
}'
Kết quả mong đợi: Throughput (số event/giây) tăng lên, độ trễ (latency) giảm.
Bước 2: Quan sát log Kafka và PostgreSQL để điều chỉnh. Nếu CPU DB tăng cao, giảm batch.size xuống.
Cấu hình đề xuất cho môi trường Production:
batch.size=1000
poll.interval.ms=50
max.poll.interval.ms=300000
Kết quả mong đợi: Hệ thống xử lý ổn định với lượng dữ liệu lớn mà không bị timeout.
Bước 3: Verify kết quả bằng cách tạo load test và đo throughput.
kafka-consumer-perf-test.sh --topic my-db-changes --topic-partition-count 1 --messages 100000 --rate 10000 --producer-threads 1 --producer-records-per-request 1000
Kết quả mong đợi: Logs hiển thị throughput cao và ổn định.
Quản lý Slot và Publication
Nếu slot bị tràn (wal sending rate quá chậm), PostgreSQL sẽ bị treo. Cần cấu hình tự động cleanup.
Bước 1: Kiểm tra độ trễ của slot.
sudo -u postgres psql -c "SELECT slot_name, active, restart_lsn, pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS lag_bytes FROM pg_replication_slots WHERE plugin = 'pgoutput';"
Kết quả mong đợi: lag_bytes nhỏ (dưới 100MB). Nếu lớn, cần tăng tốc consumer hoặc reset slot.
Bước 2: Cấu hình tham số slot.snapshot.mode để tránh lock table trong lần snapshot đầu tiên.
slot.snapshot.mode=initial
Kết quả mong đợi: DB không bị khóa khi connector khởi động lại.
Cấu hình SSL/TLS và SASL cho bảo mật
Chuẩn bị chứng chỉ SSL cho PostgreSQL
Để bảo vệ dữ liệu truyền tải giữa Debezium và PostgreSQL, cần bật SSL.
Bước 1: Tạo chứng chỉ tự ký (self-signed) cho PostgreSQL.
sudo mkdir -p /etc/postgresql/16/main/ssl
sudo -u postgres openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/postgresql/16/main/ssl/postgresql.key -out /etc/postgresql/16/main/ssl/postgresql.crt -subj "/CN=localhost"
sudo chmod 600 /etc/postgresql/16/main/ssl/postgresql.key
sudo chmod 644 /etc/postgresql/16/main/ssl/postgresql.crt
Kết quả mong đợi: File .key và .crt được tạo trong thư mục ssl.
Bước 2: Bật SSL trong /etc/postgresql/16/main/postgresql.conf.
ssl = on
ssl_cert_file = '/etc/postgresql/16/main/ssl/postgresql.crt'
ssl_key_file = '/etc/postgresql/16/main/ssl/postgresql.key'
Kết quả mong đợi: PostgreSQL yêu cầu kết nối SSL.
Bước 3: Restart PostgreSQL.
sudo systemctl restart postgresql@16-main
Kết quả mong đợi: DB chỉ chấp nhận kết nối qua SSL.
Cấu hình Debezium để kết nối qua SSL
Debezium cần được cấu hình để tin tưởng chứng chỉ của PostgreSQL.
Bước 1: Copy file .crt của PostgreSQL vào thư mục truststore của Debezium (hoặc cấu hình đường dẫn).
cp /etc/postgresql/16/main/ssl/postgresql.crt /opt/debezium/truststore/postgres-ca.crt
Kết quả mong đợi: File cert nằm trong thư mục truststore.
Bước 2: Cập nhật config connector để bật SSL và chỉ định truststore.
curl -X PUT http://localhost:8083/connectors/postgres-connector/config \
-H "Content-Type: application/json" \
-d '{
"database.sslmode": "verify-full",
"database.ssl.rootcert": "/opt/debezium/truststore/postgres-ca.crt",
"database.hostname": "localhost",
"database.port": "5432",
"database.user": "debezium",
"database.password": "password",
"database.dbname": "postgres",
"database.server.name": "my-server",
"table.include.list": "public.users",
"slot.name": "debezium_slot",
"publication.name": "debezium_publication"
}'
Kết quả mong đợi: Connector kết nối thành công qua kênh bảo mật.
Bước 3: Verify kết nối SSL.
psql "host=localhost dbname=postgres user=debezium sslmode=verify-full" -c "SELECT ssl_is_used();"
Kết quả mong đợi: Trả về giá trị t (true).
Cấu hình SASL/PLAIN cho Kafka
Để bảo vệ luồng dữ liệu giữa Debezium và Kafka, cần bật SASL.
Bước 1: Tạo user SASL trong Kafka.
kafka-configs.sh --bootstrap-server localhost:9092 --alter --add-config 'USER_debezium:password=secure_password' --entity-type users --entity-name debezium
Kết quả mong đợi: User debezium được tạo với password.
Bước 2: Cấu hình server Kafka để chấp nhận SASL_PLAINTEXT.
Sửa file /opt/kafka/config/server.properties:
listeners=SASL_PLAINTEXT://0.0.0.0:9092
listener.security.protocol.map=SASL_PLAINTEXT:SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=PLAIN
authorizer.class.name=kafka.security.authorizer.AclAuthorizer
Kết quả mong đợi: Kafka yêu cầu xác thực SASL.
Bước 3: Cập nhật config connector để kết nối qua SASL.
curl -X PUT http://localhost:8083/connectors/postgres-connector/config \
-H "Content-Type: application/json" \
-d '{
"bootstrap.servers": "localhost:9092",
"key.converter.schemas.enable": false,
"value.converter.schemas.enable": false,
"key.converter": "org.apache.kafka.connect.storage.StringConverter",
"value.converter": "org.apache.kafka.connect.json.JsonConverter",
"database.hostname": "localhost",
"database.port": "5432",
"database.user": "debezium",
"database.password": "password",
"database.dbname": "postgres",
"database.server.name": "my-server",
"table.include.list": "public.users",
"slot.name": "debezium_slot",
"publication.name": "debezium_publication",
"sasl.mechanism": "PLAIN",
"security.protocol": "SASL_PLAINTEXT",
"sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"debezium\" password=\"secure_password\";"
}'
Kết quả mong đợi: Connector kết nối vào Kafka qua SASL thành công.
Bước 4: Verify bằng cách cố gắng connect không có password.
kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-db-changes --from-beginning --property print.key=true
Kết quả mong đợi: Lệnh bị từ chối (Authentication failed) nếu không cấu hình SASL đúng, hoặc chạy thành công nếu cấu hình đúng.
Điều hướng series:
Mục lục: Series: Triển khai Database Change Data Capture với Debezium và Kafka trên Ubuntu 24.04
« Phần 7: Tích hợp Schema Registry và xử lý định dạng Avro/JSON