Cấu hình mạng cho Node thứ nhất để chuẩn bị mở rộng Cluster
Điều chỉnh seed_nodes, listen_address và broadcast_address
Để Cassandra nhận diện được các node trong cluster, bạn cần xác định rõ địa chỉ IP mà node này dùng để giao tiếp nội bộ (internode) và địa chỉ quảng bá (broadcast) cho các node khác.
Sửa file cấu hình chính /etc/cassandra/cassandra.yaml trên Node 1 (giả sử IP là 192.168.1.10).
Các tham số cần chỉnh sửa:
- listen_address: IP địa phương mà node này lắng nghe các kết nối từ các node khác trong cluster.
- broadcast_address: IP mà node này quảng bá cho các node khác biết để kết nối lại.
- seed_nodes: Danh sách IP của các node đã tồn tại trong cluster để node mới có thể join vào.
Mở file và tìm các dòng sau, thay thế nội dung bằng cấu hình dưới đây:
sudo nano /etc/cassandra/cassandra.yaml
Tìm và sửa các dòng (bình luận các dòng mặc định, uncomment và chỉnh sửa dòng mới):
listen_address: 192.168.1.10
broadcast_address: 192.168.1.10
seed_nodes: '192.168.1.10'
Kết quả mong đợi: Node 1 hiện đã được cấu hình để lắng nghe trên IP riêng của nó và tự coi là seed node. Khi node 2 join vào, nó sẽ lấy danh sách seed này để tìm Node 1.
Thiết lập giao thức Internode Encryption (TLS)
Trong môi trường sản xuất, bạn bắt buộc phải mã hóa lưu lượng truy cập giữa các node (internode) để chống nghe lén và đảm bảo tính toàn vẹn dữ liệu.
Trên Ubuntu 24.04, chúng ta sẽ sử dụng tự ký chứng chỉ (self-signed) bằng OpenSSL để đơn giản hóa quy trình setup ban đầu.
Tạo thư mục chứa chứng chỉ và key:
sudo mkdir -p /etc/cassandra/ssl
Khởi tạo file cấu hình OpenSSL để tạo chứng chỉ tự ký cho Node 1:
cat > /tmp/cassandra_node1.cnf
Tạo chứng chỉ và key riêng (private key):
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/cassandra/ssl/node1.key -out /etc/cassandra/ssl/node1.crt -config /tmp/cassandra_node1.cnf
Thay đổi quyền sở hữu file chứng chỉ để user cassandra có thể đọc được:
sudo chown cassandra:cassandra /etc/cassandra/ssl/node1.key /etc/cassandra/ssl/node1.crt
Kết quả mong đợi: File node1.crt và node1.key đã được tạo trong thư mục /etc/cassandra/ssl/.
Cấu hình Internode Authentication
Bên cạnh mã hóa, bạn cần xác thực (authentication) để đảm bảo chỉ các node được ủy quyền mới có thể tham gia vào cluster.
Sử dụng cơ chế InternodeAuthenticator dựa trên chứng chỉ TLS đã tạo ở bước trên.
Tiếp tục chỉnh sửa file /etc/cassandra/cassandra.yaml:
sudo nano /etc/cassandra/cassandra.yaml
Thêm hoặc sửa các dòng sau vào cuối file hoặc tìm vị trí thích hợp:
internode_encryption: dc
client_encryption: optional
endpoint_snitch: SimpleSnitch
authenticator: AllowAllAuthenticator
authorizer: AllowAllAuthorizer
Để cấu hình cụ thể cho Internode Encryption sử dụng chứng chỉ tự ký, bạn cần thêm một file cấu hình phụ encryption_options hoặc cấu hình trực tiếp trong cassandra.yaml (tùy phiên bản, Ubuntu 24.04 thường dùng JNA). Tuy nhiên, cách an toàn và chuẩn nhất cho self-signed là cấu hình trong cassandra.yaml như sau:
internode_encryption: dc
client_encryption: optional
internode_sasl: true
internode_encryption_options:
enabled: true
require_client_auth: false
require_endpoint_auth: true
truststore: /etc/cassandra/ssl/node1.crt
keystore: /etc/cassandra/ssl/node1.crt
truststore_password:
keystore_password:
store_type: PKCS12
Lưu ý: Để đơn giản hóa việc deploy trên tutorial này, chúng ta sẽ dùng cơ chế InternodeAuthenticator mặc định của Cassandra nếu dùng chứng chỉ, nhưng để đảm bảo tương thích cao nhất với Ubuntu 24.04 (Cassandra 4.x), ta sẽ dùng ssl option đơn giản hơn nếu không cần PKI phức tạp. Dưới đây là cấu hình an toàn cho self-signed:
internode_encryption: dc
internode_encryption_options:
enabled: true
require_client_auth: false
require_endpoint_auth: true
truststore: /etc/cassandra/ssl/node1.crt
keystore: /etc/cassandra/ssl/node1.crt
truststore_password:
keystore_password:
store_type: PKCS12
Chuyển đổi chứng định PEM sang PKCS12 (cần thiết cho Java Truststore/Keystore):
sudo openssl pkcs12 -export -out /etc/cassandra/ssl/node1.p12 -inkey /etc/cassandra/ssl/node1.key -in /etc/cassandra/ssl/node1.crt -passout pass: -passin pass:
Chỉnh sửa lại cassandra.yaml để trỏ đúng file .p12:
internode_encryption_options:
enabled: true
require_client_auth: false
require_endpoint_auth: true
truststore: /etc/cassandra/ssl/node1.p12
keystore: /etc/cassandra/ssl/node1.p12
truststore_password:
keystore_password:
store_type: PKCS12
Kết quả mong đợi: File node1.p12 được tạo. Cấu hình mạng và bảo mật trên Node 1 đã sẵn sàng.
Khởi động lại Node 1 và Verify
Áp dụng các thay đổi cấu hình bằng cách khởi động lại dịch vụ Cassandra.
sudo systemctl restart cassandra
Kiểm tra trạng thái của node đầu tiên:
cassandra-cli --host 127.0.0.1 --port 9042 -c "SELECT status FROM system.local;"
Hoặc dùng lệnh cqlsh để kiểm tra nhanh:
cqlsh -e "SELECT datacenter, rack, host_id FROM system.peers_v2;"
Kết quả mong đợi: Node 1 lên trạng thái UN (Up/Normal). Khi chạy system.peers_v2 sẽ trả về rỗng vì chưa có node nào khác join vào.
Cài đặt và cấu hình Node thứ hai
Chuẩn bị môi trường Ubuntu 24.04 trên Node 2
Giả sử Node 2 có IP là 192.168.1.11. Thực hiện các bước cài đặt gói Cassandra tương tự như Phần 2.
Cập nhật repository và cài đặt:
sudo apt update
sudo apt install -y openjdk-21-jdk curl gnupg
curl -s https://downloads.apache.org/cassandra/4.x/bin/apache-cassandra-4.1.4-ubuntu2404.deb -o apache-cassandra.deb
sudo dpkg -i apache-cassandra.deb
sudo apt install -f -y
Kết quả mong đợi: Cassandra được cài đặt thành công trên Node 2.
Tạo chứng chỉ TLS cho Node 2
Tương tự như Node 1, Node 2 cần có cặp chứng chỉ riêng của nó để tham gia vào mạng encrypted.
Tạo cấu hình OpenSSL cho Node 2:
cat > /tmp/cassandra_node2.cnf
Tạo chứng chỉ và key:
sudo mkdir -p /etc/cassandra/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/cassandra/ssl/node2.key -out /etc/cassandra/ssl/node2.crt -config /tmp/cassandra_node2.cnf
Chuyển đổi sang PKCS12:
sudo openssl pkcs12 -export -out /etc/cassandra/ssl/node2.p12 -inkey /etc/cassandra/ssl/node2.key -in /etc/cassandra/ssl/node2.crt -passout pass: -passin pass:
Chỉnh quyền sở hữu:
sudo chown cassandra:cassandra /etc/cassandra/ssl/node2.key /etc/cassandra/ssl/node2.crt /etc/cassandra/ssl/node2.p12
Kết quả mong đợi: File node2.p12 đã sẵn sàng trong thư mục /etc/cassandra/ssl/.
Cấu hình mạng và seed_nodes trên Node 2
Bây giờ là bước quan trọng nhất: Cấu hình Node 2 để nó biết cách kết nối với Node 1.
Chỉnh sửa file /etc/cassandra/cassandra.yaml trên Node 2:
sudo nano /etc/cassandra/cassandra.yaml
Cập nhật các tham số sau:
listen_address: 192.168.1.11
broadcast_address: 192.168.1.11
seed_nodes: '192.168.1.10'
Cấu hình encryption options cho Node 2 (tương tự Node 1 nhưng trỏ vào file node2.p12):
internode_encryption: dc
internode_encryption_options:
enabled: true
require_client_auth: false
require_endpoint_auth: true
truststore: /etc/cassandra/ssl/node2.p12
keystore: /etc/cassandra/ssl/node2.p12
truststore_password:
keystore_password:
store_type: PKCS12
Lưu ý quan trọng: Để Node 2 tin tưởng Node 1 (và ngược lại), trong môi trường self-signed, bạn cần thêm chứng chỉ của Node 1 vào truststore của Node 2. Tuy nhiên, với cấu hình require_client_auth: false (chỉ yêu cầu endpoint auth), Cassandra 4.x thường chấp nhận nếu cấu hình đúng. Để chắc chắn 100%, ta sẽ merge chứng chỉ.
Truyền file chứng chỉ của Node 1 sang Node 2 và merge vào truststore:
scp /etc/cassandra/ssl/node1.crt cassandra@192.168.1.11:/tmp/
sudo cat /tmp/node1.crt /etc/cassandra/ssl/node2.crt > /tmp/combined.crt
sudo openssl pkcs12 -export -out /etc/cassandra/ssl/node2.p12 -inkey /etc/cassandra/ssl/node2.key -in /tmp/combined.crt -passout pass: -passin pass:
sudo chown cassandra:cassandra /etc/cassandra/ssl/node2.p12
Tương tự, cần truyền file node2.crt sang Node 1 để Node 1 tin Node 2 (bước này có thể làm sau khi Node 2 join, nhưng tốt nhất làm trước để tránh lỗi handshake):
scp /etc/cassandra/ssl/node2.crt cassandra@192.168.1.10:/tmp/
# Trên Node 1:
sudo cat /tmp/node2.crt /etc/cassandra/ssl/node1.crt > /tmp/combined.crt
sudo openssl pkcs12 -export -out /etc/cassandra/ssl/node1.p12 -inkey /etc/cassandra/ssl/node1.key -in /tmp/combined.crt -passout pass: -passin pass:
sudo chown cassandra:cassandra /etc/cassandra/ssl/node1.p12
Kết quả mong đợi: Cả hai node đều có file .p12 chứa chứng chỉ của chính nó và chứng chỉ của node kia trong truststore.
Khởi động Node 2 và kiểm tra kết nối
Khởi động dịch vụ Cassandra trên Node 2:
sudo systemctl start cassandra
Kiểm tra log để đảm bảo không có lỗi về network hay encryption:
sudo tail -f /var/log/cassandra/system.log
Kết quả mong đợi: Trong log sẽ thấy dòng Starting listening for CQL clients và quan trọng hơn là Starting to join the ring. Không xuất hiện lỗi SSLHandshakeException hay UnknownHostException.
Đưa Node mới vào Cluster và Kiểm tra tính đồng bộ
Verify trạng thái Cluster từ Node 1
Sau khi Node 2 đã khởi động và thực hiện handshake thành công, Node 1 sẽ nhận ra Node 2.
Trên Node 1, chạy lệnh cqlsh để xem danh sách các node:
cqlsh -e "SELECT host_id, datacenter, rack, broadcast_address, status FROM system.peers_v2;"
Kết quả mong đợi: Bảng trả về sẽ có 1 dòng (là Node 2) với trạng thái UP và normal. Nếu trạng thái là LEAVING hoặc DRAINING thì cần kiểm tra lại log.
Kiểm tra trạng thái ring:
cqlsh -e "SELECT start_token, end_token, host_id, status FROM system_ring;"
Kết quả mong đợi: Bạn sẽ thấy 2 dòng tương ứng với 2 node, mỗi node chiếm một khoảng token (token range) trong ring. Tổng cộng 2 node đang hoạt động.
Chạy lệnh nodetool để kiểm tra chi tiết
Sử dụng nodetool để kiểm tra sâu hơn về giao tiếp internode và trạng thái gossip.
nodetool status
Kết quả mong đợi:
Datacenter: datacenter1
====================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address State TL Tokens Host ID
UN 192.168.1.10 Normal 3 256
UN 192.168.1.11 Normal 3 256
Trong đó UN nghĩa là Up và Normal. Nếu thấy UN cho cả 2 node, cluster đã được mở rộng thành công.
Thử nghiệm đồng bộ dữ liệu (Data Replication)
Để đảm bảo dữ liệu được sao chép tự động giữa 2 node, ta sẽ tạo một keyspace có replication factor = 2.
cqlsh -e "CREATE KEYSPACE test_cluster WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': 2};"
Tạo bảng và chèn dữ liệu:
cqlsh -e "CREATE TABLE test_cluster.users (id uuid PRIMARY KEY, username text, email text);"
cqlsh -e "INSERT INTO test_cluster.users (id, username, email) VALUES (uuid(), 'admin', 'admin@example.com');"
Kiểm tra dữ liệu trên Node 2 để xác nhận replication đã hoạt động:
ssh cassandra@192.168.1.11 "cqlsh -e 'SELECT * FROM test_cluster.users;'"
Kết quả mong đợi: Dữ liệu bạn vừa chèn trên Node 1 xuất hiện ngay lập tức khi query trên Node 2. Điều này chứng tỏ cơ chế replication (NetworkTopologyStrategy) đã hoạt động đúng với RF=2.
Verify Internode Encryption hoạt động
Để chắc chắn traffic giữa các node đã được mã hóa, kiểm tra lại trong log hoặc dùng nodetool (nếu có option) hoặc đơn giản là xem lại cấu hình internode_encryption_options đã áp dụng.
Chạy lệnh kiểm tra thông tin kết nối:
nodetool gossipinfo
Kết quả mong đợi: Bạn sẽ thấy thông tin của cả 2 node trong output. Nếu encryption thất bại, Node 2 sẽ không thể join vào ring và nodetool status sẽ không hiện Node 2 hoặc hiện trạng thái lỗi.
Verify Authentication (nếu có)
Vì chúng ta đang dùng AllowAllAuthenticator để đơn giản hóa setup ban đầu, bước này chủ yếu là xác nhận node đã trust nhau.
Thử truy cập cqlsh từ Node 1 sang Node 2 qua IP trực tiếp (bỏ qua localhost):
cqlsh 192.168.1.11 9042 -e "SELECT host_id FROM system.local;"
Kết quả mong đợi: Lệnh chạy thành công, trả về host_id của Node 2. Nếu authentication hoặc encryption sai, kết nối sẽ bị từ chối ngay lập tức.
Điều hướng series:
Mục lục: Series: Triển khai Database phân tán với Apache Cassandra và Ubuntu 24.04
« Phần 2: Cài đặt và cấu hình node đầu tiên của Apache Cassandra
Phần 4: Thiết kế Schema và tối ưu hóa phân vùng dữ liệu »