Cassandra报错 Not enough replicas avaiable for query at consistency LOCAL_ONE

解决Cassandra集群查询失败:节点下线与replication_factor设置问题

之前开发装了个时序数据库Cassandra的集群,一共3个节点,用于存储底层MQTT上报的数据,通过SpringBoot在网页展示,最近Cassandra开始反复出问题。

Java后台打印日志CQL报错 Not enough replicas avaiable for query at consistency LOCAL_ONE (1 required but only 0 alive)这个错误其实说的很清楚:没有足够的副本可用于一致性为1的查询(需要1个,但只有0个有效)。Cassandra运行query需要至少1个节点,而节点数量为0。这就很奇怪,明明之前部署了3个节点,怎么会1个都访问不到。

排查3个节点的具体情况,发现有1个节点服务器下线了,但是另外两个均正常运行。我们的情况暂时无法重启节点服务器,所以需要从其他方向入手。

搜索错误之后决定排查keyspace的replication_factor复制因子情况,通过正常节点所在的服务器,命令行进入数据库./cqlsh xxx.xxx.xxx.xxx,在数据库中查询keyspace具体情况desc keyspacename; 找到replication_factor,果然,这里对应数字为1。3个节点的集群算是白部署了,keyspace的replication_factor为1,读写都有可能会遇到查询那个坏了的节点,从而导致查询失败的情况。这里需要改写复制因子来对应集群节点,运行以下命令:

alter keyspace keyspacename with replication = {'class': 'SimpleStrategy', 'replication_factor': 3};

这里执行需要一点时间,等待执行完后再运行desc keyspacename; 确认replication_factor修改完毕。

再度检查Java程序,程序正常运行。

另外,Cassandra集群中的节点服务器下线,有可能导致各种报错,以下三种情况,怀疑全部是由于节点下线和复制因子设置为1导致,有待进一步确认:

1. 读写Cassandra数据可能会出现NoHostAvailable错误

2. 更新keyspace时,会因为节点下线产生版本不一致报错schema version mismatch detected; check the schema versions of your nodes in system.local and system.peers.

3. Java后台日志出现system.peers相关错误query 'SELECT * FROM system.peers' timed out after PT0.5S

Cassandra 中,`CONSISTENCY LOCAL_ONE` 表示写入操作只需在本地数据中心的**一个副本节点**上成功即可返回,适用于对低延迟要求高且能容忍短暂不一致的场景。以下是关键点解析及示例操作: --- ### **1. 语句解析** ```sql CONSISTENCY LOCAL_ONE; -- 设置一致性级别为“本地单节点” INSERT INTO consistency_test.sensor_data (sensor_id, timestamp, value) VALUES (uuid(), toTimestamp(now()), 23.5); ``` - **`LOCAL_ONE`**:仅要求本地数据中心的**一个节点**确认写入,不等待其他数据中心(多数据中心集群中)。 - **`uuid()`**:生成唯一传感器 ID。 - **`toTimestamp(now())`**:将当前时间转为 Cassandra 的时间戳格式。 - **`23.5`**:传感器数值。 --- ### **2. 执行流程** 1. **协调节点**(客户端连接的节点)接收请求。 2. **本地副本确认**:协调节点将写入转发到拥有该分区(Partition)的本地副本节点,等待其响应。 3. **返回结果**:本地副本确认后立即返回成功,**不等待其他节点**(包括远程数据中心的副本)。 --- ### **3. 适用场景** - **低延迟写入**:如实时传感器数据、日志收集。 - **容忍短暂不一致**:允许后续读取时可能读到旧值(最终一致性)。 - **单数据中心部署**:若集群仅有一个数据中心,`LOCAL_ONE` 与 `ONE` 行为一致。 --- ### **4. 潜在问题** #### **问题 1:数据丢失风险** - **场景**:写入成功的节点在数据同步到其他节点前宕机。 - **解决**:根据业务需求选择更高一致性级别(如 `QUORUM`)。 #### **问题 2:读取不一致** - **现象**:立即读取可能返回旧值(因其他副本尚未同步)。 - **解决**:读取时使用相同或更高的一致性级别(如 `CONSISTENCY LOCAL_QUORUM`)。 --- ### **5. 对比其他一致性级别** | 级别 | 描述 | |---------------|----------------------------------------------------------------------| | `ONE` | 任意一个节点确认即可(可能跨数据中心)。 | | `LOCAL_ONE` | 仅本地数据中心的一个节点确认。 | | `QUORUM` | 大多数副本确认(跨数据中心时需计算多数)。 | | `ALL` | 所有副本确认(最高一致性,但性能最低)。 | --- ### **6. 验证一致性级别** #### **方法 1:通过 CQLSH 查看当前设置** ```sql CONSISTENCY; -- 显示当前一致性级别(执行前需先运行 CONSISTENCY LOCAL_ONE) ``` #### **方法 2:检查表配置** ```sql DESCRIBE TABLE consistency_test.sensor_data; ``` - 注意:表定义中的 `read_request_timeout_in_ms` 等参数可能影响实际行为。 --- ### **7. 完整示例(含表创建)** ```sql -- 创建键空间和表(单数据中心时 replication_factor=1 即可) CREATE KEYSPACE IF NOT EXISTS consistency_test WITH replication = {'class': 'NetworkTopologyStrategy', 'DC1': 1}; CREATE TABLE IF NOT EXISTS consistency_test.sensor_data ( sensor_id UUID, timestamp TIMESTAMP, value DOUBLE, PRIMARY KEY (sensor_id, timestamp) ); -- 设置一致性级别并插入数据 CONSISTENCY LOCAL_ONE; INSERT INTO consistency_test.sensor_data (sensor_id, timestamp, value) VALUES (uuid(), toTimestamp(now()), 23.5); -- 验证数据 SELECT * FROM consistency_test.sensor_data LIMIT 1; ``` --- ### **8. 性能优化建议** - **批量写入**:使用 `BATCH` 语句减少网络开销(但需控制批量大小)。 - **异步写入**:在应用层启用异步提交(如 Cassandra Java Driver 的 `async` 模式)。 - **调整副本数**:单数据中心时,`replication_factor=1` 可减少协调开销。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值