专栏
天翼云开发者社区

Cassandra数据库数据一致性控制

2024-03-28 09:35:25 14阅读

  • 时间戳来源

    参数:DefaultTimestamp

    // Sends a client side timestamp for all requests which overrides the timestamp at which it arrives at the server. (default: true, only enabled for protocol 3 and above)

    Cassandra的每一列都是分版本存储的,即插入一列新数据,Cassandra都要赋予其一个时间戳作为版本号,如果主键一致,那原来的数据并不删除,而是直接把新数据覆盖在旧数据上,并按时间戳排序;每次查询都会获取时间戳最大的那一个。

    1. 当DefaultTimeStamp = false:当有数据插入或者更新的时候,所带来的列时间戳根据request所访问的cassandra节点的ntp服务时间作为列时间戳,并同步到集群的其他节点中。
      • 此时若cassandra集群内的节点服务器时间不一致,可能导致多客户端对不同cassandra操作同一key的时候,产生一致性的问题。
    1. 当DefaultTimeStamp = true:以客户端的时间戳为准,覆盖其到达服务端的时间戳
      • 当多个客户端节点时间不一致时,且多个客户端同时对数据库中的同一key值进行更新操作时,可能会导致数据的乱序,从而导致数据库写入失败;

    解决方法:

    1. 使用NTP同步数据库节点和需要访问数据库的节点之间的时间;
    2. 如果是多客户端,客户端之间还要同步时间;
    3. 使用Consistency Level: QUORUM;

    可调控的读写一致性

    Cassandra 提供了可调节的一致性,允许我们选定需要的一致性水平与可用性水平,在二者间找到平衡点。因为客户端可以控制在更新到达多少个副本之前,必须阻塞系统。这是通过设置副本因子(replication factor)来调节与之相对的一致性级别。

    通过副本因子(replication factor),你可以决定准备牺牲多少性能来换取一致性。副本因子是你要求更新在集群中传播到的节点数(注意,更新包括所有增加、删除和更新操作)。

    客户端每次操作还必须设置一个一致性级别(consistency level)参数,这个参数决定了多少个副本写入成功才可以认定写操作是成功的,或者读取过程中读到多少个副本正确就可以认定是读成功的。

    调控参数:SetConsistency

    Cassandra中,强调的是“最终一致性”,即如果在一致性级别较低时,Cassandra只能保证存储数据的最终一致,可能在某个时刻,数据库中所有副本之间的数据并不一致

    客户端在发起请求(读or写)时,可以指定一致性级别(默认为ONE),简单分为ONE,QUORUM和ALL。以单数据中心为例,假设数据中心有3个节点,replication_factors为3(表示数据的副本数量,用户创建键空间时指定),那么写请求的在三种一致性级别下的情况分别是:

    (1)ONE:客户端向3个(所有)节点都发送写请求,但是只要有任意一个节点返回写成功,那么本次客户端的写请求就算成功;

    (2)QUORUM:客户端向3个(所有)节点都发送写请求,必须满足QUORUM数量的节点返回写成功,那么本次客户端的写请求就算成功;

    (3)ALL:客户端向3个(所有)节点都发送写请求,必须所有节点返回写成功,那么本次客户端的写请求才算成功;

    读请求在三种一致性级别下的请求分别是:

    (1)ONE:客户端向3个(所有)节点都发送读请求,只要任意一个节点返回数据记录,就直接返回该节点的记录;

    (2)QUORUM:客户端向3个(所有)节点都发送请求,只要任意QUORUM数量的节点有数据返回,Cassandran会返回时间戳记录最新的数据;(QUORUM = replication_factors / 2 + 1

    (3)ALL:客户端向3个(所有)节点都发送请求,必须所有节点返回数据,并且Cassandran会返回记录中具有最新时间戳的数据;

    综上所述,客户端在进行读写请求时,可以自定义指定读写的一致性级别,ONE级别为最低级别,效率高,一致性差,如过读写均为ONE,那么很大概率就会读写不一致。因此,只要保证下列条件,就能保证客户端视角的读写一致性:

    读请求节点 + 写请求节点 >= replication_factors

    即保证读写一致性级别均在QUORUM及以上即可,保证客户端视角的读写一致性

    利用Batch实现原子性

    Cassandra中批量写入的操作称为batch,通过batch操作可以将多个写请求合并为一个请求。这样有如下好处:

    • 把多次更新操作合并为一次请求,减少客户端和服务端的网络交互。
    • batch中同一个partition key的操作具有隔离性。
    • 默认的LOGGED类型可以保证batch中的所有操作要么(最终)全部成功,要么全部失败。也就是原子性
    Cassandra Batch的类型:
    • Logged Batch:Logged Batch是一种强一致性的写入操作,要么全部成功要么全部失败。如果Logged Batch中的一个请求失败,整个Batch都会失败,无法写入数据。
    • Unlogged Batch:Unlogged Batch是一种不保证强一致性的写入操作,可以部分成功部分失败,但是不会对整个Batch造成影响

    LOGGED 批处理用于确保不同分区(不同表或不同分区键)的原子性。 UNLOGGED 批处理用于确保单个分区批处理的原子性和隔离性。如果将 UNLOGGED 批处理用于多分区批处理原子性,将无法保证。默认为 LOGGED 批次。对于单个分区批处理,默认值为 UNLOGGED 。原因是将单个分区批处理视为单行突变。对于单行更新,无需使用 LOGGED 批处理。

  • 3
  • 1
  • 0
0 评论
0/1000
评论(0) 发表评论
吴****锜

吴****锜

1 篇文章 1 粉丝
关注

Cassandra数据库数据一致性控制

2024-03-28 09:35:25 14阅读

  • 时间戳来源

    参数:DefaultTimestamp

    // Sends a client side timestamp for all requests which overrides the timestamp at which it arrives at the server. (default: true, only enabled for protocol 3 and above)

    Cassandra的每一列都是分版本存储的,即插入一列新数据,Cassandra都要赋予其一个时间戳作为版本号,如果主键一致,那原来的数据并不删除,而是直接把新数据覆盖在旧数据上,并按时间戳排序;每次查询都会获取时间戳最大的那一个。

    1. 当DefaultTimeStamp = false:当有数据插入或者更新的时候,所带来的列时间戳根据request所访问的cassandra节点的ntp服务时间作为列时间戳,并同步到集群的其他节点中。
      • 此时若cassandra集群内的节点服务器时间不一致,可能导致多客户端对不同cassandra操作同一key的时候,产生一致性的问题。
    1. 当DefaultTimeStamp = true:以客户端的时间戳为准,覆盖其到达服务端的时间戳
      • 当多个客户端节点时间不一致时,且多个客户端同时对数据库中的同一key值进行更新操作时,可能会导致数据的乱序,从而导致数据库写入失败;

    解决方法:

    1. 使用NTP同步数据库节点和需要访问数据库的节点之间的时间;
    2. 如果是多客户端,客户端之间还要同步时间;
    3. 使用Consistency Level: QUORUM;

    可调控的读写一致性

    Cassandra 提供了可调节的一致性,允许我们选定需要的一致性水平与可用性水平,在二者间找到平衡点。因为客户端可以控制在更新到达多少个副本之前,必须阻塞系统。这是通过设置副本因子(replication factor)来调节与之相对的一致性级别。

    通过副本因子(replication factor),你可以决定准备牺牲多少性能来换取一致性。副本因子是你要求更新在集群中传播到的节点数(注意,更新包括所有增加、删除和更新操作)。

    客户端每次操作还必须设置一个一致性级别(consistency level)参数,这个参数决定了多少个副本写入成功才可以认定写操作是成功的,或者读取过程中读到多少个副本正确就可以认定是读成功的。

    调控参数:SetConsistency

    Cassandra中,强调的是“最终一致性”,即如果在一致性级别较低时,Cassandra只能保证存储数据的最终一致,可能在某个时刻,数据库中所有副本之间的数据并不一致

    客户端在发起请求(读or写)时,可以指定一致性级别(默认为ONE),简单分为ONE,QUORUM和ALL。以单数据中心为例,假设数据中心有3个节点,replication_factors为3(表示数据的副本数量,用户创建键空间时指定),那么写请求的在三种一致性级别下的情况分别是:

    (1)ONE:客户端向3个(所有)节点都发送写请求,但是只要有任意一个节点返回写成功,那么本次客户端的写请求就算成功;

    (2)QUORUM:客户端向3个(所有)节点都发送写请求,必须满足QUORUM数量的节点返回写成功,那么本次客户端的写请求就算成功;

    (3)ALL:客户端向3个(所有)节点都发送写请求,必须所有节点返回写成功,那么本次客户端的写请求才算成功;

    读请求在三种一致性级别下的请求分别是:

    (1)ONE:客户端向3个(所有)节点都发送读请求,只要任意一个节点返回数据记录,就直接返回该节点的记录;

    (2)QUORUM:客户端向3个(所有)节点都发送请求,只要任意QUORUM数量的节点有数据返回,Cassandran会返回时间戳记录最新的数据;(QUORUM = replication_factors / 2 + 1

    (3)ALL:客户端向3个(所有)节点都发送请求,必须所有节点返回数据,并且Cassandran会返回记录中具有最新时间戳的数据;

    综上所述,客户端在进行读写请求时,可以自定义指定读写的一致性级别,ONE级别为最低级别,效率高,一致性差,如过读写均为ONE,那么很大概率就会读写不一致。因此,只要保证下列条件,就能保证客户端视角的读写一致性:

    读请求节点 + 写请求节点 >= replication_factors

    即保证读写一致性级别均在QUORUM及以上即可,保证客户端视角的读写一致性

    利用Batch实现原子性

    Cassandra中批量写入的操作称为batch,通过batch操作可以将多个写请求合并为一个请求。这样有如下好处:

    • 把多次更新操作合并为一次请求,减少客户端和服务端的网络交互。
    • batch中同一个partition key的操作具有隔离性。
    • 默认的LOGGED类型可以保证batch中的所有操作要么(最终)全部成功,要么全部失败。也就是原子性
    Cassandra Batch的类型:
    • Logged Batch:Logged Batch是一种强一致性的写入操作,要么全部成功要么全部失败。如果Logged Batch中的一个请求失败,整个Batch都会失败,无法写入数据。
    • Unlogged Batch:Unlogged Batch是一种不保证强一致性的写入操作,可以部分成功部分失败,但是不会对整个Batch造成影响

    LOGGED 批处理用于确保不同分区(不同表或不同分区键)的原子性。 UNLOGGED 批处理用于确保单个分区批处理的原子性和隔离性。如果将 UNLOGGED 批处理用于多分区批处理原子性,将无法保证。默认为 LOGGED 批次。对于单个分区批处理,默认值为 UNLOGGED 。原因是将单个分区批处理视为单行突变。对于单行更新,无需使用 LOGGED 批处理。

文章来自专栏

cassandra

1 篇文章 1 订阅
0 评论
0/1000
评论(0) 发表评论
  • 3
    点赞
  • 1
    收藏
  • 0
    评论