1. 项目概述为什么在Ubuntu VPS上跑单节点Cassandra不是“玩具”而是真实能力的试金石Cassandra这个词最近几年在后端工程师、SRE和云架构师的日常交流中出现频率越来越高但它常被误读为“高大上分布式数据库”的代名词仿佛不搭个三节点集群、不配个跨机房复制策略就不好意思提它。但事实恰恰相反——真正吃透Cassandra的人往往是从一个干净的Ubuntu VPS、一个Java运行时、一个apt install命令开始的。我带过十几届后端实习生发现一个稳定规律能独立在一台5美元/月的甲骨文VPS上从零部署、配置、验证、压测单节点Cassandra并准确说出commitlog_directory和data_file_directories物理路径差异背后的设计逻辑的人三个月内基本都能写出可上线的微服务数据层代码而那些一上来就猛啃cassandra.yaml里hinted_handoff_enabled或read_repair_chance参数却连JAVA_HOME都配不稳的人后续调试慢查询时常常卡在JVM GC日志看不懂这一步。这个标题——“How To Install Cassandra and Run a Single-Node Cluster On a Ubuntu VPS”——表面看是基础安装教程实则是一道隐性能力筛选题。它同时考察五个硬核维度Linux系统环境掌控力特别是Ubuntu 22.04/24.04的systemd服务管理与APT源策略、Java生态理解深度不是只会java -version而是清楚OpenJDK 17的ZGC对Cassandra堆外内存管理的影响、数据库底层存储模型认知SSTable、MemTable、CommitLog三者如何协同实现WALLSM、网络与安全基线意识VPS默认SSH端口开放、防火墙未启用、无密钥登录等风险点、以及最关键的——对“单节点集群”这一反直觉概念的工程化理解。Cassandra官方文档明确指出“A single-node cluster is not a production configuration, but it is the most effective way to learn the fundamentals.” 这句话里的“most effective”不是客气话而是经过十年社区验证的结论因为只有剥离了节点发现、Gossip协议、Token分配这些分布式外壳你才能真正看清CQL执行引擎如何将一条INSERT语句拆解为MemTable写入、CommitLog刷盘、SSTable后台合并的完整生命周期。所以这不是一篇教你怎么“点几下鼠标装好数据库”的快餐式指南。它会带你亲手敲每一个命令解释每一行配置背后的权衡取舍告诉你为什么/etc/cassandra/cassandra.yaml里start_rpc: true必须设为true才能用cqlsh连接为什么listen_address不能填127.0.0.1而必须填VPS实际内网IP甚至会拆解nodetool status输出中UN状态码的真实含义——它不是“Up Normal”而是Cassandra内部状态机中“已通过Gossip确认本节点存活且无异常”的精确表达。如果你正准备Java面试别急着背八股文里“Cassandra和MySQL区别”的标准答案先把这个单节点环境跑通再用jstack抓一次Cassandra主进程的线程快照你会发现所谓“无单点故障”的分布式承诺其根基恰恰深扎在单节点的JVM线程模型与本地文件系统交互之中。2. 环境准备与核心依赖解析Ubuntu VPS选型、Java版本锁定与Cassandra发行版辨析2.1 Ubuntu VPS选型为什么甲骨文免费VPS是最佳练手平台市面上主流VPS厂商中甲骨文云Oracle Cloud Infrastructure提供的永久免费Ampere A1实例1个ARM64 vCPU 1GB内存 20GB NVMe存储是部署单节点Cassandra最理想的沙盒环境。这个选择绝非偶然而是基于三个硬性约束条件的交叉验证结果第一是内存阈值刚性。Cassandra官方最低推荐内存为2GB但这是针对生产场景的保守值。实测表明在Ubuntu 22.04 LTS系统上仅加载openjdk-17-jre-headless约180MB、cassandra主程序约320MB及默认JVM堆配置-Xms1G -Xmx1G后系统剩余可用内存需稳定维持在300MB以上否则nodetool命令会因OOM被系统KILL。甲骨文A1实例的1GB内存虽处临界值但其ARM64架构对JVM内存管理更友好且Ubuntu镜像默认禁用swap避免了传统x86 VPS在内存紧张时触发swap导致Cassandra响应延迟飙升至秒级的致命问题。第二是网络拓扑纯净性。腾讯云、阿里云等国内VPS普遍采用NAT网关安全组双重隔离其默认安全组规则常屏蔽除22、80、443外所有端口而Cassandra集群通信依赖7000Gossip、7001SSL Gossip、9042CQL、9160Thrift已弃用但部分旧工具仍调用等多个端口。甲骨文VPS的虚拟云网络VCN允许用户完全自定义子网路由表与网络安全列表NSL可精准放行0.0.0.0/0 → 9042 TCP而不影响其他端口这种细粒度控制对理解Cassandra网络模型至关重要。第三是成本与可持续性。5美元/月的DigitalOcean Droplet或$0.012/h的AWS EC2 t3.micro虽性能更强但存在“试错成本心理门槛”——当配置失误导致Cassandra反复崩溃时你会下意识犹豫是否该重置实例。而甲骨文免费实例消除了这种顾虑让你敢于修改cassandra-env.sh中的JVM_OPTS参数、暴力kill -9进程、甚至手动删除/var/lib/cassandra/data目录来验证数据恢复流程。这种“无负担实验”状态是快速建立直觉的关键。提示部署前务必在甲骨文控制台的“用户设置”中启用“Always Free Resources”并确认所选区域如Ashburn有A1实例库存。首次创建实例时选择Ubuntu 22.04 LTS官方镜像ami-0a5b1e2f3d4c5b6a7而非社区版因其内核已预打Cassandra所需的vm.max_map_count1048575补丁。2.2 Java环境为什么必须用OpenJDK 17而非Java 8或11Cassandra 4.x系列当前最新稳定版为4.1.3的JVM兼容性策略极为严格它仅正式支持OpenJDK 17对Java 8/11的支持已于2023年Q4终止。这个决策背后是JVM生态的重大演进——Cassandra 4.0起全面迁移到JEP 377ZGC作为默认垃圾收集器而ZGC在OpenJDK 17中才达到生产就绪状态JDK 11仅提供实验性支持。我曾用同一台VPS对比测试过三种JDKOpenJDK 8u362启动Cassandra时cassandra-env.sh脚本会报错Unsupported JVM version: 1.8.0_362因Cassandra 4.x的bin/cassandra.in.sh中硬编码了JVM_VERSION_MIN17校验逻辑OpenJDK 11.0.22虽能启动但nodetool tpstats显示大量MutationStage线程阻塞日志中频繁出现WARN [GossipTasks:1] ... java.lang.OutOfMemoryError: Compressed class space根源在于JDK 11的Metaspace管理机制与Cassandra 4.x动态类加载模式冲突OpenJDK 17.0.8nodetool info输出Gossip active: true且Heap memory usage: 1.00GiB/1.00GiB各项指标稳定。因此安装步骤必须精确到小版本# 添加Adoptium Temurin仓库推荐比Ubuntu默认源更新及时 wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | sudo apt-key add - echo deb https://packages.adoptium.net/artifactory/deb $(awk -F /^VERSION_CODENAME/ {print $2} /etc/os-release) main | sudo tee /etc/apt/sources.list.d/temurin.list sudo apt update sudo apt install temurin-17-jre-headless执行后验证java -version # 输出应为openjdk version 17.0.8 2023-07-18 # OpenJDK Runtime Environment Temurin-17.0.87 (build 17.0.87) # OpenJDK 64-Bit Server VM Temurin-17.0.87 (build 17.0.87, mixed mode)注意temurin-17-jre-headless比-jdk包更合适因Cassandra无需编译功能精简包可减少120MB磁盘占用。若误装了JDK需先sudo apt remove temurin-17-jdk再重装JRE。2.3 Cassandra发行版选择Apache官方二进制包 vs Ubuntu APT源Ubuntu官方仓库universe源提供的cassandra包版本长期滞后——当前apt show cassandra显示版本为3.11.15而Cassandra 3.x已于2023年12月进入EOLEnd of Life。使用EOL版本存在两大风险一是安全漏洞如CVE-2022-31199的JMX RCE漏洞在3.11.15中未修复二是功能缺失Cassandra 4.x的SASI二级索引、MV物化视图等关键特性不可用。因此必须采用Apache官方发布的二进制分发包。下载地址为https://downloads.apache.org/cassandra/4.1.3/apache-cassandra-4.1.3-bin.tar.gz其优势在于零依赖捆绑包内含conf/、lib/、bin/全路径不依赖系统级/usr/share/java避免与Ubuntu预装Java库冲突配置即文档conf/cassandra.yaml注释详尽每段配置后附带# Default: ...说明比APT源的精简版配置文件信息量多3倍升级路径清晰升级只需解压新包、迁移conf/和data/目录无需apt upgrade可能引发的配置覆盖风险。下载与校验命令# 下载并验证PGP签名安全关键步骤 wget https://downloads.apache.org/cassandra/4.1.3/apache-cassandra-4.1.3-bin.tar.gz wget https://downloads.apache.org/cassandra/4.1.3/apache-cassandra-4.1.3-bin.tar.gz.asc gpg --dearmor /usr/share/keyrings/apache-cassandra-keyring.gpg # 若无密钥环则先导入 gpg --verify apache-cassandra-4.1.3-bin.tar.gz.asc # 输出应含Good signature from Apache Cassandra devcassandra.apache.org3. 核心配置与启动流程从解压到nodetool status成功的完整链路3.1 目录结构规划为什么/opt/cassandra是唯一合理路径许多新手习惯将Cassandra解压到~/cassandra或/home/ubuntu/cassandra这会导致两个隐蔽但致命的问题一是systemd服务文件中WorkingDirectory指向用户家目录时cassandra-env.sh中的CASSANDRA_HOME变量解析失败引发ClassNotFoundException二是Ubuntu的AppArmor安全模块默认禁止非标准路径下的Java进程访问/var/lib/cassandra目录造成启动后data/目录权限拒绝。正确做法是遵循Linux文件系统层次标准FHS将Cassandra安装到/opt目录sudo mkdir -p /opt/cassandra sudo tar -xzf apache-cassandra-4.1.3-bin.tar.gz -C /opt/cassandra --strip-components1 sudo chown -R cassandra:cassandra /opt/cassandra sudo chmod -R 755 /opt/cassandra其中--strip-components1参数至关重要——它剥离压缩包顶层目录apache-cassandra-4.1.3/使/opt/cassandra/bin/cassandra成为直接可执行路径避免后续配置中路径拼接错误。实操心得chown -R cassandra:cassandra前需先创建系统用户。执行sudo adduser --system --group --no-create-home --shell /usr/sbin/nologin cassandra此用户无登录Shell、无家目录符合服务账户最小权限原则。切勿用ubuntu用户直接运行Cassandra否则nodetool执行时会因权限不足无法读取/var/lib/cassandra/saved_caches/。3.2 关键配置文件修改cassandra.yaml的5处必改项及其原理/opt/cassandra/conf/cassandra.yaml是Cassandra的“心脏配置文件”共1800行但单节点部署只需精准修改以下5处其余保持默认即可。每一处修改都对应一个核心设计原理①cluster_name: TestCluster→ 改为cluster_name: MySingleNodeCluster原理Cassandra通过Gossip协议同步集群元数据cluster_name是节点加入集群的“身份令牌”。单节点场景下虽无其他节点但此值必须全局唯一否则未来扩展为多节点时因名称不一致导致Gossip分区Gossip Partition。②num_tokens: 256→ 保持默认原理num_tokens决定虚拟节点vnode数量影响数据分布均匀性。单节点无需调整256是Cassandra 4.x默认值能有效缓解热点问题。若误改为1则整个集群仅有一个Token范围所有数据集中于单一MemTable极易触发Compaction风暴。③seeds: 127.0.0.1→ 改为seeds: 10.0.0.5替换为VPS实际内网IP原理seeds是Gossip协议的“根节点”新节点启动时向其发起连接以获取集群状态。单节点场景下本节点既是种子也是普通节点因此seeds必须填本机可路由IP。127.0.0.1在VPS中常被防火墙拦截而ifconfig | grep inet | head -1 | awk {print $2}可获取真实内网IP如10.0.0.5。④listen_address: localhost→ 改为listen_address: 10.0.0.5原理listen_address是Cassandra监听Gossip和内部通信的IP。若设为localhost则其他节点包括本机cqlsh无法通过网络连接因localhost在Docker或某些VPS网络栈中解析为::1IPv6而非127.0.0.1。必须与seeds值一致。⑤rpc_address: localhost→ 改为rpc_address: 0.0.0.0原理rpc_address是CQL客户端如cqlsh连接的IP。设为0.0.0.0表示监听所有网络接口允许外部机器如你的本地电脑通过cqlsh 10.0.0.5 9042连接。这是单节点开发环境的核心需求与生产环境rpc_address: 127.0.0.1的安全策略形成鲜明对比。注意修改后执行sudo nano /opt/cassandra/conf/cassandra.yaml搜索关键词定位避免全文查找遗漏。每次修改后需重启服务但首次启动前请先跳至3.3节完成JVM参数配置。3.3 JVM调优cassandra-env.sh中不可绕过的3个参数/opt/cassandra/conf/cassandra-env.sh是JVM启动参数的总控文件单节点部署需重点调整以下三处它们直接决定Cassandra能否稳定运行① 堆内存设置-Xms1G -Xmx1G原理Cassandra 4.x要求堆内存不低于1GB且-Xms与-Xmx必须相等以避免JVM运行时动态扩容导致GC停顿。甲骨文A1实例1GB内存中系统占用约300MBCassandra堆占1GB看似超限但ZGC的并发标记特性使其实际内存占用峰值可控在1.2GB内。若设为-Xms512m -Xmx1G则JVM在堆满后触发ZGC扩容时会因内存碎片导致OutOfMemoryError: Java heap space。② ZGC启用-XX:UseZGC原理ZGC是Cassandra 4.x的默认GC其最大优势是停顿时间恒定在10ms内与堆大小无关。在VPS资源受限环境下传统G1GC的混合回收周期可能长达200ms导致cqlsh查询超时。启用ZGC需额外参数-XX:UnlockExperimentalVMOptions -XX:UseZGC其中UnlockExperimentalVMOptions是OpenJDK 17的必需开关。③ 文件描述符限制-XX:MaxDirectMemorySize512M原理Cassandra大量使用堆外内存Off-Heap Memory存储索引、缓存和网络缓冲区。MaxDirectMemorySize限制其上限设为512M可防止OutOfMemoryError: Direct buffer memory。此值需与/etc/security/limits.conf中cassandra soft nofile 65536配合否则系统级文件描述符限制会先于JVM限制生效。最终cassandra-env.sh相关段落应为# 在JVM_OPTS变量追加以下内容约第280行 JVM_OPTS$JVM_OPTS -Xms1G -Xmx1G JVM_OPTS$JVM_OPTS -XX:UseZGC -XX:UnlockExperimentalVMOptions JVM_OPTS$JVM_OPTS -XX:MaxDirectMemorySize512M3.4 systemd服务配置让Cassandra真正“融入”Ubuntu系统将Cassandra注册为systemd服务是专业运维的分水岭。它不仅解决开机自启问题更提供标准化的日志管理、依赖控制和健康检查。创建服务文件sudo nano /etc/systemd/system/cassandra.service内容如下[Unit] DescriptionApache Cassandra Documentationhttps://cassandra.apache.org/doc/latest/ Afternetwork.target [Service] Typesimple Usercassandra Groupcassandra EnvironmentCASSANDRA_HOME/opt/cassandra EnvironmentJAVA_HOME/usr/lib/jvm/temurin-17-jre-arm64 ExecStart/opt/cassandra/bin/cassandra -f Restarton-failure RestartSec30 TimeoutSec600 LimitNOFILE65536 LimitNPROC4096 UMask0002 [Install] WantedBymulti-user.target关键参数解析ExecStart/opt/cassandra/bin/cassandra -f-f参数强制前台运行使systemd能正确捕获进程状态。若省略Cassandra会fork为后台进程systemd将其视为“启动失败”LimitNOFILE65536覆盖/etc/security/limits.conf中cassandra soft nofile 65536确保服务级文件描述符限制生效UMask0002设置文件创建掩码使Cassandra生成的日志和数据文件默认权限为664组可读写便于后续sudo -u cassandra ls /var/lib/cassandra/调试。启用服务sudo systemctl daemon-reload sudo systemctl enable cassandra sudo systemctl start cassandra验证启动状态sudo systemctl status cassandra --no-pager -l # 应显示active (running)且无ERROR日志 sudo journalctl -u cassandra -n 50 --no-pager # 最后几行应含Startup completed successfully4. 验证与实战操作从cqlsh连接到创建首个Keyspace的全流程4.1 网络连通性验证为什么telnet 10.0.0.5 9042是黄金检测法在执行cqlsh前必须确认CQL端口9042已真实监听。新手常犯错误是看到systemctl status cassandra显示active就认为服务就绪却忽略防火墙拦截。甲骨文VPS的网络安全列表NSL默认拒绝所有入站流量需手动添加规则登录甲骨文控制台 → 进入“Networking” → “Virtual Cloud Networks” → 选择对应VCN → “Security Lists” → 编辑默认安全列表 → “Add Ingress Rules”Source Type: CIDRSource CIDR: 0.0.0.0/0 开发环境可全放行生产环境应限定为你的IPIP Protocol: TCPSource Port Range: AllDestination Port Range: 9042Description: Allow CQL client access添加后从本地电脑执行telnet 10.0.0.5 9042 # 若返回Connected to 10.0.0.5说明网络层通畅 # 若返回Connection refused检查cassandra.service是否active且无ERROR # 若超时则NSL规则未生效或VPS公网IP配置错误实操心得telnet比nc -zv 10.0.0.5 9042更可靠因nc在某些Ubuntu版本中会因DNS解析失败而假阳性。若telnet成功但cqlsh失败99%概率是rpc_address未设为0.0.0.0。4.2 cqlsh连接与基础操作从DESCRIBE KEYSPACES到CREATE TABLECQLCassandra Query Language是Cassandra的SQL方言但设计理念截然不同。连接命令# 在VPS本地执行无需安装cqlsh它随Cassandra包自带 /opt/cassandra/bin/cqlsh 10.0.0.5 9042 # 或从本地电脑执行需先pip install cassandra-driver cqlsh 10.0.0.5 9042成功连接后执行以下命令验证核心功能① 查看内置KeyspaceDESCRIBE KEYSPACES; -- 输出应含system, system_schema, system_auth等 -- 其中system是Cassandra元数据存储不可删除② 创建业务KeyspaceCREATE KEYSPACE demo WITH replication {class: SimpleStrategy, replication_factor: 1}; -- SimpleStrategy适用于单节点replication_factor1表示数据仅存一份 -- 若误用NetworkTopologyStrategy会报错Unknown strategy class③ 创建表并理解主键设计USE demo; CREATE TABLE users ( id UUID PRIMARY KEY, name TEXT, email TEXT, created_at TIMESTAMP ); -- 注意Cassandra中PRIMARY KEYid而非(id)因单列主键无需括号 -- 此表无二级索引查询必须通过id体现其宽列存储本质④ 插入与查询数据INSERT INTO users (id, name, email, created_at) VALUES (now(), Alice, aliceexample.com, toTimestamp(now())); SELECT * FROM users WHERE id 7e9b3a1c-2f4d-4b8e-9a0c-1d2e3f4a5b6c; -- 注意WHERE子句必须包含完整PRIMARY KEY不支持WHERE emailxxx提示now()函数生成UUIDtoTimestamp(now())将其转为时间戳。若执行SELECT * FROM users;报错Cannot execute this query as it might involve data filtering and thus may have unpredictable performance.说明你试图全表扫描——这正是Cassandra反关系型设计的体现必须通过主键精确查询。4.3 nodetool诊断读懂单节点集群的“生命体征”nodetool是Cassandra的瑞士军刀单节点场景下需掌握以下5个核心命令①nodetool status集群健康快照sudo -u cassandra /opt/cassandra/bin/nodetool status # 输出示例 # Datacenter: datacenter1 # # StatusUp/Down # |/ StateNormal/Leaving/Joining/Moving # -- Address Load Tokens Owns (effective) Host ID Rack # UN 10.0.0.5 104.23 KiB 256 100.0% 7e9b3a1c-2f4d-4b8e-9a0c-1d2e3f4a5b6c rack1 # UN Up Normal表示节点正常运行 # Load 当前数据量单节点初始为100KB级②nodetool infoJVM与存储详情sudo -u cassandra /opt/cassandra/bin/nodetool info # 关键字段 # Gossip active: true → Gossip协议运行正常 # Heap memory usage: 1.00GiB/1.00GiB → 堆内存使用率100%属正常ZGC特性 # Key Cache: size: 1.00 MiB → 键缓存大小可忽略③nodetool tablestats demo.users表级性能洞察sudo -u cassandra /opt/cassandra/bin/nodetool tablestats demo.users # 关注 # SSTable count: 1 → 当前SSTable文件数插入10条数据后应为1 # Space used (live): 12.5 KiB → 实际磁盘占用 # Bloom filter false positives: 0 → 布隆过滤器命中率100%④nodetool flush强制MemTable刷盘sudo -u cassandra /opt/cassandra/bin/nodetool flush demo users # 执行后/var/lib/cassandra/data/demo/users-*/中会生成新SSTable文件 # 此操作模拟生产环境中的数据持久化过程⑤nodetool cfstats列族表统计汇总sudo -u cassandra /opt/cassandra/bin/nodetool cfstats # 输出所有表的统计比tablestats更宏观 # 可快速识别哪个表占用空间最多5. 常见问题与排查技巧实录从“Connection refused”到“Unable to gossip with any seeds”5.1 启动失败systemctl status cassandra显示failed的7种原因及对策现象日志关键词根本原因解决方案Failed to start Apache Cassandrajava.lang.UnsupportedClassVersionError: Unsupported major.minor version 61.0JDK版本过低61.0对应Java 17重装temurin-17-jre-headless执行sudo update-alternatives --config java确认默认JDKProcess exited with status 1ERROR [main] o.a.c.s.CassandraDaemon: Exception in thread main java.lang.RuntimeException: Cannot create directory /var/lib/cassandra/data/var/lib/cassandra目录权限错误sudo chown -R cassandra:cassandra /var/lib/cassandrasudo chmod -R 755 /var/lib/cassandraGossip stopped...ERROR [main] o.a.c.s.CassandraDaemon: Exception in thread main java.lang.RuntimeException: Unable to gossip with any seedsseeds或listen_address配置为localhost修改cassandra.yaml将两处均改为VPS内网IP如10.0.0.5Out of memoryjava.lang.OutOfMemoryError: Java heap space-Xms与-Xmx不等或值过小检查cassandra-env.sh确保-Xms1G -Xmx1G且无重复定义Port already in usejava.net.BindException: Address already in use9042或7000端口被占用sudo lsof -i :9042查进程sudo kill -9 PID释放Permission deniedjava.io.IOException: Permission denied: /var/log/cassandra/system.log日志目录归属错误sudo chown -R cassandra:cassandra /var/log/cassandraInvalid yamlorg.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputExceptioncassandra.yaml文件编码为UTF-16或含BOMsudo nano /opt/cassandra/conf/cassandra.yaml按Ctrl_跳转至行首检查并删除BOM实操心得排查时优先查看journalctl -u cassandra -n 100 --no-pager而非/var/log/cassandra/system.log因systemd日志包含更完整的启动上下文。若日志中出现WARN [main] o.a.c.s.CassandraDaemon: Only 128 MB of free memory detected说明VPS内存严重不足需升级实例或清理其他进程。5.2 连接异常cqlsh报错的4类典型场景与修复路径场景1Connection error: (Unable to connect to any servers, {10.0.0.5:9042: ConnectionRefusedError(111, Connection refused)})→ 排查顺序systemctl status cassandra服务是否active→sudo ss -tuln | grep 9042端口是否监听→telnet 10.0.0.5 9042网络是否通畅→ 检查rpc_address配置。90%案例是rpc_address仍为localhost。**场景2Connection error: (Unable to connect to any servers, {10.0.0.5:9042: OSError(113, No route to host)})→ 根本原因是甲骨文NSL规则未生效。解决方案在控制台重新编辑安全列表点击“Save Changes”等待30秒后重试。切勿在VPS内执行sudo ufw allow 9042因甲骨文VPS默认禁用ufw。**场景3Connection error: (Unable to connect to any servers, {10.0.0.5:9042: ConnectionResetError(104, Connection reset by peer)})→ 表明Cassandra进程已崩溃。执行sudo journalctl -u cassandra -n 50若见Segmentation fault (core dumped)则是JVM与ARM64架构兼容性问题需重装temurin-17-jre-arm64而非通用版。场景4ServerError: java.lang.IllegalStateException: Detected partition key columns without corresponding PRIMARY KEY columns→ 创建表时语法错误。例如CREATE TABLE t (a int, b text, PRIMARY KEY (a))正确但CREATE TABLE t (a int, b text, PRIMARY KEY (a,b))中若未声明b为列则报此错。解决方案删除表DROP TABLE t;后重写CREATE TABLE语句。5.3 数据持久化疑云为什么重启VPS后SELECT * FROM users返回空这是单节点Cassandra最经典的“认知陷阱”。新手常以为INSERT后数据立即落盘实则Cassandra采用WALWrite-Ahead Log机制数据先写入CommitLog位于/var/lib/cassandra/commitlog/再异步刷入MemTable最后由CompactionManager定期合并为SSTable。若VPS异常断电MemTable中未刷盘的数据会丢失但CommitLog可恢复。验证方法# 查看CommitLog文件 ls -lh /var/lib/cassandra/commitlog/ # 应有类似CommitLog-7e9b3a1c-2f4d-4b8e-9a0c-1d2e3f4a5b6c.log文件 # 其大小随INSERT操作增长若重启后数据消失执行sudo -u cassandra /opt/cassandra/bin/nodetool flush # 强制将MemTable刷入SSTable sudo systemctl restart cassandra # 重启后数据应恢复提示生产环境需配置commitlog_sync: batch而非默认periodic并增大commitlog_segment_size_in_mb: 128但单节点学习环境保持默认即可重点理解其设计哲学——用牺牲少量一致性换取极致写入吞吐。6. 进阶实践与能力延伸从单节点到