@xtccc
2016-04-03T09:20:25.000000Z
字数 6543
阅读 4053
Cassandra
参考链接:
目录
启动
在每一个Cassandra的节点上,进入安装目录,通过以下命令启动该节点上的Cassandra:
$ bin/cassandra
这是在前台启动Cassandra的命令,如果想在后台启动,可以为该命令加上一个参数-f
:
$ bin/cassandra -f
停止
$ kill [pid]
以上是针对Apache Cassandra的操作,如果使用的是DSE(DataStax Enterprise):
启动
$ bin/dse cassandra
停止
$ bin/dse cassandra-stop
参考 Repairing nodes , Advanced repair techniques
应该安排定期的Repair工作(如每周一次)。Repair可以自动触发,也可以手动触发。如果目标表很少写入删除或者重写数据,那么repair的间隔可以适当拉长一些。
自动触发
在创建表时,可以加上参数 gc_grace_seconds,也可以通过"desc "来查看它的默认值(10天)。每间隔这么长时间,该table就会自动触发一次repair。
手动触发
通过 nodetool utility 来进行。只需在一个DSE节点上执行该命令,修复过程会针对整个Cassandra集群。
参考 Add / Remove nodes, data centers, clusters
参考 Backing up and restoring data, Cassandra and Backups, Backuping Up Cassandra Data
Cassandra通过为某节点上数据目录中的所有数据文件(SSTables)创建snapshot的方式来为该节点实现数据备份。 当系统在线上运行时,我们也可以为all keyspaces、a single keyspace或者a single table创建snapshot。
以上说的是基于snapshot的数据备份与恢复,如果想实现基于外部存储系统(如s3)的数据备份与恢复,请参考 Netflix Priam 。
只有当table schema存在时,Cassandra才能从snapshot中恢复数据,所以推荐对table schema也进行备份。
问题:数据备份与恢复,是在一个节点上进行就可以了?还是要在集群的每个节点上进行才行?
生成快照文件的命令"bin/nodetool snapshot",是一个只作用于本节点的命令,这意味着它只能为本节点上的数据生成snapshot,而不是整个集群中的数据,所以它只能为备份集群中的一部分数据。
如果想要进行全局备份,则需要在集群的每一个节点上运行"nodetool snapshot",并且是在同一个时间点进行。
通过并行的ssh工具(例如pssh),我们可以为整个集群创建快照,这样就能为被备份的数据实现eventually consistency。
备份Schema
通过cqlsh命令,可以将某个keyspace或者全部keyspaces的Schema导出到外部的文件中进行备份。
备份指定keyspace的schema:
$ bin/cqlsh [hostname/ip] -e "DESC KEYSPACE <keyspace_name>" > schema.cql
备份全部keyspaces的schema:
$ bin/cqlsh [hostname/ip] -e "DESC SCHEMA" > schema.cql
导入Schema
$ bin/cqlsh [hostname/ip]
source <path_to_schema_file.cql>
为keyspace创建single node snapshot
$ bin/nodetool -h localhost -p [JMX_port] snapshot [keyspace_name]
其中,JMS_port默认是7199。
执行这个命令,只会在本机生成snapshot文件,路径为
<data_dir>/<keyspace_name>/<table_name>/snapshots/<snapshot_name>
例如,我为xt_space.persons这个表创建的snapshot文件的路径是 /disk2/dse/dse-4.8/data/xt_space/persons-74e37771f0fb11e599dcf113c567d78c/snapshots/1458891272166
,该目录里面的结构为:
-rw-r--r-- 1 root root 44 Mar 25 15:34 manifest.json
-rw-r--r-- 2 root root 43 Mar 23 22:13 xt_space-persons-ka-1-CompressionInfo.db
-rw-r--r-- 2 root root 76 Mar 23 22:13 xt_space-persons-ka-1-Data.db
-rw-r--r-- 2 root root 10 Mar 23 22:13 xt_space-persons-ka-1-Digest.sha1
-rw-r--r-- 2 root root 16 Mar 23 22:13 xt_space-persons-ka-1-Filter.db
-rw-r--r-- 2 root root 21 Mar 23 22:13 xt_space-persons-ka-1-Index.db
-rw-r--r-- 2 root root 4434 Mar 23 22:13 xt_space-persons-ka-1-Statistics.db
-rw-r--r-- 2 root root 101 Mar 23 22:13 xt_space-persons-ka-1-Summary.db
-rw-r--r-- 2 root root 91 Mar 23 22:13 xt_space-persons-ka-1-TOC.txt
如果使用参数"-t"参数,则可以指定生成的snapshot文件的目录名。否则,目录名是带有时间戳的。
为table创建singe node snapshot
用参数"-cf",可以指定只为某一个table创建snapshot,用法为:
$ bin/nodetool snapshot \
-t <snapshot_dir_name> \
-cf <table_name> \
<keyspace_name>
例如,要为表"xt_space.persons"生成snapshot文件,并将其放入到目录"snapshots/xt_space_persons"中,则可以使用如下的命令:
$ bin/nodetool snapshot \
-t xt_space_persons \
-cf persons \
xt_space
经测试发现,执行"snapshot"命令后,不仅会生成"snapshots"目录,还会生成"backups"目录。这是因为:该节点的cassandra.yaml文件中将incremental_backup设为true,如果没有设置,则不会生成"backups"目录。
创建全局snapshot
以上命令都是创建单点的snapshot,即"bin/nodetool snapshot"只能为其运行所在的主机生成snapshot,而不能为集群创建全局的snapshot。
备份前必须进行flush
如果要为keyspace或者table生成snapshot,那么必须保证数据都在SSTable中,那些存在于commit log或者memtable中的数据不会被备份至snapshot文件(通过flush操作可以将其放入SSTable中)。因为,生成snapshot的操作其实也就是对SSTable进行一次文件复制。
实际上,通过nodetool工具进行备份时,它自己会先进行flush。
备份至s3
除了将数据备份在本地外,还可以将数据备份到s3。
删除snapshot
过去创建的snapshot目录并不会被自动删除,如果不再需要的话,应该删除旧的snapshot文件:
$ bin/nodetool -h localhost -p [JMX_port] clearsnapshot
这只会删除localhost的全部snapshot文件,如果想删除全部节点上的snapshot文件,应该使用 parallel ssh 工具来运行 nodetool clearsnapshot 命令。
增量备份
在为整个系统创建了snapshot之后,我们可以为每一个节点进行incremental backup —— 每当数据被flush到一个SSTable后,它的hard link被复制到数据目录的backups子目录中(假设JNA可用,否则,文件数据会被真正复制)。
Incremental backups这个功能默认是diasbled,如果enabled,Cassandra会将flushed SSTabels硬链接到数据目录的backups目录下。也就是说,如果开启了该功能,每当Memtable被flush到SSTables时(无论是因为memtable数据满了而触发flush,还是手动触发flush),被flush的SSTable文件会出现在backups目录下。
将cassandra.yaml文件中的incremental_backups设置为true可以enable incremental backups。这是开启增量备份的唯一方法,不存在触发增量备份的命令。注意:这些设置只会对目标节点起作用,而不是对整个集群都起作用。
Incremental backup是依赖于/基于snapshot的,必须与snapshot结合使用。当完成了一次snapshot后,可以定期地进行incremental backup;怎样恢复数据呢?请看下一小节。
从snapshot恢复某个keyspace时需要用到全部的snapshot files。如果使用了incremental backup,则需要用到snapshot之后创建的全部incremental backup files。
一般来说,在从snapshot恢复数据之前,需要首先对table执行truncate。
如果delete发生在backup之后并在restore之前,那么restore完成后我们无法得到原来的数据。因为delete数据时,目标数据只是被打上了标记,tombstone仍然存在于其他的SSTables中而不会被删除,直到compaction的发生。这样,当从原始数据的SSTable恢复数据时,这些tombstone标记仍然存在,原始的数据看起来就处于被删除的状态。
truncate则会立即将表中的数据真正不可逆地清空。
从snapshot文件恢复Cassandra数据可以有多种不同的途径:
在恢复一个节点的数据之前,需要防止该节点仍然在接收数据,特别是待恢复的目标表应该停止接收数据(包括来自客户端的数据和其他节点的数据),我们可以用命令 "bin/nodetool drain" 来实现这一点。
该命令执行后,目标节点会将Memtables flush到SSTables,然后该节点将停止监听来自客户端和其他节点的连接。因此,后期还需要重启该节点上的Cassandra服务。
方法1: 使用sstableloader
sstableloader除了可以从snapshot文件恢复Cassandra数据外,还可以实现: a) 将外部数据批量导入到集群中;b) 将已有的SSTables导入到另外一个集群(该集群可以有不同的node number / replication strategy)。
在使用sstableloader从snapshot文件恢复Cassandra数据时,sstableloader并不是简单地将全部SSTables复制到集群的每一个节点上,而是将相应的数据传输到对应的节点上,使数据与集群的replication strategy保持一致,而且目标table也不要求是空表。
在开始导入数据之前,必须先定义目标表的schema。
为了最大化导入数据时的吞吐量,我们可以运行多个sstableloader实例,将数据导向多个节点。究竟怎样做?
在使用sstableloader导入数据前,snapshot文件/sstables所在的目录形式为"keyspace_name/table_name",例如,如果要把sstables导入到表"xt_space.persons"中,则这些文件要放在目录"xt_space/persons"中。
导入sstables的命令:
$ bin/sstableloader \
-d <initial_hosts> \
-f <path_to_cassandra.yaml> \
<path_to_sstable_files>
方法2: 直接复制snapshots文件
首先,停掉目标节点上的Cassandra服务。
接着,清除目标节点上目标表的数据目录("data_file_directories"),并清除commit log目录("commitlog_directory"),然后将snapshot目录中的所有文件直接复制到目标表的数据目录。
最后,在目标节点上执行命令"bin/nodetool refresh",这样可以不必重启Cassandra服务。
如果有多个节点需要恢复数据,在每个节点重复以上步骤,都完成后执行命令 "bin/nodetool repair" 以使得集群的数据恢复一致性。
方法2相比方法1存在局限:
The tokens for the cluster you are restoring must match exactly the tokens of the backed-up cluster at the time of the snapshot. Furthermore, the snapshot must be copied to the correct node with matching tokens matching. If the tokens do not match, or the number of nodes do not match, use the sstableloader procedure.
参考 Cassandra Backup and Recovery - OpsCenter
一般来说,写入新数据的会被写入Memtable内存结构和CommitLog文件中,只有等到Memtable的数据达到了阈值后,Cassandra才会将Memtable写入(flush)到磁盘上的SSTable文件(位于Cassandra配置的数据文件中)。
我们也可以通过JMX手动地触发flush(例如通过命令 "bin/nodetool flush"),让Memtable立即被flush到SStabel中。如果在某个节点上触发flush,那么只有这个节点上的Memtable会被写入到该节点的SSTable中,其他的节点并不受影响。