💀

DMSによるレプリケーションがよく止まる場合の対処法まとめ

2023/01/26に公開

前置き

こんにちは。株式会社GENDAのデータエンジニアのこみぃです。

本日のお話は以下の記事の続きのようなお話です。
https://zenn.dev/kommy339/articles/636f8a7c58596c

DMSが、止まる。。。。

前述の記事にもあるように、DMSを継続的レプリケーションで使うと、まあ本当によく止まります。

止まる理由としては以下が多いです。

  • 定期的にALTERを打つ必要があり、仕方がない
  • 更新が多いテーブルであるためレプリケーションが遅れ、binlogの保持期間を過ぎてしまう
  • 原因不明

そういうわけで、これに対しての対策として編み出したことを列挙しておきたいと思います。

1. リカバリ用のSQLを用意しておく

これは前回の記事で書いた内容ですね。
https://zenn.dev/kommy339/articles/636f8a7c58596c

特に定期的に止まることが確定している場合にはリカバリ方法は必須で、可能なら自動化したいところです。

2. RDSのbinlogの保持期間を長くする

これは2つ目のケースの対応としてかなり有効で、実際かなり緩和される印象です。

やり方はこんな感じです。
https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Source.MySQL.html#CHAP_Source.MySQL.AmazonManaged

更新が多いテーブルはDMSが更新を追いかけるときに追いつかないということがよくあります。
なぜこうなるかというと、行指向であるRDSと比較して列指向のデータウェアハウスは1レコード単位での追加や更新に時間がかかるからだと思われます。

binlogの保持期間を長くしておけば、一気に定期処理で更新をかけるようなタイミングではかなり反映が遅れますが、更新が少ない時間帯に追いついていくのでかなり解消されます。

3. 過去のデータは別テーブルに退避しておき、フルロード時にすべてのテーブルを読み込まないようにする

DMSはテーブルごとにレプリケーションする行の条件を指定できます。
ログのテーブルなどはレコードが追加されていくのが基本で過去のデータは書き換わらないので、毎回テーブル全体をフルロードするのではなく一定以上過去のデータは別テーブルに置いておいてあとでマージすることができます。

レコードが多い場合の悩みだと思いますので、過去データと新しいデータのマージはViewではなくdbtなどでテーブルを作るのがおすすめです。
SnowflakeだとEnterpriseが必要ですが、Materialized Viewもありです。

ちなみにこれを書いておいてなんですが、ログテーブルをRDSで管理すること自体があまりオススメではありません。
ログは可能ならストリームでKinesisFirehoseなどを使ってS3に流し、RDSを経由せずにデータウェアハウスに入るようにすると良いです。

結びの言葉

DMSは仕組みとしては画期的なんですが、ちょっと安定性がね。。。以前も多分同じことを書いていて、AWSを使うデータエンジニアの悩みの一つなんじゃないかなと思います。
今後もベストプラクティスを議論してより良い世界を目指していければと思います。

最後に一つ宣伝を。
私が所属する株式会社GENDAでは一緒に働く仲間をすごくすごい真剣に求めています。
興味がありましたらぜひお気軽にお声おかけください。
https://genda.jp/

本日はこのあたりで。
それじゃあ、バイバイ!

Discussion