关于Cassandra启动加载索引是报AssertionError的问题及解决

本文记录了一次在Cassandra中解决二级索引加载失败的问题经历,通过升级版本和重建索引最终解决了问题。
部署运行你感兴趣的模型镜像

       

       系统环境:

        linux5.4  64位

        jdk1.6.45 64位

        Cassandra1.2.5

        最近在使用Cassandra做一个通讯录的存储工作,通讯录表共建了三个二级索引,有三个复合主键,有一个功能就是根据某二级索引查询出相关的所有联系人,该二级索引的长度大约为32,可以看做是主键的一个子集。

建表语句如下:

CREATE TABLE contactsmimic (
	owneruserid text,
	contactid text,
	phone text,
	label text,//use as timestamp for protoObj
	friendid text,
	ismutual int,
	phoneindex text,
	isdeleted int,
	Json blob,
	PRIMARY KEY (owneruserid, contactid, phone)
) ;
CREATE INDEX relation_friendid ON contactsmimic (friendid);
CREATE INDEX index_isdelete ON contactsmimic (isdeleted);
CREATE INDEX relation_phoneindex ON contactsmimic (phoneindex);

   数据量大概10万条左右,每次启动报如下错误:

  INFO [SSTableBatchOpen:1] 2013-09-03 09:27:36,573 SSTableReader.java (line 169) Opening /var/lib/cassandra/data/contactks/cpmimic/contactks-cpmimic.cpmimic_friendid_idx-ic-1 (485779 bytes)
ERROR [SSTableBatchOpen:1] 2013-09-03 09:27:36,573 CassandraDaemon.java (line 175) Exception in thread Thread[SSTableBatchOpen:1,5,main]
java.lang.AssertionError
	at org.apache.cassandra.utils.ByteBufferUtil.readBytes(ByteBufferUtil.java:401)
	at org.apache.cassandra.io.sstable.IndexSummary$IndexSummarySerializer.deserialize(IndexSummary.java:124)
	at org.apache.cassandra.io.sstable.SSTableReader.loadSummary(SSTableReader.java:426)
	at org.apache.cassandra.io.sstable.SSTableReader.load(SSTableReader.java:360)
	at org.apache.cassandra.io.sstable.SSTableReader.open(SSTableReader.java:201)
	at org.apache.cassandra.io.sstable.SSTableReader.open(SSTableReader.java:154)
	at org.apache.cassandra.io.sstable.SSTableReader$1.run(SSTableReader.java:241)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)

  

     而比较奇怪的是同样的数据放到32位机器上确没有任何错误。

     解决过程也算费劲脑汁,升级JDK,升级Cassandra,升级glibc,升级操作系统,结果一无所获,要么索引直接失效,无法查询,要么加载失败。

     就在快要放弃的时候,发现官网发布了Cassandra2.0.0,死马当活马医,权且一试,启动Cassandra,drop index,create index,还有nodetool rebuild_index,再重启,发现错误消失了,真是庆幸,但还不明确是哪一步使索引重建的。

      还发现一个事情,Cassandra1.2*的索引文件是以ic为标识了,到了Cassandra2.0,是以ja为标识的。

    

      最后,没有问题的部署环境如下:

      Linux6.3   64位

      JDK1.7.25 64位

      Cassandra2.0.0

  

    

 

PS:当然以上不是解决问题的好方式,并没有找到根本问题,哪位大牛找到问题症结,请不吝赐教

     

您可能感兴趣的与本文相关的镜像

Facefusion

Facefusion

AI应用

FaceFusion是全新一代AI换脸工具,无需安装,一键运行,可以完成去遮挡,高清化,卡通脸一键替换,并且Nvidia/AMD等显卡全平台支持

### **Cassandra 二级索引Secondary Index)详解** #### **1. 定义** 二级索引Secondary Index)是 **基于非主键列(普通列)创建的索引**,用于加速对非分区键(Non-Partition Key)的查询。 **核心特点**: - 允许按 **非主键列** 查询(如 `WHERE email = 'user@example.com'`)。 - 索引数据 **与表数据存储在同一节点**(本地索引),不跨节点分布。 --- #### **2. 为什么需要二级索引?** Cassandra 的默认查询模式要求 **必须指定分区键(Partition Key)**,例如: ```sql SELECT * FROM users WHERE id = 1; -- 高效(id 是主键) ``` 但如果想按非主键列查询: ```sql SELECT * FROM users WHERE email = 'user@example.com'; -- 低效(全表扫描) ``` **二级索引** 解决了这个问题,使得这类查询可行。 --- #### **3. 二级索引的工作原理** - **存储方式**: 每个节点 **独立维护** 自己数据分片的索引(不跨节点同步)。 - 例如,节点A存储 `email` 索引的 `A-M` 部分,节点B存储 `N-Z` 部分。 - **查询流程**: 1. 客户端发起查询(如 `WHERE email = 'x'`)。 2. **所有节点** 并行检查本地索引,找到匹配的分区键。 3. 返回最终结果。 --- #### **4. 二级索引的适用场景** ✅ **低基数(Low Cardinality)列**: - 例如性别、省份、状态(值重复率高)。 ✅ **点查询(精确匹配)**: - `WHERE status = 'active'`,而非范围查询。 ❌ **不适用场景**: - 高基数(High Cardinality)列(如 `user_id`),会导致索引过大。 - 频繁更新的列(索引维护成本高)。 --- #### **5. 二级索引的局限性** ⚠️ **性能问题**: - 需要 **广播查询** 到所有节点(`ALLOW FILTERING` 的隐式行为)。 - 不适合高并发或低延迟场景。 ⚠️ **不支持复杂查询**: - 不能组合多个非主键列(如 `WHERE age > 20 AND name = 'Alice'`)。 - 范围查询(`WHERE date > '2020-01-01'`)效率极低。 --- #### **6. 如何创建二级索引?** ```sql -- 语法 CREATE INDEX [index_name] ON table_name(column_name); -- 示例 CREATE INDEX idx_email ON users(email); ``` --- #### **7. 二级索引 vs. 物化视图(Materialized View)** | 特性 | 二级索引 | 物化视图 | |--------------------|----------------------------|----------------------------| | **查询灵活性** | 仅支持单列条件 | 支持多列组合查询 | | **性能** | 低(广播查询) | 高(预计算) | | **存储开销** | 较低 | 较高(冗余存储) | | **适用场景** | 简单条件查询 | 复杂查询模式 | --- #### **8. 替代方案** 如果二级索引性能不足,可考虑: 1. **物化视图**(Materialized View):预计算查询结果。 2. **手动冗余存储**:将查询需要的字段复制到主键中(如 `(country, email)` 作为复合主键)。 3. **使用搜索工具**:如 Elasticsearch 集成(适合全文检索)。 --- ### **经典面试题:为什么Cassandra的二级索引比关系型数据库(如MySQL)慢?** - **分布式架构**:需要广播查询所有节点,而MySQL的索引是全局的。 - **本地索引**:每个节点只维护自己数据的索引,无法全局排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值