cassandra随机获取数据_Cassandra实战 笔记-《Cassandra内部数据存储结构》

本文深入探讨了Cassandra的数据存储结构,包括Commitlog用于临时存储更新数据,保证数据不丢失;Memtable作为内存缓冲,将随机写转化为顺序写;以及SSTable作为数据持久化文件,由Data、Filter、Index和Statistics四个部分组成。Cassandra的system表空间用于存储元数据和HINT数据,理解这些机制对于优化Cassandra应用至关重要。
摘要由CSDN通过智能技术生成

1.1 Cassandra中的数据存放规则

Cassandra的配置文件可以对Cassandra中的数据进行配置。cassandra.yaml 中关于存放数据信息的配置如下:

# directories where Cassandra should store data on disk.

data_ file, directories:

- /var/lib/cassandra /data

# commit log

commitlog.directory: /var/lib/cassandra /commitlog

saved caches

saved_caches_ directory: /var/lib/cassandra /saved_ caches

数据信息一共分为以下3类:

data目录:用于存储真正的数据文件,即后面将要讲到的SSTable文件。如果服务器有多个磁盘,可以指定多个目录,每一个目录都在不同的磁盘中。这样Cassandra就可以利用更多的硬盘空间。

commitlog目录: 用于存储未写人SSTable中的数据,每次Cassandra系统中有数据写入,都会先将数据记录在该日志文件中,以保证Cassandra在任何情况下宕机都不会丢失数据。如果服务器有足够多的磁盘,可以将本目录设置在一个与data目录和cache目录不同的磁盘中,以提升读写性能。

cache目录: 用于存储系统中的缓存数据。可以在cassandra. yaml文件中定义Column Family的属性中定义与缓存相关的信息,如缓存数据的大小(对应配置文件中的keys_cached和rOws_ cached)、 持久化缓存数据的时间间隔(对应配置文件中的row cache_save_ period in. seconds 和key. cache save period in seconds)等。当Cassandra系统重启的时候,会从该目录下加载缓存数据。如果服务器有足够多的磁盘空间,可以将本目录设置在一个与data目录和commitlog目录不同的磁盘中,以提升读写性能。

在data目录下,Cassandra 会将每一个 Keyspace 中的数据存储在不同的文件目录下,并且 Keyspace 文件

目录的名称与 Keyspace 名称相同。

假设有两个 Keyspace,分别为 ks1 和 ks2,但在 data目录下,将看到3个不同的目录:ks1,ks2和 system。其中 ks1 和 ks2 用于存储系统定义的两个 Keyspace 的数据,另外一个 system 目录是 Cassandra 系统默认的一个 Keyspace,叫做 system,它用来存储 Cassandra 系统的相关元数据信息以及 HINT 数据信息。

6.2 Commitlog

当 Cassandra 有数据需要更新时,第一个记录这个更新的地方就是 Commitlog。

Commitlog由如下两个部分构成:

CommitLog - xxx.log、CommitLog - xxx.log.header。

在 CommitLog - xxx.log 文件中,保存了每一次更新操作的值。

在 CommitLog - xxx.log.header 文件中,记录了哪些数据已经从 memtable 中写入 SSTable 中。

通过log. header文件中记录的元数据信息, Cassandra 可以及时删除不必要的Commitlog文件,减少磁盘的占用量,并在Cassandra重启时,加快从Commitlog中恢复数据的速度。

Commitlog文件的大小可以在配置文件中指定,默认是128MB。

Size to allow commitlog to grow to before creating a new segmentcommitl og_ rotat ion threshold in mb: 128

当一个Commitlog文件大小超过设置的阈值后,将会新建一个Commitlog,并将更新数据写人这个新的文件中。

Cassandra提供了两种记录Commitlog的方式:周期记录( periodic)和批量记录( batch)。如果使用周期记录的方式,需要在配置文件进行如下配置:

commit1og_ sync: periodic

commitlog_ sync. period in ms: 10000

Cassandra会每次更新信息将写人 Commitlog 中,并且每隔一定的时间间隔(commitlog-sync_ period in ms)调用 org apache. cassandra. io. util. BufferedRandomAccessFile. syne() 同步 Commitlog 文件。

如果使用批量记录的方式,需要在配置文件进行如下配置:

commitlog_ sync: batch

commitlog sync_ batch window_ in_ ms: 100

Cassandra会缓存每次更新信息,每隔一定的时间间隔(commitlog sync_ batch _window_in_ ms)调用 org. apache. cassandra. io. util. BuferedRandomAccessFile. syne () 同步Commitlog 文件,最后将之前缓存的更新信息写人Commitlog中。

如果不允许数据丢失,可以使用周期的方式记录 Commitlog。如果写入数据量非常大,同时可以承担由于机器可能宕机导致的数据丢失的风险,则使用批量记录的方式记录 Commitlog。

在实际的使用中,可以根据情况来选用合适的 Commitlog记录方式。

6.3 Memtable

数据写入 Commitlog 后,将缓存在 Memtable 中。

Cassandra 中每一个 Memetable 只为一个 ColumnFamily 提供服务。

当下面3个条件中任意个满足后,会将Memtable中缓存的数据写入磁盘,形成一个SSTable文件。

Memtable中缓存的数据达到容量( memtable_ throughput in _mb)上限。

Memtable中包含的数据的条数( memtable_ operations in millions超过上限。

Memtable距离上一次将缓存的数据写 人磁盘的时间超过某一 个间隔( memtable_ flush_after_mins)。

上面提到的3个参数都可以在配置文件中进行设置,Cassandra 为每一个ColumnFamily提供单独的配置。

memtable_ flush_ after mins: 59memtable_ throughput in mb: 255

memtable operations in millions: 0.29在Memtable中缓存数据的成员变量如下:

private final ConcurrentNavigabl eMap < DecoratedKey, ColumnFamily > colunnFami-lies = new Concurrent SkipListMap < DecoratedKey, columnFamily> ();

每当有数据进人 Memtable 中时,会将数据保存到成员变量 ColumnFarmilies 中,并解析这个数据,排除重复或者是已经过期的数据。具体实现如下:

void put (DecoratedKey key, ColumnFamily colunnFamily){

currentThroughput. addAndGet (cf. size());

currentoperat ions. addAndGet (cf. getColumnCount ));

ColumnFamily olacf = columnp amilies. putIfAbsent (key, cf); :if (oldCf == nu1l)

return;

oldCf. resolve (cf):

当Cassandra需要将Memtable中缓存的数据写人磁盘时,会按照内存中Key的顺序写人SSTable中。

private SsTableReader writeSort edContents () throws IOExcept ion

logger. info ("Writing”+ this);

SsTablewriter writer = new ssTableWriter (cfs. getFlushPath (),columnFamili-es.size(), cfs. metadata, cfs. partit ioner);

for (Map. Entry < DecoratedKey, ColunnFamily > entry : columnFamilies . entrySet ())

writer . append (entry . getKey (), entry .getvalue());

SSTableReader ssTable = writer. closeAndopenReader ();

logger.info("Completed flushing "+ ssTable.getFilename());

return ssTable;

使用 Memtable 的优势在于:将随机 IO 写变为顺序 IO 写,降低大量的写操作对存储系统的压力。

6.4 SSTable

Cassandra 中的 Memtable 会缓存客户端写入的数据,当Memtable中缓存的某一个ColumnFamily中的数据量( 对应配置文件中的 memtable_ throughput_ in mb和memtable_ operations_in_ millions 或者超过上一次生成SSTable的时间(对应配置文件中的 memtable flush_ after_mins)后,Cassandra 会将Memtable中对应的ColumnFamily的数据持久化到磁盘中,生成一个SSTable文件。

如ColumnFamily名称为Cfl的一个SSTable文件由如下文件组成:

Cf1 -e-1 - Data.db

Cf1 -e-1 - Filter.db

Cf1 -e-1 - Index.db

Cf1 -e-1 - Statistics.db

其中,“Cf1”为ColumnFamily的名称;“e” 为版本的标识(这个标识在0.7之前的版本中是没有的);“1”代表这是名称为Cfl的ColumnFamily的第一个SSTable,这个数字会随着新的SSTable文件的生成不断增加;“Data”、“Filter”、 “Index"和“Statistics" 分别代表 SSTable 4个不同组成部分,它们的作用各不相同。

6.5 系统表空间

在Cassandra中,除了用户自己定义的 Keyspace 之外,还有一个特殊的 Keyspace :名称为system的系统表空间。

用户不能在 Cassandra 中创建名为 system 的 Keyspace,只能由 Cassandra 系统自动创建。系统表空间的主要有以下两个作用:

管理Cassandra的系统元数据信息。

缓存HINT数据。

如果系统首次启动,Cassandra 将会自动在data目录下创建系统表空间,并将系统元数据信息存放在系统表空间中。以后启动的过程中,Cassandra 将会直接从系统表空间中读取系统元数据信息。

如果 Cassandra 发现某一个节点宕机,就会将发送给宕机节点的数据以 HINT 的形式发送给另外台 Cassandra 服务器。接收到 HINT 数据的 Cassandra 服务器将数据缓存到系统表空间中,当其发现宕机的 Cassandra 恢复后,将缓存 HINT 数据发送给恢复的服务器,完成数据传输后,将缓存的 HINT 数据从系统表空间中删除。

6.6 本章小结

本章从原理上分析和讲解了 Cassandra 的内部数据存储结构Commitlog、Memtable、SSTable和构成SSTable的4个子文件。了解Cassandra的内部数据存储构造有利于为基于Cassandra的应用程序设计合理的数据模型,以及找出造成读写瓶颈的原因。另外还介绍了Cassandra的系统表空间,了解了整个系统元数据管理的机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值