• Cassandra:基本概念


    数据模型

    Cassandra的数据模型与常见的关系型数据库的数据模型有很大的不同

    列(Column)

    列是Cassandra的基本数据结构单元,具有三个值:名称,值、时间戳

    名称 时间戳
    name:byte[] value:byte[] clock:byte[]

    在Cassandra中不需要预先定义列(Column),只需要在KeySpace里定义列族,然后就可以开始写数据了。

    列族( Column Family)

    列族相当于关系数据库的表(Table),是包含了多行(Row)的容器。

    ColumnFamily的结构举例,如图:

    image-20220315150408187

    可以理解为Java结构 Map<String,Map<byte[],Column>>,如图:

    image-20220315150438136

    1)ColumnFamily 的2种类型

    • 静态column family(static column family)

    静态的column family,字段名是固定的,比较适合对于这些column都有预定义的元数据

    • 动态column family(dynamic column family)

    动态的column family,字段名是应用程序计算出来并且提供的,所以column family只能定义这些字段的类型,无法不可以指定这些字段的名字和值,这些名字和值是由应用程序插入某字段才得出的。

    2)Row key

    ColumnFamily 中的每一行都用Row Key(行键)来标识,这个相当于关系数据库表中的主键,并且总是被索引的。

    3)主键

    Cassandra可以使用PRIMARY KEY 关键字创建主键,主键分为2种

    • Single column Primary Key

    如果 Primary Key 由一列组成,那么称为 Single column Primary Key

    • Composite Primary Key(复合主键)

    如果 Primary Key 由多列组成,那么这种情况称为 Compound Primary Key 或 Composite Primary Key

    列族具有以下属性 -

    • keys_cached - 它表示每个SSTable保持缓存的位置数。
    • rows_cached - 它表示其整个内容将在内存中缓存的行数。
    • preload_row_cache -它指定是否要预先填充行缓存。

    键空间 (KeySpace)

    Cassandra的键空间(KeySpace)相当于数据库,我们创建一个键空间就是创建了一个数据库。

    键空间包含一个或多个列族(Column Family)

    注意:一般将有关联的数据放到同一个 KeySpace 下面

    键空间 (KeySpace) 创建的时候可以指定一些属性:副本因子,副本策略,Durable_writes(是否启用 CommitLog 机制)

    副本因子(Replication Factor)

    副本因子决定数据有几份副本。例如:

    副本因子为1表示每一行只有一个副,。副本因子为2表示每一行有两个副本,每个副本位于不同的节点上。在实际应用中为了避免单点故障,会配置为3以上。

    注意:所有的副本都同样重要,没有主从之分。可以为每个数据中心定义副本因子。副本策略设置应大于1,但是不能超过集群中的节点数。

    副本放置策略 (Replica placement strategy)

    描述的是副本放在集群中的策略

    目前有2种策略,内容如下:

    策略名 中文名 描述
    SimpleStrategy 简单策略 适用于只有一个数据中心。为集群指定简单的副本因子(有几个副本)
    NetworkTopologyStrategy 网络拓扑策略 推荐方式,因为可以扩展到多数据中心,可以单独为每个数据中心设置复制因子

    Durable_writes

    否对当前KeySpace的更新使用commitlog,默认为true

    副本 (Replication)

    副本就是把数据存储到多个节点,来提高容错性

    节点(Node)

    存储数据的机器

    集群(Cluster)

    Cassandra数据库是为跨越多条主机共同工作,对用户呈现为一个整体的分布式系统设计的。Cassandra最外层容器被称为群集。Cassandra将集群中的节点组织成一个环(ring)(一致性hash处理),然后把数据分配到集群中的节点(Node)上。

    超级列

    超级列是一个特殊列,因此,它也是一个键值对。但是超级列存储了子列的地图。

    通常列族被存储在磁盘上的单个文件中。因此,为了优化性能,重要的是保持您可能在同一列族中一起查询的列,并且超级列在此可以有所帮助。下面是超级列的结构。

    数据类型

    CQL提供了一组丰富的内置数据类型,用户还可以创建自己的自定义数据类型。

    CQL是Cassandra提供的一套查询语言

    数值类型

    数据类型 含义 描述
    int 32位有符号整型 和 Java 中的 int 类似
    bigint 64位长整型 和 Java 中的 long 类似
    smallint 16位有符号整型 和 Java 中的 short 类似
    tinyint 8位有符号整型 和 Java 中的 tinyint 类似
    varint 可变精度有符号整数 和 Java 中的 java.math.BigInteger 类似
    float 32位 IEEE-754 浮点型 和 Java 中的 float 类似
    double 64位 IEEE-754 浮点型 和 Java 中的 double 类似
    decimal 可变精度的 decimal 和 Java 中的 java.math.BigDecimal 类似

    文本类型

    CQL提供2种类型存放文本类型,text和varchar基本一致

    数据类型 含义 描述
    ascii 文本 表示ASCII字符串
    text 文本 表示UTF8编码的字符串
    varchar 文本 表示UTF8编码的字符串

    时间类型

    数据类型 含义 描述
    timestamp 时间 包含了日期和时间,使用64位有符号的整数表示
    date 日期
    time 时间

    标识符类型

    类型 含义 描述
    uuid 128位数据类型 通用唯一识别码
    CQL 中的 uuid 实现是 Type 4 UUID,其实现完全是基于随机数的
    timeuuid Type 1 UUID

    集合类型

    1)set

    集合数据类型,set 里面的元素存储是无序的。

    set 里面可以存储前面介绍的数据类型,也可以是用户自定义数据类型,甚至是其他集合类型。

    2)list

    list 包含了有序的列表数据,默认情况下,数据是按照插入顺序保存的。

    3)map

    map 数据类型包含了 key/value 键值对。key 和 value 可以是任何类型,除了 counter 类型

    使用集合类型要注意:
    1、集合的每一项最大是64K。
    2、保持集合内的数据不要太大,免得Cassandra 查询延时过长,Cassandra 查询时会读出整个集合内的数据,集合在内部不会进行分页,集合的目的是存储小量数据。
    3、不要向集合插入大于64K的数据,否则只有查询到前64K数据,其它部分会丢失。

    其他基本类型

    类型 含义 描述
    boolean 布尔类型 值只能为 true/false
    blob 二进制大对象 存储媒体或者其他二进制数据类型时很有用
    inet IPv4 或 IPv6 网络地址 cqlsh 接受用于定义 IPv4 地址的任何合法格式,包括包含十进制,八进制或十六进制值的点或非点式表示
    CQL 会输出为 0.0.0.0 这种 地址形式。
    counter 计数器类型 值不能直接设置,而只能递增或递减
    不能用作主键的一部分;如果使用计数器,则除primary key 列之外的所有列都必须是计数器

    用户自定义类型

    如果内置的数据类型无法满足需求,可以使用自定义数据类型。

    Cassandra的数据存储

    Cassandra的数据包括在内存中的和磁盘中的数据。

    CommitLog:主要记录客户端提交过来的数据以及操作。这种数据被持久化到磁盘中,方便数据没有被持久化到磁盘时可以用来恢复。

    Memtable:用户写的数据在内存中的形式,它的对象结构在后面详细介绍。其实还有另外一种形式是BinaryMemtable 这个格式目前 Cassandra 并没有使用,这里不再介绍了。

    SSTable:数据被持久化到磁盘,这又分为 Data、Index 和 Filter 三种数据格式。

    CommitLog 数据格式

    Cassandra在写数据之前,需要先记录日志,保证Cassandra在任何情况下宕机都不会丢失数据,这就是CommitLog日志。要写入的数据按照一定格式组成 byte 组数,写到 IO 缓冲区中定时的被刷到磁盘中持久化。Commitlog是server级别的。每个Commitlog文件的大小是固定的,称之为一个CommitlogSegment

    当一个Commitlog文件写满以后,会新建一个的文件。当旧的Commitlog文件不再需要时,会自动清除。

    Memtable 内存中数据结构

    数据写入的第二个阶段,MemTable是一种内存结构,当数据量达到块大小时,将批量flush到磁盘上,存储为SSTable。优势在于将随机IO写变成顺序IO写,降低大量的写操作对于存储系统的压力。每一个columnfamily对应一个memtable。也就是每一张表对应一个。用户写的数据在内存中的形式。

    SSTable 数据格式

    SSTable是Read Only的,且一般情况下,一个ColumnFamily会对应多个SSTable,当用户检索数据时,Cassandra使用了Bloom Filter,即通过多个hash函数将key映射到一个位图中,来快速判断这个key属于哪个SSTable。

    为了减少大量SSTable带来的开销,Cassandra会定期进行compaction,简单的说,compaction就是将同一个ColumnFamily的多个SSTable合并成一个SSTable。

    在Cassandra中,compaction主要完成的任务是:

    1) 垃圾回收: cassandra并不直接删除数据,因此磁盘空间会消耗得越来越多,compaction 会把标记未删除的数据真正删除;

    2) 合并SSTable:compaction 将多个 SSTable 合并为一个(合并的文件包括索引文件,数据文件,bloom filter文件),以提高读操作的效率;

    3) 生成 MerkleTree:在合并的过程中会生成关于这个ColumnFamily中数据的 MerkleTree,用于与其他存储节点对比以及修复数据。

    Cassandra的重要知识点

    Cassandra的集群中每一台机器都是对等的,不存在主、从节点的区分,集群中任何一台机器出现故障是,整个集群系统不会受到影响。

    一致性哈希是Cassandra搭建集群的基础,一致性哈希可以降低分布式系统中,数据重新分布的影响。

    在Cassandra中,每个表有Primary Key外,还有一个叫做Partition Key,Partition Key列的Value会通过Cassandra一致性算法得出一个哈希值,这个哈希值将决定这行数据该放到哪个节点上。

    每个节点拥有一段数字区间,这个区间的含义是:如果某行记录的Partition Key的哈希值落在这个区间范围之内,那么该行记录就该被存储到这个节点上。

    如果简单的使用哈希值,可能会引起数据分布不均匀的问题,为了解决这个问题,一致性哈希提出虚拟节点的概念,简单的理解就是:将某个节点根据一个映射算法,映射出若干个虚拟子节点出来,再把这些节点分布在哈希环上面,保存数据时,如果通过一致性哈希计算落到某个虚拟子节点上,这条记录就会被存在这个虚拟子节点的母节点上。

    Token:在Cassandra,每个节点都对应一个token,相当于hash环中的一个节点地址。在Cassandra的配置文件中有一项配置叫做:num_tokens,这个配置项可以控制一个节点映射出来的虚拟节点的个数。

    Range:在Cassandra中,每一个节点负责处理hash环的一段数据,范围是从上一个节点的Token到本节点Token,这就是Range

    在健康的集群中,可以通过自带的工具nodetool查看集群的哈希环具体情况,命令为:nodetool ring。

    这里我们使用cassandra官方文档中一张图来说明:

    image-20220317152908133

    Gossip内部通信协议

    Cassandra使用Gossip的协议维护集群的状态,这是个端对端的通信协议。通过Gossip,每个节点都能知道集群中包含哪些节点,以及这些节点的状态,

    Gossip进程每秒运行一次,与最多3个其他节点交换信息,这样所有节点可很快了解集群中的其他节点信息。

  • 相关阅读:
    2019-05-07
    2019-04-28 问题记录
    2019-04-15 python深浅复制
    2019-04-11 统计日志重复数量
    2019-03-23 shell练习,日志统计
    问题记录2019-03-12
    问题记录2019-03-06(todo)
    回归
    Mac进行 usr/bin 目录下修改权限问题,operation not permitted
    个人的随笔心情
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/16008700.html
Copyright © 2020-2023  润新知