java ClockRepair_cassandra日常维护之nodetool repair

前提

cassandra的根据分区key的操作是很快的,这也是它的优势,但是它的多条件查询是很弱的,特别是如果你有删除操作的话,就更坑爹了。cassandra的删除操作,实际上并不是真的删除,它是执行的插入操作,插入的数据叫做tombstone(墓碑),记录了被删除记录的信息和删除时间。当你根据条件查询的时候,如果它会把满足条件的记录查询出来,包括tombstone。然后过滤掉删除的记录,再把结果返回给你。

现象

如果你的表mykeyspace.t_table有3个副本,主键是(a,b,c) 。你插入4000条数据(a=1),然后再删除掉3999条,你再根据a=1去查询,你会在cassandra的日志中发现一条警告日志.

WARN [ReadStage:18926] 2015-02-05 07:18:02,869 SliceQueryFilter.java Read 1 live and 11997 tombstoned cells in mykeyspace.t_table (see tombstone_warn_threshold)....

这个警告信息是根据你的cassandra.yaml里配置的tombstone_warn_threshold决定的。也就是说它搜索了11997=3999*3条数据,才搜到一个1个live。这就是墓碑的危害。当你删除的数据更多的时候。到达配置项tombstone_failure_threshold的值,这次查询就失败了。你会看到下面的ERROR日志。

ERROR [ReadStage:219774] 2015-02-04 00:31:55,713 SliceQueryFilter.java (line 200) Scanned over 100000 tombstones in mykeyspace.t_table; query aborted (see tombstone_fail_threshold)

ERROR [ReadStage:219774] 2015-02-04 00:31:55,713 CassandraDaemon.java (line 199) Exception in thread Thread[ReadStage:219774,5,main]

java.lang.RuntimeException: org.apache.cassandra.db.filter.TombstoneOverwhelmingException

at org.apache.cassandra.service.StorageProxy$DroppableRunnable.run(StorageProxy.java:1916)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:745)

Caused by: org.apache.cassandra.db.filter.TombstoneOverwhelmingException

at org.apache.cassandra.db.filter.SliceQueryFilter.collectReducedColumns(SliceQueryFilter.java:202)

真实的数据实实在在的被删除,发生在两个时期:

第一个时期是新的SSTable文件生成的时候。而且它只删除gc_grace_seconds之前插入的tombstone。

gc_grace_seconds是表结构的一个额外参数,可以通过alter table进行修改。所以说如果你的某个节点挂了,挂的时间超过gc_grace_seconds。可能导致删除的数据又出现了。

第二个时期就来自日常的Nodetool repair操作。每个gc_grace_seconds周期内至少repair一遍。

解决

普通repair

nodetool repair基本语法是这样的:

nodetool -h host repair [keyspace] [cfnames]

它会修复keyspace.cfnames这个表分区主键token值落在这个节点上的数据(包括master和slave数据)。等你把所有的节点repair一遍,

如果你有三个副本,你相当于repair了三遍数据,所以这个时间会很长。

只repair master数据

你可以使用-pr选项,表示只修复range落在该节点的master数据:当然你需要把所有的节点都repair一遍。

nodetool -h host -pr repair [keyspace] [cfnames]

根据token段repair

当你的数据量足够大的时候,这个过程还是很慢,你可能焦急的不知道这个过程什么时候结束。你可以通过token段的方式,

nodetool -h host -st xxx -et xxxx repair [keyspace] [cfnames]

至于token段的获取,可以使用nodetool ring命令得到。

Note: Ownership information does not include topology; for complete information, specify a keyspace

Datacenter: datacenter1

==========

Address Rack Status State Load Owns Token

9192997390010868737

192.168.1.101 rack1 Up Normal 98.1 MB 35.79% -9196740398802827883

192.168.1.102 rack1 Up Normal 98.55 MB 30.03% -9124289757510820389

192.168.1.103 rack1 Up Normal 98.09 MB 34.18% -9088595326201594476

192.168.1.102 rack1 Up Normal 98.55 MB 30.03% -9084487345633494070

192.168.1.101 rack1 Up Normal 98.1 MB 35.79% -9061596030643872312

192.168.1.102 rack1 Up Normal 98.55 MB 30.03% -9056941391849010003

192.168.1.101 rack1 Up Normal 98.1 MB 35.79% -9055818090063560183

这就表示token 从-9088595326201594476到-9084487345633494070的master数据分布在192.168.1.102机器上。

多线程并发repair。

可以加一个-par选项 例如:

nodetool -h host -pr -par repair [keyspace] [cfnames]

nodetool -h host -st xxx -et xxxx -par repair [keyspace] [cfnames]

这个repair速度会提高数倍。但是你要考虑你集群的负载。

增量repair

可以加一个-inc选项(注:这个选项只能在2.1以后的版本使用)

例如

每条数据都有自己的时间戳,当你repair一次之后,你第二次repair的时候,其实只要repair上次repair数据最后一个时间戳之后的数据就可以了。

nodetool -h host -pr -inc repair [keyspace] [cfnames]

nodetool -h host -st xxx -et xxxx -inc repair [keyspace] [cfnames]

这样也可以增加repair速度,注意-inc和-par是不能一起使用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值