MySQLをDynamoDBにリプレイスしたい時に考えるべき事

MySQLをDynamoDBにリプレイスしたい時に考えるべき事

MySQLをDynamoDBにリプレイスしたい時に考えるべき事

MVCモデルなフレームワークが開発の中心に座っている現在、チョコチョコと話に上がるのがSQLをNonSQLにリプレイスする話です。
具体的にはMySQLをDynamoDBにしようとかAzureが使えないかとか。
今回はDynamoDBに特化してリプレイスが可能なシーンとDBの構造設計についてまとめてみます。

MySQLなどのリレーショナルDBは何が問題なの?

件数が多いと抽出に時間がかかる

なので、ビッグデータをゴニョゴニョする様な動作は苦手です。
正しくインデックスを貼って対応していけば抽出時間の軽減は可能ですが、億を超えるレコードだとどうしても遅いです。
それでもPHPやRubyなどで抽出/計算するよりは早いので重宝されています。

DynamoDBのメリットとは

よく言われるメリットは2つです。

  • 容量を気にしなくていい
  • 決まった値で抽出する能力が高い

DynamoDBのデ・メリットとは

  • 1テーブル最大4つのカラムでしか検索/抽出ができない
  • 集計/計算が苦手

DynamoDBは大量のデータを格納するため検索能力を向上させるためにインデックスを貼るのですが、これが1テーブル最大4つしか設定できません。(つまりは4つのカラムでしか検索やソートができません)

また、相方のようにLambdaが存在しているため、自身で集計する能力に関してはとても弱くSQLに劣ります。

Lambdaを介す方法と直接アクセスする方法の違い

Lambda:抽出から集計/計算までをLambdaに任せ、問い合わせに対して処理済みの答えを返す姿を用意できる
直接アクセス:DynamoDBに接続し抽出するが、集計/計算はバックエンドが担う。バックエンドの計算処理能力が重要になる。

今回のプロジェクトではバックヤードがLaravelで動いているので、直接アクセス = Laravelを使った接続方法になります。
Lambdaを介した場合、LambdaがDynamoDBの参照から集計/計算処理までをこなします。
そのため、LaravelなどのバックヤードはLambdaのAPIを叩き、結果を受け取るというフローで構築を行います。

一方で、直接アクセスする場合はAWSのDSKを利用し接続/取得していくことになります。
予め接続できる環境を整えてくれているlaravel-dynamodbなどのツールも存在しておりこういったものを利用させて頂くと環境整備の速度は早くなります。※ただし、それぞれ癖もあるようです。

今のデータベース構造をそのままDynamoに移植できる?

検索や並び替えをしたいカラムの数によっては無理です

DynamoDB は最大4つの項目でしか検索をしてくれません。
それ以外の項目で処理をしたい場合は一旦バックエンドに引き取ってPHPやPythonなどで抽出/並び替えを実行することになります。
マシンパワーにもよりますが、この構築はMySQLで実装した場合よりも遥かに時間がかかることでしょう。

検索対象項目が多い場合はDynamoDBをどう処理するか

大きく2つの方法があります。

  1. テーブルを分割し、親キーを保存するカラムを基礎として仮想レーションを構築、バックエンドで合成する
  2. 複合インデックス用のカラムを用意し、検索などは複合インデックスに記載されるルールに則って該当のカラムを検索する

前者の場合は書き込みの回数が倍増するので、テーブルを2つに分解した場合、単純に維持経費が2倍になります。

具体例:1200万回/日の書込みと読込が発生する場合

おおよそ4万円/月かかる様です。

  • 書き込み: 0.000742USD * 5キャパシティーユニット * 24時間 * 30日 = 2.67USD
  • 読み込み: 0.0001484USD * 5キャパシティーユニット * 24時間 * 30日 = 0.53USD

※ 1WCU(書き込みキャパシティユニット)は1秒間に1回の書き込み

DynamoDBリプレイスの課題

懸念事項としては3点です。

  1. 検索/ソートするカラムは固定で問題ないか
  2. 検索/ソートするカラムが4つ以上の時、テーブル設計を見直すことは可能か
  3. テーブルを分割した場合、経費的に問題のないラインで収まるか

DynamoDBへの書込みが多い場合(何がしかの機械が毎秒ログ書き込んでくるとか)は、台数によって中々な金額になってきます。

具体的なところだと、90秒に1回データを上げるBOTが存在し、その流通数が10万台だとした場合【9千6百万回】の書込みが発生することになります。これを積算してみると、24万円の費用が必要になります。
この時、検索/抽出項目が多いからとテーブルを4つに分裂させていた場合【24万×4】の費用が発生することになります。
つまり、テーブル設計がダイレクトに費用に返ってくると。

DB屋の腕の見せ所でもありますが、頭も心もシンドイですよね。

まとめ

ちょうどDynamoDB移行の案件が出てきたため簡単にまとめてみました。
一筋縄ではいかない事が多々あり、速度と利便性を考えるとDynamo×Lambdaでの構築例が多い理由、よくわかりますね。