Cassandra教程FG009-Cassandra集群搭建与节点扩展实战
本文档风哥主要介绍Cassandra数据库集群搭建与节点扩展实战,包括集群架构概述、集群拓扑结构、Gossip协议、集群规划、硬件要求、网络规划、集群搭建实战、节点添加实战、节点移除实战、3节点集群搭建、5节点集群扩展、数据重平衡等内容,风哥教程参考Cassandra官方文档Architecture和Operations内容编写,适合DBA人员和运维人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 Cassandra数据库集群架构概述
Cassandra数据库集群采用无中心架构(Peer-to-Peer),所有节点地位平等,没有单点故障。这种架构设计使得Cassandra具有高可用性和线性可扩展性。更多视频教程www.fgedu.net.cn
1.1.1 Cassandra数据库集群架构特点
# 1. 无中心架构
– 所有节点地位平等
– 没有Master节点
– 没有单点故障
– 任意节点可接受请求
# 2. 环形拓扑
– 节点组成一个逻辑环
– 每个节点负责一段令牌范围
– 数据按令牌分布存储
# 3. 数据分区
– 使用一致性哈希算法
– 数据均匀分布在节点上
– 支持动态扩缩容
# 4. 数据复制
– 支持多副本存储
– 可配置副本因子
– 支持跨数据中心复制
# 5. 高可用性
– 节点故障自动检测
– 数据自动复制
– 读写请求自动路由
# 集群架构层次
Cluster(集群)
├── Data Center(数据中心)
│ ├── Rack(机架)
│ │ ├── Node(节点)
│ │ └── Node(节点)
│ └── Rack(机架)
│ └── Node(节点)
└── Data Center(数据中心)
└── Rack(机架)
└── Node(节点)
1.1.2 Cassandra数据库集群组件
# 1. 节点(Node)
– 最小存储单元
– 存储数据分区
– 处理读写请求
# 2. 机架(Rack)
– 物理或逻辑分组
– 提高容错能力
– 同一机架节点共享资源
# 3. 数据中心(Data Center)
– 逻辑或物理分组
– 可按地理位置划分
– 支持多数据中心部署
# 4. 集群(Cluster)
– 所有数据中心的集合
– 共享相同集群名称
– 协同工作提供服务
# 5. 分区器(Partitioner)
– 计算数据分区位置
– 决定数据分布策略
– 默认使用Murmur3Partitioner
# 6. Snitch
– 确定节点拓扑信息
– 决定数据中心和机架
– 影响副本放置策略
# 组件关系图
Cluster: fgedu_cluster
├── DC1 (北京)
│ ├── Rack1
│ │ ├── Node1 (192.168.1.101)
│ │ └── Node2 (192.168.1.102)
│ └── Rack2
│ ├── Node3 (192.168.1.103)
│ └── Node4 (192.168.1.104)
└── DC2 (上海)
└── Rack1
├── Node5 (192.168.2.101)
└── Node6 (192.168.2.102)
1.2 Cassandra数据库集群拓扑结构
Cassandra数据库集群拓扑结构详解:
1.2.1 Cassandra数据库令牌环
# 1. 令牌概念
– 令牌是数据分区的标识
– 令牌范围: -2^63 到 2^63-1
– 每个节点负责一段令牌范围
# 2. 令牌分配
– 初始令牌(Initial Token)
– 虚拟节点(VNodes)
– 自动令牌分配
# 3. 数据分布
– 分区键通过哈希函数计算令牌
– 数据存储在负责该令牌的节点
– 副本存储在后续节点
# 令牌环示例
# 3节点集群,使用Murmur3Partitioner
节点1: 令牌范围 -9223372036854775808 到 -3074457345618258603
节点2: 令牌范围 -3074457345618258602 到 3074457345618258602
节点3: 令牌范围 3074457345618258603 到 9223372036854775807
# 虚拟节点(VNodes)
# 每个物理节点包含多个虚拟节点
# 默认每个节点256个虚拟节点
节点1: [token1, token2, …, token256]
节点2: [token257, token258, …, token512]
节点3: [token513, token514, …, token768]
# VNodes优点
1. 自动负载均衡
2. 简化扩缩容
3. 数据分布更均匀
1.2.2 Cassandra数据库副本策略
# 1. SimpleStrategy
– 单数据中心使用
– 副本按顺时针方向放置
– 不考虑机架信息
# 语法
CREATE KEYSPACE keyspace_name
WITH replication = {
‘class’: ‘SimpleStrategy’,
‘replication_factor’: 3
};
# 副本放置示例
节点: [N1, N2, N3, N4, N5]
副本因子: 3
数据写入N1 → 副本: N1, N2, N3
# 2. NetworkTopologyStrategy
– 多数据中心使用
– 副本按机架感知放置
– 每个数据中心可配置不同副本数
# 语法
CREATE KEYSPACE keyspace_name
WITH replication = {
‘class’: ‘NetworkTopologyStrategy’,
‘dc1’: 3,
‘dc2’: 2
};
# 副本放置示例
DC1: [N1(Rack1), N2(Rack1), N3(Rack2), N4(Rack2)]
DC2: [N5(Rack1), N6(Rack1)]
副本因子: dc1=3, dc2=2
数据写入 → DC1副本: N1, N3, N2 (跨机架优先)
→ DC2副本: N5, N6
# 3. 副本因子选择
– 生产环境建议: 3
– 开发测试环境: 1-2
– 关键数据: 5
# 副本因子与一致性级别关系
– QUORUM = (replication_factor / 2) + 1
– RF=3, QUORUM=2
– RF=5, QUORUM=3
1.3 Cassandra数据库Gossip协议
Cassandra数据库Gossip协议详解:
1.3.1 Cassandra数据库Gossip协议原理
# 1. 协议概述
– P2P通信协议
– 用于节点间状态同步
– 每秒执行一次
# 2. 工作原理
– 每个节点随机选择其他节点通信
– 交换节点状态信息
– 信息在整个集群传播
# 3. 传播内容
– 节点状态(UP/DOWN)
– 令牌信息
– 数据中心和机架信息
– Schema信息
# 4. 故障检测
– 使用Phi Accrual Failure Detector
– 计算节点故障概率
– 动态调整检测阈值
# Gossip过程
1. 节点A随机选择节点B
2. A发送Gossip消息给B
3. B回复确认消息
4. A和B交换状态信息
5. 信息传播到其他节点
# Gossip消息类型
1. GossipDigestSyn: 同步请求
2. GossipDigestAck: 确认响应
3. GossipDigestAck2: 最终确认
# 节点状态
UP: 节点正常
DOWN: 节点故障
JOINING: 节点加入中
LEAVING: 节点离开中
MOVING: 节点移动中
1.3.2 Cassandra数据库故障检测机制
# 1. Phi Accrual Failure Detector
– 基于统计的故障检测
– 计算故障概率(Phi值)
– 动态阈值判断
# 2. 心跳检测
– 定期发送心跳消息
– 记录心跳间隔
– 计算Phi值
# 3. Phi值计算
Phi = -log10(1 – F(x))
F(x): 心跳间隔累积分布函数
# 4. 故障判定
Phi > 阈值 → 节点DOWN
Phi < 阈值 → 节点UP
# 默认配置
phi_convict_threshold: 8 (默认值)
- 值越大,检测越宽松
- 值越小,检测越严格
# 5. 故障恢复
- 节点恢复后自动检测
- 状态更新传播到集群
- 数据自动同步
# 配置参数
# cassandra.yaml
phi_convict_threshold: 8
endpoint_snitch: GossipingPropertyFileSnitch
dynamic_snitch_update_interval_in_ms: 100
dynamic_snitch_reset_interval_in_ms: 600000
dynamic_snitch_badness_threshold: 0.1
Part02-生产环境规划与建议
2.1 Cassandra数据库集群规划
Cassandra数据库集群规划详解:
2.1.1 Cassandra数据库集群规模规划
# 1. 节点数量规划
# 公式
节点数 = 数据总量 / 单节点容量 * 副本因子
# 示例
数据总量: 10TB
单节点容量: 2TB
副本因子: 3
节点数 = 10 / 2 * 3 = 15个节点
# 2. 数据中心规划
– 单数据中心: 适合单一地理位置
– 多数据中心: 适合多地理位置、灾备
# 3. 机架规划
– 每个数据中心至少2个机架
– 机架数量影响副本分布
– 建议每个机架节点数相近
# 4. 容量规划考虑因素
– 数据增长速度
– 压缩比例
– 预留空间(20-30%)
– 墓碑空间
# 规划示例
# 场景: 电商订单系统
– 数据量: 5TB
– 日增长: 50GB
– 副本因子: 3
– 预留空间: 30%
# 计算
年数据量 = 5TB + 50GB * 365 = 23.25TB
考虑预留 = 23.25TB / 0.7 = 33.2TB
节点容量 = 2TB
节点数 = 33.2 / 2 * 3 ≈ 50个节点
# 部署方案
DC1 (北京): 25个节点 (5机架 x 5节点)
DC2 (上海): 25个节点 (5机架 x 5节点)
2.1.2 Cassandra数据库集群配置规划
# 1. 集群名称
– 所有节点使用相同集群名称
– 名称具有唯一性
– 示例: fgedu_cluster
# 2. 分区器选择
– Murmur3Partitioner (默认,推荐)
– RandomPartitioner (旧版)
– ByteOrderedPartitioner (不推荐)
# 3. Snitch选择
– GossipingPropertyFileSnitch (推荐)
– PropertyFileSnitch
– Ec2Snitch (AWS)
– GoogleCloudSnitch (GCP)
# 4. 种子节点
– 每个数据中心至少2个种子节点
– 种子节点不存储特殊数据
– 用于新节点加入集群
# 5. 端口配置
– 7000: 集群内部通信
– 7001: 集群内部通信(SSL)
– 9042: CQL客户端连接
– 9142: CQL客户端连接(SSL)
– 7199: JMX监控
# 配置示例
# cassandra.yaml
cluster_name: ‘fgedu_cluster’
num_tokens: 256
seed_provider:
– class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
– seeds: “192.168.1.101,192.168.1.102”
listen_address: 192.168.1.101
rpc_address: 192.168.1.101
endpoint_snitch: GossipingPropertyFileSnitch
# cassandra-rackdc.properties
dc=DC1
rack=RAC1
2.2 Cassandra数据库集群硬件要求
Cassandra数据库集群硬件要求详解:
2.2.1 Cassandra数据库服务器硬件配置
# 1. CPU配置
– 最少: 8核
– 推荐: 16-32核
– 建议: 高主频CPU
# 2. 内存配置
– 最少: 16GB
– 推荐: 64-128GB
– 堆内存: 系统内存的1/4到1/2
– 堆内存不超过32GB
# 3. 磁盘配置
– 类型: SSD(必须)
– 容量: 根据数据量规划
– 数量: 多块磁盘提高性能
– RAID: 不建议使用RAID
# 4. 网络配置
– 带宽: 1Gbps以上
– 延迟: 机房内 < 1ms
- 建议: 万兆网络
# 生产环境推荐配置
# 小型集群
CPU: 16核
内存: 64GB
磁盘: 2TB SSD x 2
网络: 1Gbps
# 中型集群
CPU: 32核
内存: 128GB
磁盘: 4TB SSD x 4
网络: 10Gbps
# 大型集群
CPU: 64核
内存: 256GB
磁盘: 8TB SSD x 8
网络: 25Gbps
# 硬件选型建议
1. CPU: 选择高主频,核心数适中
2. 内存: 充足内存提高缓存命中率
3. 磁盘: SSD是必须,NVMe SSD更好
4. 网络: 高带宽低延迟网络
2.2.2 Cassandra数据库存储规划
# 1. 磁盘布局
/cassandra/app # 安装目录 (50GB)
/cassandra/fgdata # 数据目录 (主要容量)
/cassandra/logs # 日志目录 (100GB)
/cassandra/commitlog # 提交日志 (单独磁盘)
# 2. 数据目录配置
# cassandra.yaml
data_file_directories:
– /cassandra/fgdata/data1
– /cassandra/fgdata/data2
– /cassandra/fgdata/data3
# 3. 提交日志配置
# 建议使用单独磁盘
commitlog_directory: /cassandra/commitlog
commitlog_sync: periodic
commitlog_sync_period_in_ms: 10000
# 4. 存储容量计算
数据容量 = 原始数据 * 副本因子 / 压缩比
预留空间 = 数据容量 * 1.3 (30%预留)
# 示例
原始数据: 1TB
副本因子: 3
压缩比: 0.5 (压缩后50%)
数据容量 = 1TB * 3 / 0.5 = 6TB
预留空间 = 6TB * 1.3 = 7.8TB
# 5. 磁盘性能要求
– IOPS: 最低3000 IOPS
– 吞吐量: 最低200MB/s
– 延迟: 低于1ms
# 6. 文件系统建议
– XFS (推荐)
– ext4
– 避免使用NFS
2.3 Cassandra数据库集群网络规划
Cassandra数据库集群网络规划详解:
2.3.1 Cassandra数据库网络架构
# 1. 网络拓扑
客户端 → 负载均衡 → Cassandra节点
↓
Cassandra集群内部通信
# 2. 网络分区
– 客户端网络: 192.168.1.0/24
– 集群网络: 10.0.0.0/24
– 管理网络: 172.16.0.0/24
# 3. 端口规划
端口 用途 访问范围
7000 集群内部通信 集群节点
7001 集群内部通信(SSL) 集群节点
9042 CQL客户端连接 客户端+应用
9142 CQL客户端连接(SSL) 客户端+应用
7199 JMX监控 管理节点
9180 Prometheus监控 监控系统
# 4. 防火墙配置
# 集群节点防火墙
firewall-cmd –add-port=7000/tcp –permanent
firewall-cmd –add-port=7001/tcp –permanent
firewall-cmd –add-port=9042/tcp –permanent
firewall-cmd –add-port=7199/tcp –permanent
firewall-cmd –reload
# 5. 网络性能要求
– 机房内延迟: < 1ms
- 跨机房延迟: < 10ms
- 带宽: 1Gbps以上
# 6. DNS规划
节点 IP地址 DNS名称
Node1 192.168.1.101 cassandra-node1.fgedu.net.cn
Node2 192.168.1.102 cassandra-node2.fgedu.net.cn
Node3 192.168.1.103 cassandra-node3.fgedu.net.cn
2.3.2 Cassandra数据库多数据中心网络
# 1. 数据中心互联
– 专线连接
– VPN连接
– 延迟要求: < 50ms
# 2. 数据中心配置
# DC1 (北京)
数据中心名称: DC1
机架: RAC1, RAC2
节点: 192.168.1.101-104
# DC2 (上海)
数据中心名称: DC2
机架: RAC1, RAC2
节点: 192.168.2.101-104
# 3. Snitch配置
# cassandra-rackdc.properties
# DC1节点
dc=DC1
rack=RAC1
# DC2节点
dc=DC2
rack=RAC1
# 4. Keyspace配置
CREATE KEYSPACE fgedudb
WITH replication = {
'class': 'NetworkTopologyStrategy',
'DC1': 3,
'DC2': 3
};
# 5. 一致性级别
# 本地写入
CONSISTENCY LOCAL_QUORUM
# 本地读取
CONSISTENCY LOCAL_QUORUM
# 跨数据中心写入
CONSISTENCY EACH_QUORUM
# 6. 网络优化
- 启用压缩减少带宽
- 调整批处理大小
- 使用异步复制
Part03-生产环境项目实施方案
3.1 Cassandra数据库集群搭建实战
Cassandra数据库集群搭建实战:
3.1.1 Cassandra数据库集群搭建准备
# 1. 环境信息
节点 IP地址 数据中心 机架
Node1 192.168.1.101 DC1 RAC1
Node2 192.168.1.102 DC1 RAC1
Node3 192.168.1.103 DC1 RAC2
# 2. 系统配置(所有节点执行)
# 关闭防火墙
# systemctl stop firewalld
# systemctl disable firewalld
# 关闭SELinux
# setenforce 0
# sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/’ /etc/selinux/config
# 配置主机名
# hostnamectl set-hostname cassandra-node1
# 配置hosts
# cat >> /etc/hosts << EOF
192.168.1.101 cassandra-node1
192.168.1.102 cassandra-node2
192.168.1.103 cassandra-node3
EOF
# 配置时间同步
# yum install -y chrony
# systemctl start chronyd
# systemctl enable chronyd
# 3. Java环境安装
# yum install -y java-11-openjdk java-11-openjdk-devel
# java -version
openjdk version "11.0.12" 2021-07-20 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.12+7-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.12+7-LTS, mixed mode, sharing)
# 4. 创建目录
# mkdir -p /cassandra/app
# mkdir -p /cassandra/fgdata
# mkdir -p /cassandra/logs
# mkdir -p /cassandra/commitlog
# 5. 系统参数优化
# cat >> /etc/sysctl.conf << EOF
vm.max_map_count = 1048575
vm.swappiness = 1
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
EOF
# sysctl -p
3.1.2 Cassandra数据库集群安装配置
# 1. 下载安装包(所有节点)
# cd /cassandra/app
# wget https://archive.apache.org/dist/cassandra/4.1.0/apache-cassandra-4.1.0-bin.tar.gz
# tar -xzf apache-cassandra-4.1.0-bin.tar.gz
# ln -s apache-cassandra-4.1.0 current
# 2. 配置环境变量
# cat >> /etc/profile << EOF
export CASSANDRA_HOME=/cassandra/app/current
export PATH=\$PATH:\$CASSANDRA_HOME/bin
EOF
# source /etc/profile
# 3. 配置cassandra.yaml(Node1)
# vim /cassandra/app/current/conf/cassandra.yaml
cluster_name: 'fgedu_cluster'
num_tokens: 256
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "192.168.1.101,192.168.1.102"
listen_address: 192.168.1.101
rpc_address: 192.168.1.101
endpoint_snitch: GossipingPropertyFileSnitch
data_file_directories:
- /cassandra/fgdata
commitlog_directory: /cassandra/commitlog
saved_caches_directory: /cassandra/fgdata/saved_caches
# 4. 配置cassandra-rackdc.properties(Node1)
# vim /cassandra/app/current/conf/cassandra-rackdc.properties
dc=DC1
rack=RAC1
# 5. 配置JVM参数
# vim /cassandra/app/current/conf/jvm-server.options
-Xms8G
-Xmx8G
-Xmn2G
# 6. 配置其他节点
# Node2配置
cluster_name: 'fgedu_cluster'
listen_address: 192.168.1.102
rpc_address: 192.168.1.102
dc=DC1
rack=RAC1
# Node3配置
cluster_name: 'fgedu_cluster'
listen_address: 192.168.1.103
rpc_address: 192.168.1.103
dc=DC1
rack=RAC2
# 7. 启动集群
# 先启动种子节点
# Node1
# /cassandra/app/current/bin/cassandra
# Node2
# /cassandra/app/current/bin/cassandra
# Node3
# /cassandra/app/current/bin/cassandra
# 8. 验证集群状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 100.00 KiB 256 100.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 100.00 KiB 256 100.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 100.00 KiB 256 100.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
(3 rows)
3.2 Cassandra数据库节点添加实战
Cassandra数据库节点添加实战:
3.2.1 Cassandra数据库添加节点准备
# 1. 新节点信息
Node4 192.168.1.104 DC1 RAC2
# 2. 系统配置(同集群搭建)
# 3. 安装Cassandra(同集群搭建)
# 4. 配置cassandra.yaml
# vim /cassandra/app/current/conf/cassandra.yaml
cluster_name: ‘fgedu_cluster’
num_tokens: 256
seed_provider:
– class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
– seeds: “192.168.1.101,192.168.1.102”
listen_address: 192.168.1.104
rpc_address: 192.168.1.104
endpoint_snitch: GossipingPropertyFileSnitch
auto_bootstrap: true # 启用自动引导
# 5. 配置cassandra-rackdc.properties
dc=DC1
rack=RAC2
# 6. 检查现有集群状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 150.00 KiB 256 66.7% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 150.00 KiB 256 66.7% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 150.00 KiB 256 66.7% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
(3 rows)
3.2.2 Cassandra数据库添加节点执行
# 1. 启动新节点
# /cassandra/app/current/bin/cassandra
# 2. 监控加入过程
# nodetool netstats
Mode: JOINING
Not sending any streams.
Receive side:
/192.168.1.101 stream session 8e5f6a7b
Receiving stream #0 from /192.168.1.101
Progress: 50% (100/200 files)
# 3. 查看节点状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 150.00 KiB 256 50.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 150.00 KiB 256 50.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 150.00 KiB 256 50.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UJ 192.168.1.104 100.00 KiB 256 50.0% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
(4 rows)
# UJ: Up, Joining(正在加入)
# 4. 等待加入完成
# 加入完成后状态变为UN (Up, Normal)
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 150.00 KiB 256 50.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 150.00 KiB 256 50.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 150.00 KiB 256 50.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UN 192.168.1.104 150.00 KiB 256 50.0% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
(4 rows)
# 5. 运行cleanup(所有节点)
# nodetool cleanup
# 6. 验证数据分布
# nodetool ring
3.3 Cassandra数据库节点移除实战
Cassandra数据库节点移除实战:
3.3.1 Cassandra数据库节点移除准备
# 1. 确认要移除的节点
要移除节点: 192.168.1.104
# 2. 检查集群状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 200.00 KiB 256 33.3% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 200.00 KiB 256 33.3% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 200.00 KiB 256 33.3% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UN 192.168.1.104 200.00 KiB 256 33.3% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
(4 rows)
# 3. 获取节点Host ID
# nodetool info | grep ID
ID: 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e
# 4. 检查是否为种子节点
# 如果是种子节点,需要先从种子列表移除
# vim /cassandra/app/current/conf/cassandra.yaml
seed_provider:
– class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
– seeds: “192.168.1.101,192.168.1.102” # 移除192.168.1.104
# 5. 重启其他节点使配置生效
# nodetool drain
# /cassandra/app/current/bin/cassandra
3.3.2 Cassandra数据库节点移除执行
# 方式1: 使用decommission(节点正常时)
# 在要移除的节点上执行
# nodetool decommission
# 监控移除过程
# nodetool netstats
Mode: LEAVING
Streaming to: /192.168.1.101, /192.168.1.102, /192.168.1.103
# 查看状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 250.00 KiB 256 33.3% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 250.00 KiB 256 33.3% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 250.00 KiB 256 33.3% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UL 192.168.1.104 100.00 KiB 256 0.0% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
(4 rows)
# UL: Up, Leaving(正在离开)
# 方式2: 使用removenode(节点故障时)
# 在任意节点执行
# nodetool removenode 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e
# 监控移除过程
# nodetool removestatus
RemovalStatus: Waiting for confirmation from 192.168.1.101, 192.168.1.102, 192.168.1.103
# 3. 验证移除完成
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 300.00 KiB 256 100.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 300.00 KiB 256 100.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 300.00 KiB 256 100.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
(3 rows)
# 4. 运行repair(所有节点)
# nodetool repair
# 5. 清理旧数据(可选)
# nodetool cleanup
Part04-生产案例与实战讲解
4.1 Cassandra数据库3节点集群搭建实战
Cassandra数据库3节点集群搭建实战案例:
4.1.1 Cassandra数据库3节点集群搭建脚本
#!/bin/bash
# setup_3node_cluster.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# 集群配置
CLUSTER_NAME=”fgedu_cluster”
NODE1_IP=”192.168.1.101″
NODE2_IP=”192.168.1.102″
NODE3_IP=”192.168.1.103″
SEEDS=”${NODE1_IP},${NODE2_IP}”
# 安装函数
install_cassandra() {
local NODE_IP=$1
local RACK=$2
echo “正在配置节点: ${NODE_IP}”
# 创建目录
ssh root@${NODE_IP} “mkdir -p /cassandra/app /cassandra/fgdata /cassandra/logs /cassandra/commitlog”
# 配置cassandra.yaml
ssh root@${NODE_IP} “cat > /cassandra/app/current/conf/cassandra.yaml << EOF
cluster_name: '${CLUSTER_NAME}'
num_tokens: 256
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: \"${SEEDS}\"
listen_address: ${NODE_IP}
rpc_address: ${NODE_IP}
endpoint_snitch: GossipingPropertyFileSnitch
data_file_directories:
- /cassandra/fgdata
commitlog_directory: /cassandra/commitlog
saved_caches_directory: /cassandra/fgdata/saved_caches
EOF"
# 配置cassandra-rackdc.properties
ssh root@${NODE_IP} "cat > /cassandra/app/current/conf/cassandra-rackdc.properties << EOF
dc=DC1
rack=${RACK}
EOF"
echo "节点 ${NODE_IP} 配置完成"
}
# 执行安装
echo "开始搭建3节点Cassandra集群..."
# 配置各节点
install_cassandra ${NODE1_IP} "RAC1"
install_cassandra ${NODE2_IP} "RAC1"
install_cassandra ${NODE3_IP} "RAC2"
# 启动种子节点
echo "启动种子节点..."
ssh root@${NODE1_IP} "/cassandra/app/current/bin/cassandra"
sleep 30
ssh root@${NODE2_IP} "/cassandra/app/current/bin/cassandra"
sleep 30
# 启动第三个节点
echo "启动第三个节点..."
ssh root@${NODE3_IP} "/cassandra/app/current/bin/cassandra"
sleep 30
# 验证集群
echo "验证集群状态..."
nodetool status
echo "3节点集群搭建完成"
4.1.2 Cassandra数据库3节点集群验证
# 1. 检查集群状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 100.00 KiB 256 100.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 100.00 KiB 256 100.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 100.00 KiB 256 100.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
(3 rows)
# 2. 检查令牌环
# nodetool ring
Datacenter: DC1
==========
Address Rack Status State Load Owns Token
127.0.0.1
192.168.1.101 RAC1 Up Normal 100.00 KiB 33.33% -9223372036854775808
192.168.1.102 RAC1 Up Normal 100.00 KiB 33.33% -3074457345618258603
192.168.1.103 RAC2 Up Normal 100.00 KiB 33.33% 3074457345618258602
# 3. 创建测试Keyspace
# cqlsh 192.168.1.101 9042
cqlsh> CREATE KEYSPACE fgedudb
… WITH replication = {
… ‘class’: ‘NetworkTopologyStrategy’,
… ‘DC1’: 3
… };
# 4. 创建测试表
cqlsh> USE fgedudb;
cqlsh:fgedudb> CREATE TABLE fgedu_test (
… id uuid PRIMARY KEY,
… name text,
… created_at timestamp
… );
# 5. 插入测试数据
cqlsh:fgedudb> INSERT INTO fgedu_test (id, name, created_at)
… VALUES (uuid(), ‘test’, toTimestamp(now()));
# 6. 查询测试数据
cqlsh:fgedudb> SELECT * FROM fgedu_test;
id | name | created_at
————————————–+——+———————————-
8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b | test | 2024-01-15 10:30:00.123000+0000
(1 row)
# 7. 验证数据复制
# 在其他节点查询
# cqlsh 192.168.1.102 9042 -e “SELECT * FROM fgedudb.fgedu_test”
# cqlsh 192.168.1.103 9042 -e “SELECT * FROM fgedudb.fgedu_test”
4.2 Cassandra数据库5节点集群扩展实战
Cassandra数据库5节点集群扩展实战案例:
4.2.1 Cassandra数据库集群扩展脚本
#!/bin/bash
# expand_to_5node.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
# 新节点配置
NODE4_IP=”192.168.1.104″
NODE5_IP=”192.168.1.105″
SEEDS=”192.168.1.101,192.168.1.102″
# 添加节点函数
add_node() {
local NODE_IP=$1
local RACK=$2
echo “正在添加节点: ${NODE_IP}”
# 配置cassandra.yaml
cat > /cassandra/app/current/conf/cassandra.yaml << EOF
cluster_name: 'fgedu_cluster'
num_tokens: 256
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "${SEEDS}"
listen_address: ${NODE_IP}
rpc_address: ${NODE_IP}
endpoint_snitch: GossipingPropertyFileSnitch
auto_bootstrap: true
data_file_directories:
- /cassandra/fgdata
commitlog_directory: /cassandra/commitlog
EOF
# 配置cassandra-rackdc.properties
cat > /cassandra/app/current/conf/cassandra-rackdc.properties << EOF
dc=DC1
rack=${RACK}
EOF
# 启动节点
echo "启动节点 ${NODE_IP}..."
/cassandra/app/current/bin/cassandra
# 等待节点加入
echo "等待节点加入集群..."
sleep 60
# 检查状态
nodetool status | grep ${NODE_IP}
}
# 执行扩展
echo "开始扩展集群到5节点..."
# 添加Node4
add_node ${NODE4_IP} "RAC2"
# 添加Node5
add_node ${NODE5_IP} "RAC1"
# 验证集群
echo "验证集群状态..."
nodetool status
# 运行cleanup
echo "运行cleanup..."
for node in 192.168.1.101 192.168.1.102 192.168.1.103; do
echo "Cleanup on ${node}..."
ssh root@${node} "nodetool cleanup"
done
echo "集群扩展完成"
4.2.2 Cassandra数据库集群扩展验证
# 1. 检查集群状态
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 200.00 KiB 256 40.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 200.00 KiB 256 40.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 200.00 KiB 256 40.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UN 192.168.1.104 200.00 KiB 256 40.0% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
UN 192.168.1.105 200.00 KiB 256 40.0% 2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f RAC1
(5 rows)
# 2. 检查数据分布
# nodetool ring | head -20
# 3. 验证数据完整性
# cqlsh 192.168.1.101 9042 -e “SELECT COUNT(*) FROM fgedudb.fgedu_test”
# 4. 性能测试
# cassandra-stress write n=100000 -node 192.168.1.101 -rate threads=50
# 5. 监控资源使用
# nodetool info
# nodetool tpstats
4.3 Cassandra数据库集群数据重平衡实战
Cassandra数据库集群数据重平衡实战案例:
4.3.1 Cassandra数据库数据重平衡操作
# 1. 检查数据分布不均衡
# nodetool tablehistograms fgedudb.fgedu_orders
Percentile SSTables Write Latency Read Latency Partition Size Cell Count
(micros) (micros) (bytes)
50% 0.00 125.45 234.56 1048576.00 100.00
75% 0.00 234.56 456.78 2097152.00 200.00
95% 0.00 456.78 890.12 4194304.00 400.00
# 2. 检查节点负载
# nodetool info | grep Load
Load: 500.00 GiB
# 3. 运行cleanup
# nodetool cleanup
# 4. 运行repair
# nodetool repair -pr
# 5. 检查压缩状态
# nodetool compactionstats
pending tasks: 0
# 6. 手动触发压缩
# nodetool compact fgedudb fgedu_orders
# 7. 检查数据分布
# nodetool ring
# 8. 重新平衡脚本
#!/bin/bash
# rebalance.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
echo “开始数据重平衡…”
# 获取所有节点
NODES=$(nodetool status | grep UN | awk ‘{print $2}’)
# 在每个节点运行cleanup
for node in $NODES; do
echo “Cleanup on ${node}…”
ssh root@${node} “nodetool cleanup”
done
# 在每个节点运行repair
for node in $NODES; do
echo “Repair on ${node}…”
ssh root@${node} “nodetool repair -pr”
done
echo “数据重平衡完成”
4.3.2 Cassandra数据库数据重平衡验证
# 1. 检查节点负载
# nodetool status
Datacenter: DC1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
— Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 400.00 GiB 256 20.0% 8e5f6a7b-8c9d-0e1f-2a3b-4c5d6e7f8a9b RAC1
UN 192.168.1.102 400.00 GiB 256 20.0% 9f7g8h9i-0j1k-2l3m-4n5o-6p7q8r9s0t1u RAC1
UN 192.168.1.103 400.00 GiB 256 20.0% 0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d RAC2
UN 192.168.1.104 400.00 GiB 256 20.0% 1b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e RAC2
UN 192.168.1.105 400.00 GiB 256 20.0% 2c3d4e5f-6a7b-8c9d-0e1f-2a3b4c5d6e7f RAC1
(5 rows)
# 2. 检查分区大小分布
# nodetool tablehistograms fgedudb.fgedu_orders
# 3. 验证数据完整性
# nodetool repair -pr fgedudb
# 4. 性能测试
# cassandra-stress read n=100000 -node 192.168.1.101 -rate threads=50
# 5. 监控资源使用
# nodetool info
# nodetool tpstats
Part05-风哥经验总结与分享
5.1 Cassandra数据库集群最佳实践
Cassandra数据库集群最佳实践总结:
- 集群规划:合理规划节点数量、数据中心和机架布局
- 硬件选择:使用SSD存储,充足的内存,高带宽网络
- 配置优化:合理配置JVM参数、缓存参数、压缩参数
- 监控告警:建立完善的监控体系,设置合理的告警阈值
- 备份恢复:定期备份数据,验证恢复流程
- 容量规划:预留足够的容量,定期评估增长趋势
5.2 Cassandra数据库集群监控
# 1. 关键监控指标
– 节点状态
– 读写延迟
– 磁盘使用率
– 内存使用率
– CPU使用率
– 网络流量
– 压缩队列
– 修复进度
# 2. 监控命令
# 集群状态
nodetool status
# 节点信息
nodetool info
# 表统计
nodetool tablestats
# 线程池状态
nodetool tpstats
# 压缩状态
nodetool compactionstats
# 3. 监控工具
– nodetool
– JMX
– DataStax OpsCenter
– Prometheus + Grafana
– Datadog
# 4. 告警规则
– 节点DOWN超过5分钟
– 磁盘使用率超过80%
– 读写延迟超过100ms
– 压缩队列超过100
– 修复失败
5.3 Cassandra数据库集群故障处理
Cassandra数据库集群故障处理:
5.3.1 Cassandra数据库常见故障处理
# 1. 节点DOWN
# 检查原因
– 网络问题
– 磁盘满
– 内存不足
– 进程崩溃
# 处理步骤
# 检查节点状态
nodetool status
# 检查日志
tail -100 /cassandra/logs/system.log
# 检查磁盘
df -h
# 检查内存
free -m
# 重启节点
/cassandra/app/current/bin/cassandra
# 2. 数据不一致
# 运行repair
nodetool repair -pr
# 检查数据
nodetool tablehistograms
# 3. 性能下降
# 检查压缩
nodetool compactionstats
# 检查GC
jstat -gcutil
# 检查缓存
nodetool info | grep Cache
# 4. 磁盘满
# 清理数据
nodetool cleanup
# 删除旧数据
nodetool clearsnapshot
# 压缩数据
nodetool compact
本文档详细介绍了Cassandra数据库集群搭建与节点扩展实战,包括集群架构概述、集群拓扑结构、Gossip协议、集群规划、硬件要求、网络规划、集群搭建实战、节点添加实战、节点移除实战、3节点集群搭建、5节点集群扩展、数据重平衡、集群最佳实践、集群监控、故障处理等内容。通过学习本文档,读者可以掌握Cassandra数据库集群搭建和运维技能,为生产环境部署打下坚实基础。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
