kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Amazon Aurora を知らなかった人が 2018/12 現在の Aurora の最新状況を分かる範囲でまとめた

主にMySQLについて調査

Amazon Aurora って何?

MySQL/PostgreSQL 互換のリレーショナル・データベース

サポートしているエンジンは?

  • MySQL 5.7
  • MySQL 5.6
  • PostgreSQL 9.6

RDSと何が違うの?

  • 高パフォーマンス
  • スケーラブル
  • 低運用コスト(人もお金も)
  • 耐障害性

高パフォーマンス

標準的なMySQLより5倍、PostgreSQLより3倍早い

  • ストレージノードでのクエリの並列化
  • レプリケーション時にslaveに書き込み負荷がかからない
    • ストレージは個別に更新されて、slaveがやるのはログの位置情報の更新とキャッシュクリアだけ
  • AWSに最適化されたチューニング

スケーラブル

低運用コスト

DBの専門家でなくても運用しやすい

  • 各種パラメータはすでに最適化済
  • Performance Insights で、ボトルネックや問題を専門家でなくても発見可能に
  • 自動フェイルオーバー
  • zero-downtime-patching(ZDP)
    • データベースエンジンの更新時にダウンタイムが発生しない(すごい!)

耐障害性

  • インスタンスの自動修復
  • 3つのAZにそれぞれ2つのリードレプリカが作られる

その他便利な機能

  • backtrack : DBのデータを巻き戻すことが可能
  • database clone: データの複製が一瞬で行われる(参照元はwriteされるまで同じ
  • IAM権限でログイン可能(高負荷アプリケーションの接続には向かないらしい
  • lambdaを実行可能(!)
    • mysql.lambda_async というストアドプロシージャからlambdaを呼べる
  • S3への自動バックアップ
  • Performance Insights
    • 専門家でなくてもクエリパフォーマンスの評価やDBの状態を把握可能に
  • Parallel Query
    • 1つのSQLを複数のストレージノードとCPUで並列実行して高速化する
    • いろいろ制限もある
  • Aurora Serverless
    • インスタンスタイプの指定が不要 & オートスケール
    • アクセスが一定時間発生しないと休眠する
    • 開発環境や、低頻度アクセスのDB、社内システムなど向け?
    • 機能に制限がある 👉 see: Amazon Aurora サーバーレスの使用 - Amazon Aurora

知っておくべき用語

  • パラメータグループ
  • エンドポイント

パラメータグループ

Auroraでは、エンジン(MySQLとか)のパラメータを パラメータグループ という単位で設定する

パラメータグループは、 DB クラスターパラメータDB インスタンスパラメータ に分かれる

  • DB クラスターパラメータ : クラスタ全体に適用されるパラメータ
  • DB インスタンスパラメータ : インスタンス毎に設定されるパラメータ

Auroraの構成に最適化されているので、基本的にはいじる必要は無い

参考

エンドポイント

4つのエンドポイントがある

  • クラスタエンドポイント : masterノードのエンドポイント read/writeが可能
  • 読み取りエンドポイント : リードレプリカへのエンドポイント readのみ。適当に負荷分散してくれる
  • インスタンスエンドポイント : 個別の各DBサーバへのエンドポイント
  • カスタムエンドポイント : インスタンスをユーザが組み合わせてエンドポイントを作成できる
    • たとえば、バッチ処理など重たい処理専用のリードレプリカを決めて、webサービスではそれ以外のリードレプリカを使うとか

参考

Auroraに最適化するためにやること

  • 1つのトランザクションで大量のread/writeをする場合、SQLを分けると高速化されやすいとのこと
    • 並列実行に特化したチューニングをしているらしい
    • Parallel Queryを使う場合はあんまり考える必要がなくなるのかな?
  • マシン性能に比例してパフォーマンスが上がるようにチューニングされているので、遅いときはマシンの性能を上げるのが手っ取り早いとのこと

制約事項

  • ストレージの最大容量が64TB
  • リードレプリカは最大15台
  • MySQLでは、InnoDB/ROW_FORMAT=Dynamicのみサポート
    • ROW_FORMAT= COMPRESSED が使えない(データを圧縮することで、IOのコストを下げるオプション)
  • Performance Insightsは、T2インスタンスで走らせるとメモリが不足する

あんまりわかっていないこと

  • zero-downtime-patchingでは、Auroraのバージョンアップはできるけど、エンジン(MySQLとか)の更新はできない?
  • リードレプリカのスケジュールに基づいたスケーリングってできるのかな?
    • 例えば週末だけリードレプリカを予め増やしておきたいとか
  • Auroraへの移行ってどうするの?
  • 全文検索エンジンは入れられる?

参考リンク

javascript の generator おぼえがき

ECMAScript 6 にて実装された

generator って?

generatorそのものの解説はこちらが詳しい

Pythonのジェネレーターってなんのためにあるのかをなるべく分かりやすく説明しようと試みた - Qiita

  • 要するに、ステートを持ち、呼ばれるたびにそのステートを使った処理結果を返すオブジェクト
  • 超でかいファイルを1行づつ読み込む時とか、必要な時に必要なだけ実行される処理が欲しい時に使う
  • rubyだと Enumerator::Lazy とかが近い?

実装方法

generator関数

  • generatorを生成する関数
  • generator関数は function* で宣言できる
  • generator関数の中では、yield を設定できる(後述)

generator

  • generator関数 の戻り値として生成される
  • next() を実行すると、generator関数で設定した yield のところまで実行される
  • next() の戻り値は、 valuedone のキーを持つ Hash
    • value : yield の引数
    • done
      • なにか処理が実行されていれば true
      • 何も処理が実行されていれば false

サンプル

function* generator(){
  yield 1;
  yield 2;
  yield 3;
}

g = generator();

console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
console.log(g.next());
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: undefined, done: true }
{ value: undefined, done: true }

サンプル2

遅延評価的なことをやってみる

function* fibonacci_generator(){
  var a = 0;
  var b = 1;

  while(true) {
    const c = b
    b = a + b;
    a = c;
    yield b
  }
}

const fibonacci = fibonacci_generator();

for(var i=0; i<10; i++){
  console.log(fibonacci.next());
}
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 5, done: false }
{ value: 8, done: false }
{ value: 13, done: false }
{ value: 21, done: false }
{ value: 34, done: false }
{ value: 55, done: false }
{ value: 89, done: false }

こっちは終わらない処理なので、 done はずっと false

ディスク容量が足りなすぎて growpart でエラーが出た時にやったこと

概要

  • あまりにもディスク容量が無いと、growpart に失敗する
  • その時にディスク容量を減らすために、何を削除したのかの記録

growpartのエラー

$ sudo growpart /dev/nvme0n1 1
mkdir: cannot create directory '/tmp/growpart.7531': No space left on device
FAILED: failed to make temp dir

ディスク容量削減のためにやったこと

apt-get autoremove は不要なパッケージを削除してくれるコマンドで、ディスク容量の削減にもってこいだが、あまりにもディスク容量が少ないとエラーが発生する

$ sudo apt autoremove
Reading package lists... Error!
E: Write error - write (28: No space left on device)
E: IO Error saving source cache
E: The package lists or status file could not be parsed or opened.

その場合、以下のように不要ファイルを地道に削除していく必要がある

不要ファイルの削除

以下のファイルを削除して容量を確保した

  • /var/cache/apt/archives/*deb
  • /var/cache/apt/pkgcache.bin.*
  • /var/log/*/.gz

/var/cache/apt/archives/*deb

apt-get でダウンロードしたpackageのcache

/var/cache/apt/pkgcache.bin.*

apt-get autoremove (後述) がディスク容量不足で実行失敗した時に発生したゴミファイル

/var/log/*/.gz

過去のログ。もう見なさそうなので削除

EC2にてubuntuのEBSの容量が不足した時にやったこと

概要

  • AWS EC2 でストレージ(EBS)の容量が不足した
  • EBSの管理画面から設定変更すればすぐ変更可能かと思ったらやることがまだあったので、忘れない内にまとめる

OS

Ubuntu 16.04.2 LTS (GNU/Linux 4.15.0-36-generic x86_64)

やったこと

  • EBSの管理画面からストレージの容量を変更
  • growpart コマンドで、拡張したストレージをパーティションに追加
  • resize2fs コマンドで、ファイルシステムに拡張されたパーティションを認識させる

EBSの管理画面からストレージの容量を変更

EBSを選択 → 「アクション」 → 「ボリュームの変更」

f:id:kasei_san:20181119160055p:plain

説明のところに編集ボタンがあると思ってしばらく探した...

この時点では、ストレージこそ16GBになったが、 追加された8GBはどのパーティションにも属していない状況

$ lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0  16G  0 disk 
└─nvme0n1p1 259:1    0   8G  0 part /
  • lsblk はブロックデバイスの情報を取得するコマンド

growpart コマンドで、拡張したストレージをパーティションに追加

$ sudo growpart /dev/nvme0n1 1
CHANGED: partition=1 start=2048 old: size=16775135 end=16777183 new: size=33552351,end=33554399

無事拡張された

$ lsblk
NAME        MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1     259:0    0  16G  0 disk
└─nvme0n1p1 259:1    0  16G  0 part /

growpart は、ストレージの空き領域をパーティションに追加するコマンド

resize2fs コマンドで、ファイルシステムに拡張されたパーティションを認識させる

拡張前

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/nvme0n1p1   8065444 3562788   4486272  45% /
$ sudo resize2fs /dev/nvme0n1p1
resize2fs 1.42.13 (17-May-2015)
Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/nvme0n1p1 is now 4194043 (4k) blocks long.

拡張後

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/nvme0n1p1  16197524 3563812  12617328  23% /

resize2fs は、パーティションの変更やマウントなどのデバイス上の変更をファイルシステムに反映するコマンド(っぽい

javascript の Promise おぼえがき

AWS lambda で Node.js と向きう合う必要が出てきたので、最近のモダンな JS を理解する

最近は async/await が使えるらしいが、内部的には Promise を使っているらしいので、まずは Promise から理解する

Promise とは?

非同期処理の実行結果(成功 or 失敗) の受け取り口を用意して、非同期の管理を容易にするためのオブジェクト

コールバック地獄のしんどさを回避するために生まれた

つかいかた

new Promise する

  • 第一引数は、引数が2つある関数
    • 関数の第1引数には、正常終了時に呼び出す関数
    • 関数の第2引数には、異常終了時に呼び出す関数
  • new Promise の戻り値は、then()catch() を持つオブジェクト
    • then() には正常終了時に呼ばれる関数を渡す
    • catch() には異常終了時に呼ばれる関数を渡す
      - 例外を勝手に拾ってくれたりはしないので、自前で例外をコントロールする必要がある
      
  • then()catch() が呼ばれた時点で、promise に渡した関数が実行される

正常終了例

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('foo');
  }, 10);
});

promise.then((value) => {
  console.log("then");
  console.log(value);
}).catch((value) => {
  console.log("catch");
  console.log(value);
});

出力結果

then
foo

異常終了例

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('foo');
  }, 10);
});

promise.then((value) => {
  console.log("then");
  console.log(value);
}).catch((value) => {
  console.log("catch");
  console.log(value);
});

出力結果

catch
foo

Promise のチェーン

then() の戻り値を Promise オブジェクトにすることで、Promise をチェーンできる

これにより、非同期処理を同期的に実行できる

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise1');
  }, 10);
});

promise1.then((value) => {
  console.log("then 1");

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('promise2');
    }, 10);
  });

}).then((value) => {
  console.log("then 2");
});

出力結果

then 1
then 2

Promise#all

複数 Promise の並列実行ができる

正常終了例

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('promise1')
    resolve('promise1');
  }, 10);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('promise2')
    resolve('promise2');
  }, 10);
});

Promise.all([
  promise1, promise2
]).then((value) => {
  console.log(value)
  console.log('finished')
});

then() には、各 Promiseresolve の引数を配列にしたものが渡される

promise1
promise2
[ 'promise1', 'promise2' ]
finished

異常終了例

1つでも reject() が呼ばれたら catch() が呼ばれる

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('promise1');
  }, 10);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('promise2');
  }, 10);
});

Promise.all([
  promise1, promise2
]).then((value) => {
  console.log(value)
  console.log('finished')
}).catch((value) => {
  console.log(value)
  console.log('catch')
});

出力結果

promise2
catch

reject() が複数発生する場合も、早いもの勝ちで最初の reject() の引数が渡される 処理自体は最後まで行われる

Promise.race()

複数 Promise のうち、1つでも処理が完了したら then() が呼ばれる

初心者向けNoSQLおぼえがき

RDBとの違いとかあんまりわかっていなかったのでメモ

RDBの限界

スキーマの限界

  • 多種仕様なデータや、ネストが深いデータのテーブルを設計するの大変
  • 最近の高ベロシティの要望で、それを高頻度に変更していくのはもっと大変
  • そもそもJSONやXMLでもらったデータとか、データ構造が不定だったりすると、テーブルに乗っけられない

スケールアウトの限界

  • 複数マシンでRDBを管理するの大変
    • レプリケーション大変
    • リードレプリカつくるとか、テーブル分割とか手もなくはない
  • k8sのような分散システムを想定した設計ではない

そこでNoSQLですよ

NoSQL = Not Only SQL

NoSQLの特徴

  • スキーマ定義なしでデータの保持が可能(スキーマレス
  • 速度やスケーラビリティ重視
    • その分、 リレーションを持たない
    • その分、 トランザクションがない
      • 最近はトランザクションをサポートしているNoSQLも多い

NoSQLといっても色々ある

  • KVS
  • ドキュメントDB
  • グラフDB

今回は、KVSと、ドキュメントDBについて解説

KVS

Key Value Store

  • 名前の通りキーと値の1対1のデータ構造

特徴

シンプル

なので大量データ読み書きや分散システムに向いている

  • データ読み書きが高速
  • 水平展開が簡単

複雑なことはできない

  • データ構造は、単一値か配列くらいまで
  • なので、複雑なデータ処理はできない

使いみち

  • webアプリのセッションストア
  • RDBMSのキャッシュ(SQLをキーにする

主な製品

  • redis
  • memcached
  • Amazon ElastiCache
  • google BigTable

ドキュメントDB

保存するデータ構造が自由なデータベース

  • 大抵はJSONやXMLでデータを保存する

特徴

スキーマレス

  • 複雑な階層構造を意識してスキーマを設計しなくて良い
  • 頻繁な構造の変更に追従しやすい

KVSよりは、複雑なデータの保持や検索ができる

使いみち

  • 複雑な階層構造のデータの保持(電子カルテ、色々な情報が付く商品データなど)
  • 頻繁に仕様が変わるデータの保持(API、高ベロシティのアプリ開発とか)

デメリット

  • 全文検索が弱い(らしい)
  • 並列展開しない場合、RDBよりも検索速度が遅い
  • 結合に制約があるため、あまり複雑な検索はできない

主な製品

  • MongoDB
  • Amazon DynamoDB

どういうふうにRDBと使い分けるの?

それぞれ特徴を生かしている分、メリット、デメリットも明確なので、要件に応じて使い分けるのが得策

  • 超大量のデータをすばやく制御したい場合は、NoSQL
  • データのキャッシュはKVS、複雑なデータの保持だけドキュメントDB
  • 逆に複雑なクエリ、明確なスキーマ、トランザクションが重要な場合はRDB

MySQLやPostgreSQLもドキュメントDBやKVSをサポートしているので、一部テーブルだけそちらに移行するのも良い

  • NoSQLもRDBMSも、それぞれお互いの機能をどんどん追加している段階なので、最新の情報をもとに決めたほうが良い

Amazon S3 ストレージクラスおぼえがき

概要

以下の4つのストレージクラスがある (下に行くほど制限があるが安くなる)

  • 標準
  • 標準 – 低頻度アクセス
  • 1 ゾーン – 低頻度アクセス
  • Amazon Glacier

向いているデータ一覧

標準

以下のいずれかのデータ

  • アクセス頻度高
  • SLAやデータの耐久性が重要
  • 超細かいデータが大量にある場合
  • 30日以上保持しないデータ

標準 – 低頻度アクセス

  • アクセス頻度が低く、SLAやデータの耐久性が重要なデータ

1 ゾーン – 低頻度アクセス

  • アクセス頻度が低く、SLAやデータの耐久性がそこまで重要ではないデータ

Amazon Glacier

  • アーカイブ用。取り出しに時間がかかっても良いデータ

早見表

料金

東京リージョンの場合

  ストレージ料金 データ取り出し料金 PUT、COPY、POST料金 GET、SELECT料金
標準 0.025USD/GB 無料 0.0047USD/1000req 0.00037USD/1000req
標準 – 低頻度アクセス 0.019USD/GB 0.01USD/GB 0.01USD/1000req 0.001USD/1000req
1 ゾーン – 低頻度アクセス 0.0152USD/GB 0.01USD/GB 0.01USD/1000req 0.001USD/1000req
Amazon Glacier 0.0005USD/GB 後述 後述 後述

その他特徴

  可用性 最小料金サイズ 最小利用期間
標準 99.99% なし なし
標準 – 低頻度アクセス 99.9% 128KB 30日
1 ゾーン – 低頻度アクセス 99.5% 128KB 30日
Amazon Glacier なし なし 90日
  • 可用性: 1年に可動する論理上の値(SLAはもう一桁低い)
  • 最小料金サイズ: 128KBなら、それ以下のオブジェクトでも、128KBとみなされて課金される
  • 最小利用期間: 30日なら、それ以下のオブジェクトでも、30日とみなされて課金される

標準

アクセス頻度が高く、SLAが重要なデータ
もしくは超細かいデータが大量にある場合
もしくは30日以上保持しないデータ

特徴

  • 取り出し料金は無料
  • 最小料金サイズなし
  • 最小利用期間なし
  • リクエストコストは安い
  • ストレージコストは高い

標準 – 低頻度アクセス

アクセス頻度が低く、消えたら困るデータ向け

  • 標準IA(Infrequent Access)とか呼ばれることもある

注意事項

  • リクエストが高頻度だと、場合によっては標準より高コスト
  • 128KB以下のデータを大量に保持する場合、場合によっては標準より高コスト
  • 30日以下しか保持しないデータを大量に保持する場合、場合によっては標準より高コスト

特徴

  • 取り出し料金は有料
  • ストレージコストは安い
  • リクエストコストは高い
  • オブジェクトが128KB以下の場合も、128KBとみなされて課金される
  • オブジェクトの保持期間が30日以下でも、30日とみなされて課金される

1 ゾーン – 低頻度アクセス

アクセス頻度が低く、SLAやデータの耐久性がそこまで重要ではないデータ

注意事項

標準 – 低頻度アクセスと同じ

特徴

アベイラビリティゾーンが1つで運用される
そのため、アベイラビリティゾーンが破壊された場合データは失われる

Amazon Glacier

アーカイブ用。他のS3と異なり、取り出しに非常に時間が掛かる

  • データをテープやDVDなどのコールドストレージに保持しているらしい

取り出し方式が、標準 大容量 迅速 の3つあり、それぞれ特徴が異なる

特徴

  取り出し 料金 制限
標準 3〜5H 標準 なし
大容量 5〜12H 安い なし
迅速 1〜5min 高い 250MB以内

低冗長化ストレージ

現在非推奨

今回の価格改訂により現時点ではスタンダードストレージを選択した方がお客様にメリットがある状態になっています

aws.typepad.com

  • 標準の仕様だが、データの耐久性は 99.99%
  • Reduced Redundancy Storageの略

参考

aws.amazon.com