DynamoDBウキウキで初めて早速引っかかる問題の一つが多対多とn+1問題だと思うんだが、これについてはAWSのドキュメントに一応解決方法が乗っている。それについて書いた記事がこれ→「DynamoDBで多対多のテーブル設計 – 或る阿呆の記」。
隣接リストというデザインパターンで、初めて見た時はギョッとしたけど、実際やってみるとたしかに効率的にクエリが書ける。テーブルの構造についても、ああつまりRDBの中間テーブルに要素をもたせるとこうなるのか、ということで、個人的には納得もした。
ただこの方式は、冗長である。したがって、同一であるべきアイテムの情報に不整合が発生する可能性がある。それについて、どう対応したもんなんだろうか。
トランザクション処理
真っ先に思い浮かぶのはトランザクション処理だ。進化を続けるDynamoDBは、一定の制約はあるもののトランザクション処理もサポートするようになった。試しに使ってみたのが「DynamoDBにboto3でトランザクションな書き込み – 或る阿呆の記」の記事。
ただ数的な制約とか、boto3.resource()だと使えなくて低レベルなboto3.client()を使う必要があったとか、Lambda関数のboto3が古くてzipあげる謎工程が必要だったとか(さすがにこれはもう解決しているだろうが)あって、結局実際には使わなかった。
トランザクション処理はDynamoDBにおいては最終手段の気もする。
バッチによる定期メンテ
次に思い浮かぶのは、不整合を確認するバッチによる定期メンテだ。一日に一回くらいテーブルをフルスキャンして、おかしなところがないか確認する。
というとなんか阿呆っぽいんだけれど、実際こういうバッチを走らせてなんとかしているシステム世の中たくさんあると思う。。。
リアルタイム性を犠牲にできるユースケースであれば、なんだかんだでこれが一番ラクな気がする。しかしそうやって謎のバッチスクリプトがあちこちで走り始めると、何がなんだかわからなくなってくるので、管理の問題は別途出てくるけど……。
ほっといてもそのうち直る仕組み
このケースはけっこうある。たとえば最新値などがそうで、最新値は常に変わり続けるから、たとえ1回ミスって不整合があっても、ほっといたら再更新かかるのでなおっている。それだったらわざわざコストかけて面倒見るより、あえて放っておく、で十分だったりする。
結局……
ということで、自分はといえば、結局
- リアルタイム性が必要→更新が多いはず→対応しない。ほっといたらまぁだいたい合ってるでしょって感じ
- リアルタイム性はそんなでもない→あんまり更新もない→バッチで確認したら十分
のあわせ技でなんとかしている感じ。とはいえ、実際不整合はほとんど発生していなくて、たまに見つかるとだいたいアプリケーションのロジックがそもそもポカしていたりするので、まぁこれくらいでいいのかなぁと思いつつ、みんなどうしているんだろうというのは気になっている。
コメント