加群联系作者vx:xiaoda0423
仓库地址:https://webvueblog.github.io/JavaPlusDoc/
https://1024bat.cn/
cassandra 主备集群
elasticsearch
nginx
redis
grafana+prometheus
skywalking
一、开头部分:nohup ... &
nohup ... >/dev/null 2>&1 &
部分 | 说明 |
---|---|
nohup | 防止程序因退出终端而终止,保证服务后台运行 |
> /dev/null 2>&1 | 把标准输出( |
& | 表示 后台运行,不会卡住当前终端 |
📌 生产环境中常用,可以不挂断地运行服务。
参数 | 说明 |
---|---|
-javaagent=... | 启动时加载 SkyWalking 的探针(agent),用于采集调用链 |
agent.service_name=xx-service | 当前服务在链路追踪系统中的名称 |
collector.backend_service=xxx:xxx | SkyWalking 后端 OAP 服务地址(收集数据) |
参数 | 说明 |
---|---|
nacos.discovery.server-addr | 配置 Nacos 注册中心地址(服务注册发现) |
spring.profiles.active=prod | 使用 |
server.port=xxx | 启动服务监听的端口号为 10003 |
✅ 如果你想看日志
> /var/log/xxx-service.log 2>&1 &
✅ 如果服务挂了,可以用:
ps -ef | grep xxx-service kill -9 <PID>
给脚本加执行权限
chmod +x start.sh stop.sh restart.sh
生产环境建议
建议项 | 内容 |
---|---|
配置外置 | 用 |
日志系统 | 使用 |
守护进程 | 生产中可以考虑用 |
日常部署注意事项
内容 | 建议 |
---|---|
JAR 包版本管理 | 放在 |
使用软链接启动 | current -> 真实 jar ,解耦脚本与版本 |
保持日志不被覆盖 | 日志写入 |
自动化 | 可升级为 Jenkins、GitLab CI、Ansible 等自动部署 |
✅ 工具横向对比推荐
系统 | 推荐压测工具 | 并发控制 | 备注 |
---|---|---|---|
Cassandra | cassandra-stress | ✅ | 内置工具,广泛使用 |
Scylla | scylla-bench | ✅ | 官方支持,兼容 Cassandra |
Elasticsearch | esrally | ✅ | 官方工具,支持自定义场景 |
Kafka | kafka-producer-perf-test | ✅ | 吞吐、延迟指标清晰 |
MySQL | sysbench | ✅ | 支持读写混合、高并发模拟 |
Redis | redis-benchmark | ✅ | 极高性能测试,支持多命令 |
(Redis压测参考)
Record Count | Operation | Avg TPS / QPS | Avg Latency | CPU (%) | Mem (MB) | Disk Write | Disk Used |
---|---|---|---|---|---|---|---|
1M | Write | 150,000 | 0.6 ms | 80% | 500 MB | 100 MB/s | 0.4 GB |
汇总:
Record Count | Operation | QPS (r/s) | Avg Latency (估算) | CPU | MEM | Disk | Space |
---|---|---|---|---|---|---|---|
1,000,000 | SET | 154930.12 | ≈ 6.45ms/1M = 0.006 | ||||
1,000,000 | GET | 159235.67 | ≈ 6.28ms/1M = 0.006 |
日志文件内容(每秒一行):
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1120000 12300 205500 0 0 5 6 110 210 5 3 90 2 0
1 0 0 1108000 12000 208000 0 0 4 8 108 190 7 4 87 2 0
...
可从中提取:
us+sy
:CPU使用率(user/system)
free
:空闲内存
wa
:I/O等待率
bi/bo
:磁盘读写速率(block in/out)
✅ 注意事项
项目 | 建议 |
---|---|
✅ 自动调用 | 主脚本中已经用: |
❗防止误删 | 如果中间卡死或中断,请手动 |
✅ 多系统兼容 | 文件名中加上 |
✅ Cassandra 中的 Keyspace 是什么?
Keyspace 类似于 MySQL 的数据库(CREATE DATABASE
),是 Cassandra 的最顶层数据结构,里面包含多个表(Table)。每个 Keyspace 有自己的 复制策略(replication strategy) 和 副本数(replication factor) 。
'class': 'SimpleStrategy'
:复制策略选择的是SimpleStrategy
,适合单数据中心。'replication_factor': 2
:每条数据保存 2 份,分布在不同节点,提高容灾能力。
✅ 副本数(replication_factor)设置建议
2
表示:写入数据会保存两份,放在两个节点上。适合生产环境的主数据,防止单节点宕机导致数据丢失。
1
表示:只保存一份,适合日志这类容错要求不高、容量大的场景。
多数据中心的集群
WITH replication = {
'class': 'NetworkTopologyStrategy',
'datacenter1': 3,
'datacenter2': 2
};
你想要 将 Cassandra 数据部署为副本 2(replication_factor=2
)的高可用架构,需要满足以下两个条件:
✅ 1. 集群中至少部署两个节点
这是基本前提:因为副本数是 2,Cassandra 需要能在两个不同节点存放相同的数据。
✅ 最小部署拓扑示意:
Node1 (192.168.1.101) ⇄ Node2 (192.168.1.102)
__________________/
数据副本互为备份
✅ 2. 创建 Keyspace 使用 SimpleStrategy
(单数据中心)或 NetworkTopologyStrategy
(多数据中心)
推荐方式(生产环境):
使用 NetworkTopologyStrategy,即使你只有一个数据中心,也建议使用它。
🛠 部署步骤简化(以两节点集群为例)
假设两台服务器:
Node1:
192.168.1.101
Node2:
192.168.1.102
修改两台机器的配置
修改 /etc/cassandra/cassandra.yaml
中关键字段:
每台机器都要配置:
cluster_name: 'MyCluster' # 保持一致
num_tokens: 256 # 默认值即可
listen_address: 本机IP # 如 192.168.1.101 / 192.168.1.102
rpc_address: 0.0.0.0 # 或写死本机IP
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "192.168.1.101,192.168.1.102"
endpoint_snitch: GossipingPropertyFileSnitch
修改 /etc/cassandra/cassandra-rackdc.properties
:
确保都属于同一个数据中心:
dc=datacenter1
rack=rack1
启动 Cassandra 服务并加入集群
分别在两台机器上执行:
sudo systemctl start cassandra
或者:
cassandra -f
确认集群状态(任意节点上)
nodetool status
你会看到类似输出:
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 192.168.1.101 150.99 KB 256 ? abcdefg-... rack1
UN 192.168.1.102 160.23 KB 256 ? hijklmn-... rack1
Cassandra 集群并写数据
连接 Cassandra + 写入 + 查询
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.cql.*;
import java.net.InetSocketAddress;
public class CassandraExample {
public static void main(String[] args) {
// 连接 Cassandra 集群,传入主机 IP 和端口
try (CqlSession session = CqlSession.builder()
.addContactPoint(new InetSocketAddress("192.168.1.101", 9042))
.addContactPoint(new InetSocketAddress("192.168.1.102", 9042))
.withLocalDatacenter("datacenter1") // 与 cassandra-rackdc.properties 的 dc 匹配
.build()) {
// 使用或创建 Keyspace
session.execute("CREATE KEYSPACE IF NOT EXISTS demo_db " +
"WITH replication = {'class':'NetworkTopologyStrategy', 'datacenter1':2}");
// 使用该 keyspace
session.execute("USE demo_db");
// 创建一个表
session.execute("CREATE TABLE IF NOT EXISTS users (" +
"id UUID PRIMARY KEY," +
"name text," +
"email text)");
// 插入数据
session.execute("INSERT INTO users (id, name, email) VALUES (uuid(), 'Tom', 'tom@example.com')");
// 查询数据
ResultSet resultSet = session.execute("SELECT * FROM users");
for (Row row : resultSet) {
System.out.println("User: " + row.getString("name") + " - " + row.getString("email"));
}
}
}
}
使用 Spring Data for Apache Cassandra(推荐企业项目)
💡 依赖(Spring Boot 项目使用):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
✅ application.yml 示例配置
spring:
data:
cassandra:
contact-points: 192.168.1.101,192.168.1.102
port: 9042
keyspace-name: demo_db
local-datacenter: datacenter1
schema-action: create_if_not_exists
✅ Entity + Repository 示例
@Table("users")
public class User {
@PrimaryKey
private UUID id;
private String name;
private String email;
// getters/setters ...
}
public interface UserRepository extends CassandraRepository<User, UUID> {
}
✅ 使用 Service 或 Controller 中调用
@Autowired
private UserRepository userRepository;
public void demo() {
User user = new User();
user.setId(UUID.randomUUID());
user.setName("Alice");
user.setEmail("alice@example.com");
userRepository.save(user);
userRepository.findAll().forEach(u -> System.out.println(u.getName()));
}
方案 | 适合场景 | 优点 |
---|---|---|
原生 DataStax Java Driver | 轻量项目 / 快速集成 | 灵活、性能好、控制粒度大 |
Spring Data Cassandra | Spring Boot 项目 | 快速开发、抽象更高、更易维护 |
项目结构预览
spring-cassandra-demo/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/com/example/demo/
│ │ │ ├── DemoApplication.java
│ │ │ ├── entity/User.java
│ │ │ ├── repository/UserRepository.java
│ │ │ └── controller/UserController.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── logback-spring.xml
✅ 1. pom.xml
添加依赖
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-cassandra-demo</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Cassandra Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<!-- UUID 工具包(可选) -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<properties>
<java.version>17</java.version>
<spring.boot.version>3.1.0</spring.boot.version>
</properties>
<build>
<plugins>
<!-- Spring Boot Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
✅ 2. application.yml
配置 Cassandra 连接
spring:
data:
cassandra:
contact-points: 192.168.1.101,192.168.1.102
port: 9042
keyspace-name: demo_db
local-datacenter: datacenter1
schema-action: create_if_not_exists
✅ 3. DemoApplication.java
启动类
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
✅ 4. User.java
实体类
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
import java.util.UUID;
@Table("users")
public class User {
@PrimaryKey
private UUID id;
private String name;
private String email;
// Getters & Setters
public UUID getId() { return id; }
public void setId(UUID id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
✅ 5. UserRepository.java
仓储接口
import com.example.demo.entity.User;
import org.springframework.data.cassandra.repository.CassandraRepository;
import java.util.UUID;
public interface UserRepository extends CassandraRepository<User, UUID> {
}
✅ 6. UserController.java
示例接口
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.UUID;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping
public User create(@RequestBody User user) {
user.setId(UUID.randomUUID());
return userRepository.save(user);
}
@GetMapping
public List<User> list() {
return userRepository.findAll();
}
}
🚀 启动 & 测试
1. 启动项目:
mvn spring-boot:run
2. 测试接口:
POST http://localhost:8080/users
Body:
{
"name": "Alice",
"email": "alice@example.com"
}
GET http://localhost:8080/users