Table Store:大量の構造化データのリアルタイムバックアップ実戦
データバックアップの概要
情報技術とデータ管理の分野では、バックアップとはファイルシステムやデータベースシステムのデータをコピーし、災害やエラー操作が発生すると、システムの有効なデータと正常な動作を便利かつタイムリーに回復することを意味します.実際のバックアップでは、重要なデータを3つ以上作成し、後で保存するために異なる場所に配置してバックアップすることが望ましい.
バックアップには2つの異なる目的があります.主な目的は、データが削除されても破損しても、データが失われた後にデータを復元することです.バックアップの2つ目の目的は、ユーザー定義のデータ保存ポリシーに基づいて、通常、バックアップ・アプリケーションでバックアップにどのくらいの時間がかかるデータ・コピーを構成するより早い時間からデータをリカバリすることです.
バックアップ・システムには、保存に値すると思われるすべてのデータのコピーが少なくとも1つ含まれるため、データ・ストレージに対する要求が高くなる可能性があります.このストレージ領域を組織し、バックアップ・プロセスを管理することは複雑なタスクである可能性があります.現在、バックアップに使用できるさまざまなタイプのデータストレージデバイスが多く、地理的冗長性、データセキュリティ、移植性を提供するために、さまざまな方法でこれらのデバイスを手配することもできます.
データを格納場所に送信する前に、それらを選択、抽出、操作します.現在、開いているファイル(open files)の処理やリアルタイムのデータソースの最適化、圧縮、暗号化、重複データの削除など、バックアッププロセスを最適化するためのさまざまな技術があります.各バックアップ・スキーマには、バックアップ中のデータの信頼性を検証するための演習プロセスが含まれます.さらに重要なのは、バックアップ・スキーマに関連する制限と人為的な要因を認識することです.
Table Storeバックアップ需要分析
ストレージシステムにとって、データの安全信頼性は常に第一位であり、データのできるだけ高い信頼性を保障するには、2つの面から保障する必要があります.
Table Storeバックアップ・リカバリ・スキームの概要
下図はTable Storeバックアップ・リカバリの論理構造図で、フルインクリメンタル一体のチャネル・サービスに基づいて、リアルタイムのインクリメンタル・バックアップ能力と秒レベルのリカバリ能力を備えたデータ・バックアップとデータ・リカバリ・スキームのセットを容易に構築できます.バックアップとリカバリの計画を事前に構成すれば、バックアップ・リカバリ・システム全体を完全に自動化できます.
Table Storeバックアップ復旧方案実戦
現在、表ストレージは公式のバックアップとリカバリ機能を発売していないが、筆者はstep-by-stepの表ストレージベースのチャネルサービス設計を独自のバックアップリカバリスキームにし、実戦ステップはバックアップとリカバリの2つの部分に分けられる.
1.バックアップ
バックアップ計画とポリシーの決定
バックアップ・ポリシーには、バックアップの内容、バックアップ時間、およびバックアップ方法を決定する必要があります.現在一般的なバックアップ・ポリシーには、主に次のようなものがあります.
今回の実戦では、バックアップ計画と戦略の選択は以下の通りである(ここでは、自分のニーズに合わせてカスタマイズし、チャネルサービスのSDKを利用してニーズを満たすことができる).
チャネルサービスSDKを使用したコード作成
この部分はコードクリップの形式に合わせて説明しますが、詳細なコードは後でオープンソースになります(リンクは本稿で更新されます)、楽しみにしてください.実戦を行う前に、チャネルサービスJava SDKの使用文書を読むことをお勧めします.
private static void createTunnel(TunnelClient client, String tunnelName) {
CreateTunnelRequest request = new CreateTunnelRequest(TableName, tunnelName, TunnelType.BaseAndStream);
CreateTunnelResponse resp = client.createTunnel(request);
System.out.println("RequestId: " + resp.getRequestId());
System.out.println("TunnelId: " + resp.getTunnelId());
}
変換部のコアコードは以下のコード断片を参照し、筆者がこの部分を処理するのはunivocity-parsers(CSV)とGsonライブラリであり、いくつかの点に特に注意しなければならない.Gson逆シーケンス化LongタイプはNumberタイプに変わり,進捗が失われる可能性があり,いくつかの解決策があり,筆者はそれをStringタイプシーケンス化に変えることを採用している.2). binaryタイプのデータの特殊な処理について,筆者はbase 64の符号化を行った.3). OSSに直接ストリーミングすることで、ローカル持続性の消費を削減できます.
this.gson = new GsonBuilder().registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64TypeAdapter())
.setLongSerializationPolicy(LongSerializationPolicy.STRING).create();
// ByteArrayOutputStream ByteArrayInputStream array.copy, NIO channel.
public void streamRecordsToOSS(List records, String bucketName, String filename, boolean isNewFile) {
if (records.size() == 0) {
LOG.info("No stream records, skip it!");
return;
}
try {
CsvWriterSettings settings = new CsvWriterSettings();
ByteArrayOutputStream out = new ByteArrayOutputStream();
CsvWriter writer = new CsvWriter(out, settings);
if (isNewFile) {
LOG.info("Write csv header, filename {}", filename);
List headers = Arrays.asList(RECORD_TIMESTAMP, RECORD_TYPE, PRIMARY_KEY, RECORD_COLUMNS);
writer.writeHeaders(headers);
System.out.println(writer.getRecordCount());
}
List totalRows = new ArrayList();
LOG.info("Write stream records, num: {}", records.size());
for (StreamRecord record : records) {
String timestamp = String.valueOf(record.getSequenceInfo().getTimestamp());
String recordType = record.getRecordType().name();
String primaryKey = gson.toJson(
TunnelPrimaryKeyColumn.genColumns(record.getPrimaryKey().getPrimaryKeyColumns()));
String columns = gson.toJson(TunnelRecordColumn.genColumns(record.getColumns()));
totalRows.add(new String[] {timestamp, recordType, primaryKey, columns});
}
writer.writeStringRowsAndClose(totalRows);
// write to oss file
ossClient.putObject(bucketName, filename, new ByteArrayInputStream(out.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
}
}
バックアップ・ポリシーの実行とバックアップ・プロセスの監視
public class TunnelBackup {
private final ConfigHelper config;
private final SyncClient syncClient;
private final CsvHelper csvHelper;
private final OSSClient ossClient;
public TunnelBackup(ConfigHelper config) {
this.config = config;
syncClient = new SyncClient(config.getEndpoint(), config.getAccessId(), config.getAccessKey(),
config.getInstanceName());
ossClient = new OSSClient(config.getOssEndpoint(), config.getAccessId(), config.getAccessKey());
csvHelper = new CsvHelper(syncClient, ossClient);
}
public void working() {
TunnelClient client = new TunnelClient(config.getEndpoint(), config.getAccessId(), config.getAccessKey(),
config.getInstanceName());
OtsReaderConfig readerConfig = new OtsReaderConfig();
TunnelWorkerConfig workerConfig = new TunnelWorkerConfig(
new OtsReaderProcessor(csvHelper, config.getOssBucket(), readerConfig));
TunnelWorker worker = new TunnelWorker(config.getTunnelId(), client, workerConfig);
try {
worker.connectAndWorking();
} catch (Exception e) {
e.printStackTrace();
worker.shutdown();
client.shutdown();
}
}
public static void main(String[] args) {
TunnelBackup tunnelBackup = new TunnelBackup(new ConfigHelper());
tunnelBackup.working();
}
}
ファイルリカバリの実行
データバックアップが完了すると、必要に応じてフル・リカバリと一部のデータ・リカバリを行い、RTOを削減できます.データをリカバリする際には、リカバリのパフォーマンスを最適化するためのいくつかの方法があります.
public class TunnelRestore {
private ConfigHelper config;
private final SyncClient syncClient;
private final CsvHelper csvHelper;
private final OSSClient ossClient;
public TunnelRestore(ConfigHelper config) {
this.config = config;
syncClient = new SyncClient(config.getEndpoint(), config.getAccessId(), config.getAccessKey(),
config.getInstanceName());
ossClient = new OSSClient(config.getOssEndpoint(), config.getAccessId(), config.getAccessKey());
csvHelper = new CsvHelper(syncClient, ossClient);
}
public void restore(String filename, String tableName) {
csvHelper.parseStreamRecordsFromCSV(filename, tableName);
}
public static void main(String[] args) {
TunnelRestore restore = new TunnelRestore(new ConfigHelper());
restore.restore("FullData-1551767131130.csv", "testRestore");
}
}
まとめ
本稿ではまずTable Storeバックアップの必要性を紹介し,次に表に格納されたチャネルサービスを用いたデータバックアップとリカバリの原理を紹介し,最後に実際のコードフラグメントと結びつけてTabel Storeデータバックアップリカバリスキームの構築方法について述べた.
リファレンスリンク
作者:琸然
原文を読む
本文は雲栖コミュニティのオリジナル内容で、許可を得ずに転載してはならない.