0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【図解】AWS RDSとは。データベースの「管理人付き賃貸」と、止めたのに請求が来る理由

0
Posted at

対象読者: AWSをこれから触る人。 AWS勉強シリーズの8本目です。全体の地図は索引記事にあります。

この記事を読むと、次の2つの症状が自分で切り分けられるようになります。

  • 「EC2にPostgreSQLを入れるのと何が違うの?」に答えられない
  • DBを作ったはいいが、止め方が分からなくて課金だけ続いている

RDSはデータベースの管理人付き賃貸

RDSとは何か

Amazon Relational Database Service(RDS)は、PostgreSQLやMySQLなどのデータベースを、AWSが面倒を見てくれる形で借りるサービスです。上の絵のとおり、一軒家(自分でDBサーバーを建てる)だと修理も掃除も全部自分ですが、RDSは管理人付き賃貸。バックアップ・ソフトの更新(パッチ当て)・壊れた部品の交換を管理人(AWS)がやってくれるので、住人は「住むこと」=テーブルを作ってデータを入れることに集中できます。

中で動いているのは普通のPostgreSQLやMySQLです。RDSという名前の新しいデータベースがあるわけではありません。だから接続の仕方もSQLも、ローカルで使っていたものがそのまま通ります。

何に使うか

  • Webアプリのデータ置き場: ユーザー情報・注文・在庫など、「表で管理して、条件で検索する」データ全般
  • EC2に自分で入れたDBの引っ越し先: バックアップ忘れ・パッチ忘れから解放される
  • 複数サーバーからの共有: EC2やLambdaの複数台から同じデータベースに接続する

今AWSの地図のどこにいるか

AWS入門の地図。IAM、S3、EC2、VPC、Lambdaが済み、今回はRDS

IAM(権限)→S3(ファイル)→EC2(サーバー)→VPC(ネットワーク)→Lambda(関数)と来て、今回はデータの本丸です。RDSはVPCの中に建てるので、前回までのSecurity Groupの話がそのまま効いてきます。

今はこれだけ分かればOK

必須の3語だけ覚えます。

意味
DBインスタンス 借りる1台分。この単位で作り、この単位で課金される
エンジン 中で動くDBの種類。postgres / mysql など。作った後から変更できない
エンドポイント 接続先のアドレス。psqlpsycopg2にこれを渡す

マルチAZ、リードレプリカ、パラメータグループ、Auroraといった用語は今は後回しで大丈夫です。1台建てて繋げるようになってからで間に合います。

使い方

RDSの使い方は4手順。建てる、住所をもらう、普通に繋ぐ、使わないなら止める

やることは4つです。上の図がそのままコードの順番になります。

import boto3

rds = boto3.client("rds", region_name="ap-northeast-1")

# ① データベースサーバーを1台建てる
rds.create_db_instance(
    DBInstanceIdentifier="my-first-db",     # 自分で決める名前
    Engine="postgres",                       # エンジン。後から変更不可
    DBInstanceClass="db.t4g.micro",          # マシンの大きさ
    MasterUsername="admin_user",
    MasterUserPassword="dummy-password-123",
    AllocatedStorage=20,                     # ディスク容量(GB)
)

# ② 状態と接続先(エンドポイント)を見る
db = rds.describe_db_instances(DBInstanceIdentifier="my-first-db")["DBInstances"][0]
print("status:", db["DBInstanceStatus"])
print("endpoint:", db["Endpoint"]["Address"], ":", db["Endpoint"]["Port"])

motoで実行した出力です(motoの使い方はシリーズSQS回参照)。

status: available
endpoint: my-first-db.aaaaaaaaaa.ap-northeast-1.rds.amazonaws.com : 5432

このエンドポイントに、あとは普通のPostgreSQLクライアントで繋ぐだけです。psql -h my-first-db.xxxx.ap-northeast-1.rds.amazonaws.com -U admin_user のように使います。RDS専用の接続方法は無い、というのが大事なところです。

注意が1つ。motoでは①が一瞬で available になりますが、本物のAWSでは10分前後 creating のままです。エンドポイントも available になるまで生えてきません。「describe_db_instancesにEndpointが無い」と焦ったら、まだ建設中です。

# ③ 止める(課金を止める)・再開する
rds.stop_db_instance(DBInstanceIdentifier="my-first-db")
rds.start_db_instance(DBInstanceIdentifier="my-first-db")

# ④ スナップショット(その瞬間の完全な複製)を取ってから消す
rds.create_db_snapshot(DBInstanceIdentifier="my-first-db",
                       DBSnapshotIdentifier="my-first-snap")
rds.delete_db_instance(DBInstanceIdentifier="my-first-db", SkipFinalSnapshot=True)

今あなたが作ったもの

①で建ったのは「PostgreSQLがインストールされ、起動済みで、バックアップ設定までされた仮想サーバー1台」です。自分のPCにPostgreSQLを入れたときと違うのは、OSに入れない(SSHできない)こと。中のOSは管理人の領域で、住人が触れるのはDBのポート(5432)だけです。

1か所だけ変えてみる

Engine="postgres"Engine="mysql" に変えて②まで実行してみてください。エンドポイントのポートが 5432 から 3306 に変わります。エンジンを選ぶと接続ポートも決まる、という関係が1行の変更で見えます。

実際に叩くと止まるところ

エンジン名の罠。postgresqlは弾かれ、postgresが正しい

作り方を間違えたときに何が返るか、5パターンmotoで実際に叩きました(エラーの種類名は本物のAWSと同じです。メッセージの文言は多少違います)。

describe_db_instances(DBInstanceIdentifier="nope")     # 無い名前を見る
 → DBInstanceNotFound - DBInstance nope not found.
create_db_instance(同じ名前でもう一度)
 → DBInstanceAlreadyExists - DB instance already exists
create_db_instance(Engine="postgresql")                # 正しくは postgres
 → InvalidParameterValue - engine postgresql not supported
stop_db_instance(止まっているDBをもう一度止める)
 → InvalidDBInstanceState - Instance is not in available state
delete_db_instance(SkipFinalSnapshotを付けずに消す)
 → 最終スナップショットの指定が要る(付けるか、FinalDBSnapshotIdentifierを渡す)

3つ目は自分も引っかかりました。世間では「PostgreSQL」と書くのに、RDSのエンジン名は postgres です。mysql はそのまま mysql なのに、です。エラーメッセージに正しい候補が出ないので、初見だと数分止まります。

5つ目は逆に安全装置です。S3の「無いキーを消しても成功扱い」と正反対で、RDSは消すときに「本当にスナップショット無しでいいのか」を明示させます。スナップショットが無いままこの確認をすり抜けて消したDBは戻せません。

似たサービスとの使い分け

データの置き場所3択。結合検索はRDS、鍵で一発はDynamoDB、ファイルのままはS3

迷うところ 答え
EC2に自分でDBを入れるか、RDSか 特殊な拡張やOSレベルのチューニングが要るならEC2。それ以外はRDS。バックアップとパッチの当番を自分で持つ価値はまず無い
RDSかDynamoDBか 表と表を結合して検索する(SQL)ならRDS。キー1発で読み書きする単純で巨大なデータならDynamoDB
RDSかS3か 検索・更新するデータはRDS。ファイルのまま置いて読むだけならS3
RDSかAuroraか AuroraはAWS製の互換エンジンで速くて高い。入門の段階ではRDSの postgres で十分

料金の考え方

止めたつもりが7日後に自動再開し、月末に請求が来る

課金は主に2つです。

  • インスタンス料: 建てている時間×マシンの大きさ。db.t4g.micro(東京)で1時間約0.026 USD、つけっぱなしで月19 USD前後
  • ストレージ料: 確保した容量。gp2の20GBで月2.7 USD前後

Lambdaと違って、呼ばれていなくても建っている限り課金です。EC2と同じ感覚で扱ってください。学習用なら使わない時間は stop_db_instance で止めます。ただし止めても7日後に自動で再起動する仕様と、ストレージ料は止まっている間も掛かる点は覚えておいてください。「消したつもりが止めただけ」「止めたつもりが再起動していた」が、初心者の請求事故の定番です。

よくある注意点

  • 繋がらない原因の9割はSecurity Group。 RDSはVPCの中に建つので、VPC回で書いた「入れてもらう側の設定」がここでも要ります。接続元(EC2やあなたのPC)からポート5432の受信を許可していないと、エンドポイントが正しくてもタイムアウトします
  • パスワードをコードに書かない。 上の例はmoto用のダミーです。本物ではSecrets Managerか環境変数に置きます
  • エンジンとバージョンは最初に決め切る。 エンジンの変更は作り直し。メジャーバージョンの上げ方はあるが停止を伴う
  • 公開設定(PubliclyAccessible)は自分でFalseを明示する。 コンソールの新規作成画面では既定で非公開ですが、boto3でサブネットの指定なしに建てると、デフォルトVPCではパブリックになり得ます。上のコードを本物のAWSで使うなら PubliclyAccessible=False を足してください。DBをインターネットに晒すのは、S3のバケット公開よりさらに事故の影響が大きい設定です

まとめ

冒頭の2つの症状に答えます。EC2に自分で入れるのとの違いは「管理人が付くかどうか」で、バックアップ・パッチ・故障対応を持たなくていい代わりに、OSには入れません。課金は「建っている時間」に対して発生するので、止め方は stop_db_instance(ただし7日で再起動)、完全に終わらせるならスナップショットを取って delete_db_instance です。

次に手を動かすなら、motoで①〜④を通したあと、Engine を変えてポートの変化を見るところまでやってみてください。そこまでできれば、RDSの入門は卒業です。

次回はDynamoDB(NoSQL)を予定しています。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?