Cassandra分布式数据库教程
1. 核心概念
Apache Cassandra是一种开源的分布式NoSQL数据库管理系统,由Apache软件基金会开发。它专为处理大规模数据和高可用性而设计,具有线性可扩展性和容错能力。
1.1 主要特点
- 分布式架构:数据自动分布在多个节点上
- 线性可扩展性:随着节点增加,性能线性增长
- 高可用性:无单点故障,数据自动复制
- 容错性:节点故障不影响系统运行
- 去中心化:所有节点地位平等
- 弹性伸缩:可以动态添加或移除节点
- 可调一致性:可以在一致性和可用性之间权衡
- 高性能:针对读写操作进行了优化
- 开源免费:使用Apache许可证
1.2 核心组件
- Cassandra Cluster:由多个节点组成的集群
- Cassandra Node:单个Cassandra实例
- **Cassandra Query Language (CQL)**:类似SQL的查询语言
- **Cassandra Shell (cqlsh)**:命令行工具
- Cassandra Storage Engine:存储引擎
- Cassandra Replication:数据复制组件
1.3 数据模型
Cassandra的数据模型基于列族:
- 键空间:类似于关系型数据库的数据库
- 表:数据的集合,类似于关系型数据库的表
- 行:表中的一条记录
- 列:行中的一个字段
- 列族:列的集合
- 主键:由分区键和聚类列组成
1.4 核心概念
- 分区键:决定数据存储在哪个节点
- 聚类列:决定数据在分区内的排序
- 复制因子:数据复制的份数
- 一致性级别:读取或写入操作的一致性要求
- 数据中心:逻辑上的节点分组
- 机架:物理上的节点分组
2. 安装配置
2.1 安装Cassandra
Windows系统
- 从Apache Cassandra官方网站下载Windows安装包
- 解压到合适的目录
- 配置环境变量
- 启动Cassandra服务
Linux系统
使用包管理器安装:
# Ubuntu/Debian
curl -fsSL https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -
echo "deb http://www.apache.org/dist/cassandra/debian 40x main" | sudo tee /etc/apt/sources.list.d/cassandra.list
sudo apt update
sudo apt install cassandra
# CentOS/RHEL
sudo yum install java-1.8.0-openjdk
tar -xzf apache-cassandra-4.0.0-bin.tar.gz
mv apache-cassandra-4.0.0 /usr/local/cassandramacOS系统
使用Homebrew安装:
brew install cassandra2.2 基本配置
Cassandra的主要配置文件:
conf/cassandra.yaml:主要配置文件conf/cassandra-env.sh:环境变量配置conf/logback.xml:日志配置
2.3 启动和停止
# 启动Cassandra
sudo systemctl start cassandra # 系统服务方式
# 或
/usr/local/cassandra/bin/cassandra # 直接运行
# 停止Cassandra
sudo systemctl stop cassandra # 系统服务方式
# 或
pkill -f cassandra # 直接终止进程
# 查看Cassandra状态
sudo systemctl status cassandra # 系统服务方式
# 或
nodetool status # 查看集群状态2.4 验证安装
# 启动cqlsh命令行工具
cqlsh
# 查看Cassandra版本
cqlsh> SELECT release_version FROM system.local;
# 预期输出
release_version
-----------------
4.0.0
(1 rows)3. 基本使用
3.1 CQL查询语言
CQL是Cassandra的查询语言,类似于SQL:
- 创建键空间:使用
CREATE KEYSPACE语句 - 创建表:使用
CREATE TABLE语句 - 插入数据:使用
INSERT语句 - 查询数据:使用
SELECT语句 - 更新数据:使用
UPDATE语句 - 删除数据:使用
DELETE语句
3.2 基本操作
创建键空间
-- 创建键空间
CREATE KEYSPACE mykeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- 使用键空间
USE mykeyspace;创建表
-- 创建用户表
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT,
age INT,
created_at TIMESTAMP
);
-- 创建带聚类列的表
CREATE TABLE user_posts (
user_id UUID,
post_id UUID,
title TEXT,
content TEXT,
created_at TIMESTAMP,
PRIMARY KEY (user_id, post_id)
) WITH CLUSTERING ORDER BY (post_id DESC);插入数据
-- 插入用户数据
INSERT INTO users (user_id, name, email, age, created_at)
VALUES (uuid(), '张三', 'zhangsan@example.com', 25, toTimestamp(now()));
-- 插入用户帖子数据
INSERT INTO user_posts (user_id, post_id, title, content, created_at)
VALUES (uuid(), uuid(), 'Cassandra入门', '这是一篇关于Cassandra的入门文章', toTimestamp(now()));查询数据
-- 查询所有用户
SELECT * FROM users;
-- 查询特定用户
SELECT * FROM users WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 查询用户帖子
SELECT * FROM user_posts WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 限制结果数量
SELECT * FROM users LIMIT 10;
-- 排序结果
SELECT * FROM user_posts WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
ORDER BY post_id DESC;更新数据
-- 更新用户信息
UPDATE users SET age = 26, email = 'zhangsan_new@example.com'
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 更新帖子内容
UPDATE user_posts SET content = '更新后的内容'
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
AND post_id = 110e8400-e29b-41d4-a716-446655440000;删除数据
-- 删除用户
DELETE FROM users WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 删除帖子
DELETE FROM user_posts WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
AND post_id = 110e8400-e29b-41d4-a716-446655440000;
-- 删除表
DROP TABLE users;
-- 删除键空间
DROP KEYSPACE mykeyspace;4. 高级功能
4.1 索引
Cassandra支持多种类型的索引:
-- 创建索引
CREATE INDEX ON users(name);
CREATE INDEX ON users(age);
-- 使用索引查询
SELECT * FROM users WHERE name = '张三';
SELECT * FROM users WHERE age > 25;
-- 删除索引
DROP INDEX users_name_idx;4.2 物化视图
物化视图是预计算的查询结果:
-- 创建物化视图
CREATE MATERIALIZED VIEW users_by_age AS
SELECT user_id, name, age
FROM users
WHERE user_id IS NOT NULL AND age IS NOT NULL
PRIMARY KEY (age, user_id);
-- 查询物化视图
SELECT * FROM users_by_age WHERE age > 25;
-- 删除物化视图
DROP MATERIALIZED VIEW users_by_age;4.3 批处理
Cassandra支持批处理操作:
-- 批处理插入
BEGIN BATCH
INSERT INTO users (user_id, name, email) VALUES (uuid(), '张三', 'zhangsan@example.com');
INSERT INTO users (user_id, name, email) VALUES (uuid(), '李四', 'lisi@example.com');
INSERT INTO users (user_id, name, email) VALUES (uuid(), '王五', 'wangwu@example.com');
APPLY BATCH;
-- 批处理更新
BEGIN BATCH
UPDATE users SET age = 26 WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
UPDATE users SET age = 31 WHERE user_id = 550e8400-e29b-41d4-a716-446655440001;
APPLY BATCH;4.4 一致性级别
Cassandra允许为操作设置一致性级别:
-- 设置一致性级别
CONSISTENCY QUORUM;
-- 读取操作
SELECT * FROM users WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 写入操作
INSERT INTO users (user_id, name, email) VALUES (uuid(), '赵六', 'zhaoliu@example.com');4.5 触发器
Cassandra支持触发器:
-- 创建触发器(需要先创建触发器函数)
-- 触发器函数需要使用Java编写并部署
-- 示例:创建一个简单的触发器函数
// Save as ExampleTrigger.java
import org.apache.cassandra.triggers.*;
import java.nio.ByteBuffer;
import java.util.*;
public class ExampleTrigger implements ITrigger {
public Collection<Mutation> augment(ByteBuffer partitionKey, ColumnFamily update) {
// 触发器逻辑
return Collections.emptyList();
}
}
-- 编译并部署触发器
javac -cp "cassandra.jar:lib/*" ExampleTrigger.java
jar cf example-trigger.jar ExampleTrigger.class
-- 在cqlsh中创建触发器
CREATE TRIGGER example_trigger ON users USING 'org.apache.cassandra.triggers.ExampleTrigger';
-- 删除触发器
DROP TRIGGER example_trigger ON users;5. 最佳实践
5.1 数据模型设计
- 查询优先设计:根据查询模式设计数据模型
- 合理设计主键:分区键决定数据分布,聚类列决定排序
- 避免宽行:每行数据不要超过1MB
- 使用复合主键:对于需要多维度查询的场景
- 考虑数据分布:避免数据热点
- 使用适当的数据类型:根据实际需求选择合适的数据类型
5.2 查询优化
- 使用分区键查询:避免全表扫描
- 限制结果集:使用LIMIT限制返回的结果数量
- 避免使用ALLOW FILTERING:会导致全表扫描
- 合理使用索引:只对低 cardinality列创建索引
- 使用物化视图:对于复杂查询
- 优化WHERE子句:尽量使用主键和索引列
5.3 性能调优
- 调整缓存设置:根据服务器内存设置合适的缓存大小
- 优化写入路径:调整commitlog和memtable设置
- 优化读取路径:调整缓存和压缩设置
- 使用适当的压缩策略:根据数据访问模式选择
- 监控系统性能:使用nodetool监控系统状态
- 定期清理数据:使用TTL和compaction
5.4 部署最佳实践
- 使用多数据中心:提高可用性和容错性
- 合理设置复制因子:根据数据重要性和服务器数量设置
- 使用机架感知:提高容错性
- 定期备份:使用nodetool进行备份
- 监控集群状态:使用监控工具监控集群健康状况
- 制定升级计划:定期升级到最新版本
6. 实际应用
6.1 用户管理系统
示例:用户数据存储
-- 创建键空间
CREATE KEYSPACE user_management
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- 使用键空间
USE user_management;
-- 创建用户表
CREATE TABLE users (
user_id UUID PRIMARY KEY,
username TEXT,
email TEXT,
password_hash TEXT,
first_name TEXT,
last_name TEXT,
age INT,
created_at TIMESTAMP,
last_login TIMESTAMP
);
-- 创建用户名索引
CREATE INDEX ON users(username);
-- 创建邮箱索引
CREATE INDEX ON users(email);
-- 插入用户数据
INSERT INTO users (user_id, username, email, password_hash, first_name, last_name, age, created_at)
VALUES (uuid(), 'zhangsan', 'zhangsan@example.com', 'hashed_password', '张', '三', 25, toTimestamp(now()));
-- 查询用户
SELECT * FROM users WHERE username = 'zhangsan';
SELECT * FROM users WHERE email = 'zhangsan@example.com';
-- 更新用户信息
UPDATE users SET last_login = toTimestamp(now()) WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;6.2 时间序列数据
示例:传感器数据存储
-- 创建键空间
CREATE KEYSPACE sensor_data
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- 使用键空间
USE sensor_data;
-- 创建传感器数据表
CREATE TABLE sensor_readings (
sensor_id UUID,
reading_time TIMESTAMP,
temperature DOUBLE,
humidity DOUBLE,
pressure DOUBLE,
PRIMARY KEY (sensor_id, reading_time)
) WITH CLUSTERING ORDER BY (reading_time DESC);
-- 插入传感器数据
INSERT INTO sensor_readings (sensor_id, reading_time, temperature, humidity, pressure)
VALUES (uuid(), toTimestamp(now()), 25.5, 60.0, 1013.25);
-- 查询传感器最新数据
SELECT * FROM sensor_readings WHERE sensor_id = 550e8400-e29b-41d4-a716-446655440000 LIMIT 1;
-- 查询传感器特定时间段数据
SELECT * FROM sensor_readings
WHERE sensor_id = 550e8400-e29b-41d4-a716-446655440000
AND reading_time >= '2023-01-01 00:00:00'
AND reading_time <= '2023-01-01 23:59:59';
-- 查询传感器数据统计
SELECT AVG(temperature), AVG(humidity), AVG(pressure)
FROM sensor_readings
WHERE sensor_id = 550e8400-e29b-41d4-a716-446655440000
AND reading_time >= '2023-01-01 00:00:00'
AND reading_time <= '2023-01-01 23:59:59';6.3 电子商务系统
示例:产品和订单数据存储
-- 创建键空间
CREATE KEYSPACE ecommerce
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- 使用键空间
USE ecommerce;
-- 创建产品表
CREATE TABLE products (
product_id UUID PRIMARY KEY,
name TEXT,
description TEXT,
price DECIMAL,
stock INT,
category TEXT,
created_at TIMESTAMP
);
-- 创建产品类别索引
CREATE INDEX ON products(category);
-- 创建订单表
CREATE TABLE orders (
order_id UUID PRIMARY KEY,
user_id UUID,
total DECIMAL,
status TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
-- 创建订单项表
CREATE TABLE order_items (
order_id UUID,
item_id UUID,
product_id UUID,
quantity INT,
price DECIMAL,
PRIMARY KEY (order_id, item_id)
);
-- 创建用户订单表(按用户ID和时间排序)
CREATE TABLE user_orders (
user_id UUID,
order_id UUID,
total DECIMAL,
status TEXT,
created_at TIMESTAMP,
PRIMARY KEY (user_id, order_id)
) WITH CLUSTERING ORDER BY (order_id DESC);
-- 插入产品数据
INSERT INTO products (product_id, name, description, price, stock, category, created_at)
VALUES (uuid(), 'iPhone 14', '苹果智能手机', 6999.99, 100, '电子产品', toTimestamp(now()));
-- 插入订单数据
INSERT INTO orders (order_id, user_id, total, status, created_at, updated_at)
VALUES (uuid(), uuid(), 6999.99, 'pending', toTimestamp(now()), toTimestamp(now()));
-- 插入订单项数据
INSERT INTO order_items (order_id, item_id, product_id, quantity, price)
VALUES (order_id, uuid(), product_id, 1, 6999.99);
-- 插入用户订单数据
INSERT INTO user_orders (user_id, order_id, total, status, created_at)
VALUES (user_id, order_id, 6999.99, 'pending', toTimestamp(now()));
-- 查询用户订单
SELECT * FROM user_orders WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;
-- 查询订单详情
SELECT * FROM orders WHERE order_id = 550e8400-e29b-41d4-a716-446655440001;
SELECT * FROM order_items WHERE order_id = 550e8400-e29b-41d4-a716-446655440001;6.4 内容管理系统
示例:文章和评论数据存储
-- 创建键空间
CREATE KEYSPACE cms
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 3};
-- 使用键空间
USE cms;
-- 创建文章表
CREATE TABLE articles (
article_id UUID PRIMARY KEY,
title TEXT,
content TEXT,
author_id UUID,
category TEXT,
tags SET<TEXT>,
status TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
-- 创建文章类别索引
CREATE INDEX ON articles(category);
-- 创建文章状态索引
CREATE INDEX ON articles(status);
-- 创建评论表
CREATE TABLE comments (
article_id UUID,
comment_id UUID,
author_id UUID,
content TEXT,
created_at TIMESTAMP,
PRIMARY KEY (article_id, comment_id)
) WITH CLUSTERING ORDER BY (comment_id DESC);
-- 创建作者文章表(按作者ID和时间排序)
CREATE TABLE author_articles (
author_id UUID,
article_id UUID,
title TEXT,
status TEXT,
created_at TIMESTAMP,
PRIMARY KEY (author_id, article_id)
) WITH CLUSTERING ORDER BY (article_id DESC);
-- 插入文章数据
INSERT INTO articles (article_id, title, content, author_id, category, tags, status, created_at, updated_at)
VALUES (uuid(), 'Cassandra入门教程', '这是一篇关于Cassandra的入门教程...', uuid(), '技术', {'Cassandra', 'NoSQL', '数据库'}, 'published', toTimestamp(now()), toTimestamp(now()));
-- 插入评论数据
INSERT INTO comments (article_id, comment_id, author_id, content, created_at)
VALUES (article_id, uuid(), uuid(), '这篇文章很棒!', toTimestamp(now()));
-- 插入作者文章数据
INSERT INTO author_articles (author_id, article_id, title, status, created_at)
VALUES (author_id, article_id, 'Cassandra入门教程', 'published', toTimestamp(now()));
-- 查询文章
SELECT * FROM articles WHERE article_id = 550e8400-e29b-41d4-a716-446655440000;
-- 查询文章评论
SELECT * FROM comments WHERE article_id = 550e8400-e29b-41d4-a716-446655440000;
-- 查询作者文章
SELECT * FROM author_articles WHERE author_id = 550e8400-e29b-41d4-a716-446655440001;
-- 查询分类文章
SELECT * FROM articles WHERE category = '技术' LIMIT 10;7. 总结
Apache Cassandra是一种功能强大的分布式NoSQL数据库管理系统,专为处理大规模数据和高可用性而设计。它具有线性可扩展性、高可用性、容错性等特点,适合处理需要高吞吐量和低延迟的应用场景。
通过本教程的学习,读者应该能够:
- 理解Cassandra的核心概念和架构
- 掌握Cassandra的安装和基本配置方法
- 熟练使用CQL查询语言进行数据库操作
- 了解Cassandra的高级功能和应用场景
- 掌握Cassandra的数据模型设计和性能调优
- 能够在实际项目中应用Cassandra解决大规模数据存储问题
Cassandra作为一种分布式数据库,特别适合处理需要高可用性、高可扩展性和容错能力的应用场景,如社交媒体、物联网、金融服务等。它的线性可扩展性和去中心化架构使其成为处理大规模数据的理想选择。
随着数据量的不断增长和对系统可用性要求的提高,Cassandra的重要性将会继续增长,为企业级应用提供可靠的数据存储解决方案。