cassandra读写数据
写
写一致性级别
cassandra的可调一致性级别意味着你可以在查询中指定所需的写操作一致性,一致性级别越高,说明需要更多的副本节点相应才能认为写操作完成,更高的一致性级别还可能带来可用性的下降,因为必须有更多的节点可以使用,写操作才能成功
一致性级别 | 含义 |
---|---|
ANY | 返回到客户端之前,确保这个值写入一个副本节点,提示可以算作一个写操作 |
ONE, TWO, THREE | 返回到客户端之前, 确保至少写入1个,2个或3个节点的提交日志和memtable |
LOCAL_ONE | 与ONE类似,不过有额外要求:响应节点应当在本地数据中心 |
QUORUM | 确保至少大多数副本((副本因子/2)+1)接收了写操作 |
LOCAL_QUORUM | 与QUORUM类似,但响应节点应当在本地数据中心 |
EACH_QUORUM | 确保每个数据中心有QUORUM个节点响应 |
ALL | 返回到客户端之前,根据副本因子指定的节点数,确保相应数目的节点接收了写操作,即使只有一个副本没有写操作,操作也会失败 |
查看默认的一致性级别
cassandra写路径
写路径描述如何处理客户端发起的数据修改查询,最终将把数据存储在磁盘上
客户端向一个cassandra节点发起一个写查询时,写路径开始,这个节点将作为这个请求的协调器。协调器节点使用分区器根据键空间的副本因子确定集群中的哪些节点是副本节点。如果协调器知道没有足够的副本来满足所请求的一致性级别,它会立即返回一个错误。
然后,协调器节点为所写数据向所有副本同时发出写请求,这可以确保只要节点在线,所有节点都可以收到这个写操作,下线节点的数据可能不一致,不过这些节点将通过某种逆熵机制修复,如提示移交,读修复或逆熵修复
如果集群跨多个数据中心,本地协调器节点会在其他各个数据中心分别选择一个远程协调器,来协调向该数据中心的副本写入数据,每个远程副本直接响应原协调器节点,协调器等待副本响应,一旦有满足一致性级别的足够数量的副本做出响应,协调器就会向客户确认这个写操作。如果一个副本在超时时间内没有响应,就认为它已下线,并存储一个写操作提示,提示通常并不算是成功的副本写操作,除非使用了一致性级别ANY
首先,副本节点接收写请求,并将数据立即写至提交日志。接下来,副本节点将数据写入一个memtable。如果使用了行缓存,而且缓存中有这一行,则将缓存中这一行置位无效。
如果这个写操作导致提交日志或者memtable达到其最大阈值,就会调度运行一个刷新输出。此时认为写操作成功,节点可以向协调器节点或客户端做出回应,返回后,如果调度了刷新输出,节点会执行刷新输出,每个memtable的内容作为SSTable存储在磁盘上,并清空提交日志,刷新输出完成时,会调度额外的任务来检查是否需要合并,如果需要则合并。
轻量级事务
cassandra的轻量级事务支持以下语义:
- 每个事务的范围仅限于一个分区
- 每个事务由一个读和一个写组成,也称为“比较和设置”操作,只有比较成功时才会完成操作
- 如果由于现有的值与你期望的值不匹配而导致事务失败,cassandra会包含当前值,你能直接决定重试还是撤销,而不需要另外做一个请求
- 不支持USING TIMESTAMP选项
使用轻量级事务的场景在于,我们在向数据库中新增一条记录时,要先确认库中有没有该条记录,防止覆盖
一般就是加IF NOT EXISTS
, 如图
这个命令会查看是否有对应分区键的记录,再执行一次看看
事务失败,因为已经有一个ID为“AZ123”的记录了,
对于更新也类似
基于cassandra的更新插入模型,在insert上要使用IF NOT EXISTS
语法,而update要使用IF x=y
语法,这是两个操作在语法上的唯一区别
批处理
轻量级事务仅限于一个分区,而批处理允许把多个分区的修改操作分组到一个语句中
其语义如下:
- 批处理中只能包含修改语句(insert, update, delete)
- 批处理具有原子性,即批处理如果被接受,批处理中的所有语句最终都会成功
- 一个批处理中,属于给定分区键的所有更新会独立完成,不过分区之间不能保证隔离,因此,在批处理完成之前,可能会读取对不同分区的修改结果
- 批处理不是一种事务机制,不过可以在批处理中包含轻量级事务语句,一个批处理中的多个轻量级事务必须应用于同一分区。
- 计数器修改只能用于一种特殊形式的批处理,称为计算器批处理,计算器批处理只能包含计数器修改
利用批处理,可以避免在客户端和协调器节点之间来回传输,因为客户端能够将多个语句分组到一个查询中。
批处理,用
BEGIN BATCH
......
APPLY BATCH;
底层批处理的工作是这样的:
协调器将批处理的一个副本(batchlog)发送给另外两个节点,在这两个节点上,这个副本会存储在system.batchlog表中。然后协调器执行批处理中的所有语句,完成所有语句后再从其他节点删除batchlog。
如果协调器未能成功完成批处理,由于其他节点在其batchlog中有一个副本,所以能够重放这个批处理,每个节点每分钟检查一次它的batchlog,查看是否有应该完成的批处理,为了让协调器有充足的时间完成正在进行的批处理,cassandra会使用相对于批处理语句时间戳的一个宽限时间,它等于write_request_timeout_in_ms
属性的值或者是其两倍,所有比这个宽限时间老的批处理会重放,然后从其余节点删除。第二个batchlog节点可以另外提供一级冗余,确保批处理机制的高可靠性。
cassandra要求限制批处理语句的大小,避免他们变的无穷大而影响集群的性能和稳定性,cassandra.yaml中有两个属性来控制这一点:batch_size_warn_threshold_in_kb
属性定义一个批量大小的阈值(警告阈值),如果使用warn日志级别,达到该阈值时,日志中会记录接收到一个很大的批处理,而如果批量大小超过了batch_size_fail_threshold_in_kb
所设置的值(失败阈值),所有这样的批处理都会被拒绝,并向客户端发出错误通知。批量大小用CQL语句的长度来衡量,警告阈值默认5kb,失败阈值默认50kb。
读
如果客户端连接到一个节点,而这个节点上没有他想要的数据,所连接的节点就会作为协调器节点,从确实有数据的节点(由令牌区间标识)读取数据。
读一致性级别
读一致性级别与写一致性级别相似,这里,如果两个节点响应查询时有不同的时间戳,会采用最新的值,然后cassandra会在后台完成读修复,他会注意到响应一个查询的一个或多个副本有过期的值,并用最新的值更新这些副本,使得他们都一致。
一致性级别 | 含义 |
---|---|
ONE, TWO,THREE | 立即返回响应查询的第一个节点(两个或三个节点之中)包含的最新记录,会记录一个后台线程对这个记录与其他副本上的相同记录进行比较,如果有任何记录过期,就会完成一个读修复(read repair), 使他们都同步到最新值 |
LOCAL_ONE | 类似ONE, 只有一个额外要求:响应节点必须在本地数据中心 |
QUORUM | 查询所有节点,一旦大多数副本((副本因子/2)+1)做出响应,则向客户端返回有最新时间戳的值,然后,如果需要,对后台其余副本完成一个读修复 |
LOCAL_QUORUM | 同上,但响应节点必须在本地数据中心 |
EACH_QUORUM | 确保每个数据中心有QUORUM个节点响应 |
ALL | 查询所有节点,等待所有节点响应,返回有最新时间戳的值,如果有需要,对其余副本完成读修复 |
如果一个节点在指定时间(rpc_timeout_in_ms)之前没有响应一个查询,就认为这个节点无响应,默认为10秒。
cassandra读路径
客户端请求数据时会发生什么,这称为读路径
客户端向协调器节点发起一个读查询时,读路径开始,,与写路径一样,协调器使用分区器来确定副本,并检查是否有足够的副本能够满足请求的一致性级别,对于涉及多个数据中心的查询,会在每个数据中心选择一个远程协调器。
如果协调器本身不是一个副本,它会把读请求发送到最快的副本(由动态snitch确定),协调器节点还会向其他副本发送一个摘要请求,摘要请求与标准读请求类似,不过副本会返回所请求数据的一个摘要或哈希,协调器会为从最快副本返回的数据计算摘要哈希,将他与从其他副本返回的摘要比较,若一致,而且满足所需的一致性级别,就返回从最快副本得到的数据,若不一致,协调器会完成一个读修复。
再来看一下读请求时各个副本节点内部的交互
副本节点接收到读请求时,首先会检查行缓存,若有,则返回,若没有,副本节点会在memtable和SSTable中搜索该数据,对于一个给定的表只有一个memtable,但是,对应一个cassandra表可能会有多个物理SSTable,每个SSTable中可能包含所请求数据一部分。
cassandra实现了很多特性来优化SSTable搜索:键缓存、布隆过滤器、SSTable索引和摘要索引。
在磁盘上搜索SSTable的第一步,是使用一个布隆过滤器确定所请求的分区在不在给定SSTable中,如果不存在就没必要搜索这个SSTable了,
如果SSTable通过了布隆过滤器的检查(即SSTable可能包含这个分区),cassandra会检查键缓存,查看是否包含分区键在SSTable中的偏移位置,键缓存实现为一个映射结构,其中键是SSTable文件描述符和分区键的组合,值是SSTable文件中的偏移位置,利用键缓存,可以避免在SSTable文件中查找频繁访问的数据,因为这些数据可以直接读取。
如果没能从键缓存读到偏移位置,cassandra会使用磁盘上存储的一个二级索引找到这个偏移位置,第一级索引为分区摘要,这用来得到第二级索引的偏移位置,从而在第二级索引(分区索引)中搜索分区键,分区键在SSTable中的偏移位置就存储在分区索引中,如果找到了分区键的偏移位置,cassandra会在指定的偏移位置访问SSTable,并开始读取数据
一旦从所有SSTable得到了数据,cassandra会利用所请求的各个列的最新时间戳选择值,来合并SSTable数据和memtable数据,遇到的所有墓碑都会被忽略
在分区索引中,如果找到了分区键的偏移位置,cassandra会在指定的偏移位置访问SSTable,并开始读取数据
一旦从所有SSTable得到了数据,cassandra会利用所请求的各个列的最新时间戳选择值,来合并SSTable数据和memtable数据,遇到的所有墓碑都会被忽略
最后,可以将合并后的数据增加到行缓存(如果启用了行缓存),并返回给客户端或调节器节点,摘要请求处理与常规读请求的处理方法是一样的,不过还有额外一步:要对结果数据计算一个摘要,并返回这个摘要而不是数据本身。
参考<<cassandra权威指南>>
来源:CSDN
作者:yuyang4600
链接:https://blog.csdn.net/yuyang4600/article/details/104174887