nosql中的index

cassandra中的SecondaryIndex的应用场景主要在于没有带着rowkey的查询。虽然带着rowkey的条件进行检索式cassandra这种非关系型数据库的主流检索,但是使用nosql DB的时候,往往一些统计功能,或者公共的功能,(例如关注度最高的微博,操作次数最多的操作等等)这些不需要和用户绑定,但是又是很多应用不可少的检索功能。并且在cassandra这种海量级的nosql DB中,如果没有Secondary Index这种功能提升没有带rowkey的查询性能的功能,那么就会丧失很多机会,让很多系统发展以后,都没有办法扩展自己的能力。

1、SecondaryIndex的结构

Secondary Index和所有的数据库的index一样是一个牺牲容量,换取某种查询性能的功能。系统会新建一个index表,来存放便于检索的数据,从而加快检索。而cassandra数据库的检索最成熟的条件,就是rowkey。所以Secondary index就是一个以index字段为rowkey,以数据表中的rowkey作为Column的StandCF。

在1.2版本的cassandra中实现的KeyIndex和CompositeIndex都是继承AbstractSimplePerColumnSecondaryIndex简单单列index的实现类。

public void init()
    {
        assert baseCfs != null && columnDefs != null && columnDefs.size() == 1;

        ColumnDefinition columnDef = columnDefs.iterator().next();
        init(columnDef);

        AbstractType indexComparator = SecondaryIndex.getIndexComparator(baseCfs.metadata, columnDef);
        CFMetaData indexedCfMetadata = CFMetaData.newIndexMetadata(baseCfs.metadata, columnDef, indexComparator);
        indexCfs = ColumnFamilyStore.createColumnFamilyStore(baseCfs.table,
                                                             indexedCfMetadata.cfName,
                                                             new LocalPartitioner(columnDef.getValidator()),
                                                             indexedCfMetadata);

        // enable and initialize row cache based on parent's setting and indexed column's cardinality
        CFMetaData.Caching baseCaching = baseCfs.metadata.getCaching();
        if (baseCaching == CFMetaData.Caching.ALL || baseCaching == CFMetaData.Caching.ROWS_ONLY)
        {
            /*
             * # of index CF's key = cardinality of indexed column.
             * if # of keys stored in index CF is more than average column counts (means tall table),
             * then consider it as high cardinality.
             */
            double estimatedKeys = indexCfs.estimateKeys();
            double averageColumnCount = indexCfs.getMeanColumns();
            if (averageColumnCount > 0 && estimatedKeys / averageColumnCount > 1)
            {
                logger.debug("turning row cache on for " + indexCfs.getColumnFamilyName());
                indexCfs.metadata.caching(baseCaching);
                indexCfs.initRowCache();
            }
        }
    }

2、SecondaryIndex表的属性

SecondaryIndex的CF的属性有:

属性名属性值
keyspaceName源CF的keyspaceName
CFTypeStandard CF
Rowkey的类型index字段的类型
读修复概率0
GC清理时间0
keycache开启配置如果源CF开启则开启
RowCache开启配置
compact策略与源CF一致
compress策略与源CF一致


public static CFMetaData newIndexMetadata(CFMetaData parent, ColumnDefinition info, AbstractType<?> columnComparator)
    {
        // Depends on parent's cache setting, turn on its index CF's cache.
        // Here, only key cache is enabled, but later (in KeysIndex) row cache will be turned on depending on cardinality.
        Caching indexCaching = parent.getCaching() == Caching.ALL || parent.getCaching() == Caching.KEYS_ONLY
                             ? Caching.KEYS_ONLY
                             : Caching.NONE;

        return new CFMetaData(parent.ksName, parent.indexColumnFamilyName(info), ColumnFamilyType.Standard, columnComparator, null)
                             .keyValidator(info.getValidator())
                             .readRepairChance(0.0)
                             .dcLocalReadRepairChance(0.0)
                             .gcGraceSeconds(0)
                             .caching(indexCaching)
                             .compactionStrategyClass(parent.compactionStrategyClass)
                             .compactionStrategyOptions(parent.compactionStrategyOptions)
                             .reloadSecondaryIndexMetadata(parent);
    }


3、SecondaryIndex创建的条件

在普通的CF创建的时候,如果Column定义的时候,indexType属性可以为KEYS(即为KeyIndex),COMPOSITES(即为CompositeIndex),CUSTOM(即为用户自己二次开发的index功能)。

在1.2版本的cassandra中,目前只支持KeyIndex,主要是针对StandCF的普通Column的和CompositeIndex主要是针对CompositeCF的普通Column。

/**
     * Drops and adds new indexes associated with the underlying CF
     */
    public void reload()
    {
        // figure out what needs to be added and dropped.
        // future: if/when we have modifiable settings for secondary indexes,
        // they'll need to be handled here.
        Collection<ByteBuffer> indexedColumnNames = indexesByColumn.keySet();
        for (ByteBuffer indexedColumn : indexedColumnNames)
        {
            ColumnDefinition def = baseCfs.metadata.getColumn_metadata().get(indexedColumn);
            if (def == null || def.getIndexType() == null)
                removeIndexedColumn(indexedColumn);
        }

        for (ColumnDefinition cdef : baseCfs.metadata.getColumn_metadata().values())
            if (cdef.getIndexType() != null && !indexedColumnNames.contains(cdef.name))
                addIndexedColumn(cdef);

        Set<SecondaryIndex> reloadedIndexes = Collections.newSetFromMap(new IdentityHashMap<SecondaryIndex, Boolean>());
        for (SecondaryIndex index : indexesByColumn.values())
        {
            if (reloadedIndexes.add(index))
                index.reload();
        }
    }

4、SecondaryIndex的应用




5、SecondaryIndex与源数据表的关系

Secondary IndexCF都是每个节点自己的本地表,没有副本,所以当数据迁移的时候,需要重新生成对应的index数据。

(1)重启的时候,需要在加载数据表的时候,加载出对应的indexCF结构。这样就根据indexInfo系统表中有没有对应的indexCF的记录,判断indexCF是否需要生成index数据,如果IndexInfo系统表有对应的indexCF数据,则不需要重新生成indexCF的数据,如果没有,则需要重新生成。

问题:如果indexCF在生成对应的数据的时候,此时进行的index条件的查询,由于index数据还没有生成完全导致极大可能差不多数据。




### Nosql 数据库 InfluxDB 介绍 InfluxDB 是一款专门为时间序列数据设计的开源 NoSQL 数据库。它的核心特性使其非常适合物联网 (IoT) 应用程序、监控系统以及其他需要高效存储和查询大量带时间戳数据的应用场景[^1]。 #### 主要特性 - **高性能写入与查询**: InfluxDB 被优化用于高速摄取大量的时间序列数据点,同时提供高效的实时查询能力。 - **内置支持 TSI(Timestamp Index)**: 这种新型的时间戳索引机制极大地提高了大数据量下的查询速度, 尤其是对带有标签过滤器的大范围扫描操作 [^4]. - **灵活的数据模型**: 支持字段(field), 标签(tag), 时间戳(timestamp)三者组合而成的独特模式来表示每一条记录. - **丰富的生态系统**: 包括 Chronograf(可视化工具), Telegraf(采集插件集合) 和 Kapacitor(告警处理引擎),共同构成了 TICK Stack 解决方案. #### 使用场景 由于上述特点,InfluxDB 广泛应用于以下几个领域: 1. **指标收集与分析**: 如服务器性能监测(CPU/MEM/DISK I/O etc.), 网络流量统计等业务场景下表现优异; 2. **日志管理平台构建基础组件之一**, 可以用来替代传统的关系型数据库来进行海量事件消息存档; 3. 工业自动化控制过程中的传感器数值追踪记录工作流中也常能看到它的身影; 然而值得注意的是尽管如此强大但仍然存在局限性比如不支持 OR 查询条件这可能会限制某些特定场合下的灵活性应用[^1]. ```python from influxdb import InfluxDBClient client = InfluxDBClient('localhost', 8086, 'root', 'root', 'example') json_body = [ { "measurement": "cpu_load_short", "tags": { "host": "server01", "region": "us-west" }, "time": "2009-11-10T23:00:00Z", "fields": { "value": 0.64 } } ] client.write_points(json_body) ``` 上面这段 Python 示例演示了如何向名为 `example` 的数据库里插入单条 CPU 负载相关的测量值。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值