之前比较关注如何使用Cassandra,但是真正想大规模使用前提还是需要搞清楚备份机制,确保数据安全。

本文主要内容来自文档 "Cassandra2.2"的翻译。最后部分为真实操作案例。

这里假设你已经了解了Cassandra的压缩、墓碑、数据一致性。

原始文档链接:http://docs.datastax.com/en/cassandra/2.2/cassandra/operations/opsBackupRestore.html

备份和数据恢复

关于镜像

Cassandra 通过直接保存所有在data目录中的磁盘数据文件(SSTable file)的镜像来备份数据。当系统还在线的时候,你可以保存所有的keyspace数据或者单个keyspace数据,或者某一张表的数据。

使用并行的ssh工具,比如pssh,你可以给整个集群做镜像。这提供一种最终一致性备份。虽然没有一个节点可以在镜像制作过程中保证他和备份节点数据的一致性,Cassandra内置一致性机制会使用一个恢复镜像恢复一致性。

当整个系统范围内的镜像都已经完成,你可以开启每个节点的增量备份,它将备份那些最后一次镜像后有改变的数据:每次SSTable 刷新,一个硬链接被复制到 data目录的/backups 子目录中(provided JNA is enabled)

如果允许JNA,镜像将只是建立一个硬链接。否则io将由于文件被从一个地方拷贝到另一处而增长,将明显降低效率。

如何得到一份镜像

通过 nodetool snapshot指令来获取每个节点的镜像。如果要获取全局的镜像,使用并行ssh工具运行这个指令,比如pssh。

镜像首先将所有内存数据刷新到磁盘中,然后给keyspace中的每个SSTable创建硬链接。你需要在每个节点上有足够的空间来容纳生成的镜像文件。单一镜像需要很小的空间。然而镜像会导致你的磁盘使用量随时间快速增长,因为镜像需要留着那些被删除的过期数据。当镜像制作完成。如果你需要的话,你可以将备份文件移动到其他位置,或者就放在那。

注意:Cassandra只能在table schema存在的情况下恢复数据,所以建议你同样备份一下schema(也就是system.schema_*系列的表).

操作过程

运行nodetool snapshot指令,需要指定hostname,JMX端口,keyspace名称。比如:

 $ nodetool -h localhost -p 7199 snapshot mykeyspace

结果

snapshot被创建在(原文)目录中,每个s镜像都包含多个包含镜像当时数据的.db文件。

镜像的路径可能是:

使用安装包:/var/lib/cassandra/data/mykeyspace/users-081a1500136111e482d09318a3b15cc2/snapshots/1406227071618/mykeyspace-users-ka-1-Data.db

使用tar包: install_location/data/data/mykeyspace/users-081a1500136111e482d09318a3b15cc2/snapshots/1406227071618/mykeyspace-users-ka-1-Data.db

增量备份

当增量备份被开启(默认关闭),Cassandra 将硬链接每个刷新过的(flushed)的在keyspace数据目录中的SStable到备份目录中。这允许保存备份的偏移量而不是整个镜像。同时,增量备份将和镜像一起提供可靠的最新的备份机制。

和镜像一样,Cassandra 并不会自动清理增量备份文件。DataStax建议配置一个程序在新的镜像生成后,清理增量备份文件。

操作过程

编辑cassandra.yaml 配置文件,将incremental_backups 设置为true,你需要在每个节点都进行此操作

从镜像中恢复

从镜像中还原keyspace需要所有的table的镜像文件,如果使用增量备份,任何在镜像后创建的增量备份文件都是必须的。

正常来说,在从镜像还原之前,你需要清空(truncate)table. 如果备份发生在删除之前,而你在删除后还原数据没有先清空,你无法得到原始的数据(行)。在压缩后,墓碑存档在和原始数据不同的SSTable中,所以当还原包含着原始数据的SSTable但是没有移除墓碑,数据依旧表现出被删除状态(虽然它还在那)。

Cassandra 仅能再table schema存在的情况下备份镜像。如果你没有备份schema,你可以做下面的任何一种工作。

方法1:

  1. 还原镜像,按照下面的方法
  2. 重新创建schema

方法2 :

  1. 重建schema
  2. 还原镜像
  3. 执行nodetool refresh

你有很多方法可以还原数据:

  1. 使用sstableloader 工具
  2. 拷贝镜像的SSTable文件到/data/keyspace/table_name-uuid目录中,然后用JConsole 在各个column family 中调用JMX方法loadNewSSTables()在column family MBean,你可以使用nodetool refresh 代替调用loadNewSSTables()

    data目录位置依赖于你的安装或者配置方式,默认是下面两种。

    1. Package installations: /var/lib/cassandra/data
    2. Tarball installations: install_location/data/data
  3. 使用Node Restart Method 下面将会介绍。

如果还原一个节点,你需要首先关闭节点。如果还原整个集群,你需要关闭所有节点,还原镜像数据,然后再次启动所有节点。

注意:还原镜像数据将导致正在还原的节点,CPU和IO临时增加。

译者注:这边可能文档没有更新完整,前面有提到需要truncate table,在关闭节点前先执行一次。

  1. 关闭节点
  2. 清理所有commitlog中的文件

这是为了防止commitlog重放导致数据更新,这可能导致还原到某个固定时间点的目标失败。

  1. 清理有*.db文件在data_directory/keyspace_name/keyspace_name-keyspace_name目录中,但是不要删除镜像和备份子目录。
  2. 确定最近的镜像数据目录
  3. 将数据拷贝内容到这个目录

data_directory/keyspace_name/talbe_name-UUID

  1. 如果你采用了增量备份,复制这里的所有数据

data_driectory/keyspace_name/table_name-UUID/backups

  1. 粘贴到

data_directory/keyspace_name/table_name-UUID中

  1. 重启节点

这会导致暂时性的io增长和占有大量CPU资源。

  1. 执行nodetool repair

实际操作记录 (Node Restart Method)

集群简介

4个节点,分别为

192.168.1.2

192.168.1.3

192.168.1.4

192.168.1.5

之后就不写完整ip 用节点2 节点3 节点4 节点5

Cassandra 版本2.1.7

创建备份测试用的数据

登录负载最低的节点2,创建一个keyspace

/* 创建tshop的keyspace */
CREATE KEYSPACE tshop WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '2'} ;
use tshop; /* 创建一张user表 */ CREATE TABLE user (
uid int PRIMARY KEY,
group_id int,
nick varchar
) WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy'}; /* 写入一些数据 */
insert into user (uid,group_id,nick) values(1,1,'kevin');
insert into user (uid,group_id,nick) values(2,1,'luxi');
insert into user (uid,group_id,nick) values(3,1,'happy');
insert into user (uid,group_id,nick) values(4,1,'豆沙柚子');
insert into user (uid,group_id,nick) values(5,1,'五仁月饼');

备份所有节点数据:

$ bin/nodetool -h 192.168.1.2 snapshot tshop
$ bin/nodetool -h 192.168.1.3 snapshot tshop
$ bin/nodetool -h 192.168.1.4 snapshot tshop
$ bin/nodetool -h 192.168.1.5 snapshot tshop

备份完成后会显示一个时间邮戳,这就是备份目录的名字,也方便还原时判定备份的时间。

/* 删除数据,假设是一次意外事故 */
delete from user where uid in (1,2,3,4,5);

关闭来自前端的请求,因为数据恢复的过程中,集群不得不关闭。

清空user表,前面有提到原因。

>truncate user;

关闭集群的所有节点

清理commitlog 避免有未提交数据的破坏

把数据目录下的*.db文件删除

把备份目录中的*.db文件放到数据目录中

重启所有节点

在每个节点上执行nodetool repair

$ bin/nodetool -h 192.168.1.2 repair tshop
$ bin/nodetool -h 192.168.1.3 repair tshop
$ bin/nodetool -h 192.168.1.4 repair tshop
$ bin/nodetool -h 192.168.1.5 repair tshop

结果

之前丢失的user数据全部还原成功

实际操作案例(增量备份)

增量备份的数据体积更小,但是备份时间似乎不好控制,先试一下。

首先基于上面一个案例,开启增量备份。

如果有安装OpsCenter 就直接改,否则需要到每个节点上去开启这个配置。

incremental_backups: true

继续往数据库写入数据

insert into user (uid,group_id,nick) values(6,1,'昵称1');
insert into user (uid,group_id,nick) values(7,1,'昵称2');
insert into user (uid,group_id,nick) values(8,1,'昵称3');
insert into user (uid,group_id,nick) values(9,1,'昵称4');
insert into user (uid,group_id,nick) values(10,1,'昵称5');
insert into user (uid,group_id,nick) values(11,1,'昵称6');
insert into user (uid,group_id,nick) values(12,1,'昵称7');
/* 如果有新数据写入,执行flush操作,可以让增量备份作一次备份,但是这并不是总是有效果,有可能当时没有写入数据,不过也意味着距离上次备份不需要再备份新的数据了 */
$ bin/nodetool -h 192.168.1.2 flush tshop
$ bin/nodetool -h 192.168.1.3 flush tshop
$ bin/nodetool -h 192.168.1.4 flush tshop
$ bin/nodetool -h 192.168.1.5 flush tshop

这时候,目录中多了一个backup的目录。

/* 再一次 删除数据,假设是一次意外事故 */
delete from user where uid in (3,4,5,6,7);

我观察了一下backup目录文件,会有多组文件,所谓多组就是这些文件名可能非常相似,只有中间一个数字差别.

$ ls backup

-rw-rw-r-- 1 cassandra cassandra   43 Sep  3 18:39 tshop-user-ka-2-CompressionInfo.db
-rw-rw-r-- 1 cassandra cassandra 138 Sep 3 18:39 tshop-user-ka-2-Data.db
-rw-rw-r-- 1 cassandra cassandra 9 Sep 3 18:39 tshop-user-ka-2-Digest.sha1
-rw-rw-r-- 1 cassandra cassandra 16 Sep 3 18:39 tshop-user-ka-2-Filter.db
-rw-rw-r-- 1 cassandra cassandra 54 Sep 3 18:39 tshop-user-ka-2-Index.db
-rw-rw-r-- 1 cassandra cassandra 4442 Sep 3 18:39 tshop-user-ka-2-Statistics.db
-rw-rw-r-- 1 cassandra cassandra 80 Sep 3 18:39 tshop-user-ka-2-Summary.db
-rw-rw-r-- 1 cassandra cassandra 91 Sep 3 18:39 tshop-user-ka-2-TOC.txt -rw-rw-r-- 1 cassandra cassandra 43 Sep 3 18:44 tshop-user-ka-4-CompressionInfo.db
-rw-rw-r-- 1 cassandra cassandra 138 Sep 3 18:44 tshop-user-ka-4-Data.db
-rw-rw-r-- 1 cassandra cassandra 9 Sep 3 18:44 tshop-user-ka-4-Digest.sha1
-rw-rw-r-- 1 cassandra cassandra 16 Sep 3 18:44 tshop-user-ka-4-Filter.db
-rw-rw-r-- 1 cassandra cassandra 54 Sep 3 18:44 tshop-user-ka-4-Index.db
-rw-rw-r-- 1 cassandra cassandra 4442 Sep 3 18:44 tshop-user-ka-4-Statistics.db
-rw-rw-r-- 1 cassandra cassandra 80 Sep 3 18:44 tshop-user-ka-4-Summary.db
-rw-rw-r-- 1 cassandra cassandra 91 Sep 3 18:44 tshop-user-ka-4-TOC.txt

显然有 “2” 组 和 “4” 组,时间一前一后,如果想恢复到18:39分,那么,就别吧“4”组的数据放到数据目录中。这个数字的变化我暂时没有找到一个解释,是不是随着flush操作次数增加而增大?(测试结果是这样的)但是还原操作后,这个数字似乎会回到一个比较小的值。所以用数字判断数据前后应该不靠谱,文件生成时间会靠谱一些,但是反复还原操作后,备份也会混乱。

周期性镜像备份还是不可替代,增量备份可以作为一种粒度更小的时间控制的补充。例如每天一个镜像,最后一个镜像后,开始保留增量。保留最新增量的方法就是在镜像制作完成后,删除所有当前增量备份,这样就是最新了,但是这两个操作间的数据又怎么办?

其他操作和之前镜像还原完全相同。

结果

数据全部还原

Cassandra 备份 - 1 - 节点镜像恢复的更多相关文章

  1. Oracle 无备份情况下的恢复--控制文件/数据文件

    13.3无备份恢复控制文件 没有备份恢复控制文件其实就是在nomount状态,create control创建一个新的控制文件. dba必须知道4个信息才能正确的创建:数据库名.在线日志路径及其大小. ...

  2. 使用rman备份将rac环境恢复到单实例

    使用rman备份将rac环境恢复到单实例 rac环境 [oracle@rac02 ~]$ cat /etc/hosts 127.0.0.1 localhost localhost.localdomai ...

  3. [20171225]没有备份数据文件的恢复.txt

    [20171225]没有备份数据文件的恢复.txt --//别人问的问题,增加了数据文件没有备份,如何恢复,实际上很简单,因为当前控制文件有记录建立时间只要从建立数据文件开始的--//归档日志都存在恢 ...

  4. 数据迁移_把RAC环境备份的数据,恢复到另一台单机Oracle本地文件系统下

    数据迁移_把RAC环境备份的数据,恢复到另一台单机Oracle本地文件系统下 作者:Eric 微信:loveoracle11g 1.创建pfile文件 # su - ora11g # cd $ORAC ...

  5. Gitlab备份、迁移、恢复和升级

    Gitlab备份.迁移.恢复和升级 自建的Gitlab服务器常常会因为使用时间的增长,其空间容量等硬件需求都需要升级,或者迁移至更高配置的服务器上.备份.迁移.恢复.升级过程如下 1.gitlab备份 ...

  6. surface 通过U盘 镜像恢复系统

    1. 在恢复之前首先要解锁bitlocker(如果你的surface没有加锁就不需要这个步骤) 在另一台电脑上登录bitlocker锁绑定的微软账号,查询密钥,在需要的地方输入这个密钥(不经过这个操作 ...

  7. 制作ACK集群自定义节点镜像的正确姿势

    随着云原生时代的到来,用户应用.业务上云的需求也越来越多,不同的业务场景对容器平台的需求也不尽相同,其中一个非常重要的需求就是使用自定义镜像创建ACK集群. ACK支持用户使用自定义镜像创建Kuber ...

  8. hadoop主节点(NameNode)备份策略以、恢复方法、操作步骤

    一.dits和fsimage      首先要提到两个文件edits和fsimage,下面来说说他们是做什么的. 集群中的名称节点(NameNode)会把文件系统的变化以追加保存到日志文件edits中 ...

  9. MongoDB副本集--Secondary节点实例恢复

    场景描述 MongoDB副本集中有一台Secondary节点出现RECOVERING的状态 状态如下: arps:RECOVERING> rs.status() { "set" ...

随机推荐

  1. .NET连接池的配置 【转】

    ADO.Net 在数据库操作过程中默认打开了连接池,不需要再进行手工配置.这个特性可以使数据库操作时效率提高,但也要有相应的代码配合,才能真正提高程序效率. 1.连接字符串 ADO.Net 中的连接池 ...

  2. POJ 2135 Farm Tour [最小费用最大流]

    题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很 ...

  3. 避免多层回调,Node.js异步库Async使用(series)

    未使用Async之前coffeescript写的代码: exports.product_file_add = (req,res) -> if !req.param('file_id') retu ...

  4. chinapay

    http://s.yanghao.org/program/viewdetail.php?i=71959 http://www.codeproject.com/csharp/biginteger.asp ...

  5. PHP 文件读取 fread、fgets、fgetc、file_get_contents 与 file 函数

    fread().fgets().fgetc().file_get_contents() 与 file() 函数用于从文件中读取内容. fread() fread() 函数用于读取文件(可安全用于二进制 ...

  6. ASP.NET MVC 之 View 测试

    项目又出问题了!手贱了一下,使用某个工具整理了一下 View 中的内容,不经意之间,将 View 的输出中大小写不小心搞错了,导致输出的内容没有办法正常解析. 这种问题太隐蔽了,下次再遇到怎么办呢? ...

  7. 翻译:Knockout 快速上手 - 5: 你需要知道的顶级特性 续

    Utilities Knockout 提供了许多可以你开发中使用的工具,你可以在 ko.utils 命名空间中找到它们,我最喜欢的工具如下所示: extend: 这个方法将两个对象合并在一起,调用这个 ...

  8. 实时阴影渲染(一):PSSM平行分割阴影图

    PSSM(Parallel Split Shadow Map)平行分割阴影图,是一种根据距离远近采用多个深度纹理渲染阴影的方法 适合用于室外大场景中的平行光比如太阳形成的阴影 本系列需要读者了解基本的 ...

  9. 用C#编写游戏脚本

    大学宿舍玩游戏的时候,为了简化重复的键鼠动作,有学习过按键精灵和TC脚本开发工具,并做了一些小脚本,基本达到了当时的需求.不知不觉,已经毕业了3年了,无聊之余又玩起了游戏,对于一些无趣的重复行为,于是 ...

  10. 统计Crash工具—Crashlytics

    官网:https://www.crashlytics.com/login 步骤: 注意:有时候再次运行,或者换了Crashlytics账号之后,获取不到Crash信息,其实你需要把plist文件里的K ...