Skip to content

Instantly share code, notes, and snippets.

@kashewnuts
Last active January 28, 2024 14:18
Show Gist options
  • Save kashewnuts/2e23d69445733603fff6510eda39be9b to your computer and use it in GitHub Desktop.
Save kashewnuts/2e23d69445733603fff6510eda39be9b to your computer and use it in GitHub Desktop.

Djangoの複数DBを使ったレプリケーション

要約

  • Django標準のDATABASESでDBを定義し、DATABASE_ROUTERSでルーティングを定義したクラスを書けばほぼ行けそう。
  • 3rd-Partyはレプリカ遅延のアプローチを提供しているので、使うならPJに合うものを選定・もしくは自前実装すること。

MySQLのレプリケーションについて

  • Django 1.4 documentation の頃には既にある機能。
  • 公式の実装例はプライマリ/レプリカ構造のレプリケーション・ラグ(書き込みがレプリカに伝播するまでに時間がかかるために生じるクエリの不整合)を処理する内容を提供していない。
  • また上記例はトランザクションとデータベース利用戦略の相互作用が考慮されていない。
  • しかし考慮すべきはそのぐらいなので標準にミドルウェアやルーターを追加して書き換えることは可能

3rd-Party

どちらも3〜4年ほどメンテされていないので、導入するなら対応内容や状況を見て行うこと

  • Released: Apr 10, 2020
  • Star: 349
  • Fork: 65
  • 特徴: デコレーターもしくは辞書で指定したviews単位でプライマリ/レプリカを指定できる
  • メンテ状況
    • 現在某PJで運用してるので実績があるが、4年ほどメンテされていない。
    • テストコードがpytestで記述されているので、テストコードだけ修正すれば動きそう。
    • Python3.12でも、Django5.0でもWarningもなくテストが通る
    • pytest-django>=4.3.0だとテストがコケるが、4.2.0ならテストは通るので一旦スキップ
  • Released: Sep 23, 2021

  • Star: 305

  • Fork: 61

  • 特徴: デコレーターでプライマリ/レプリカを指定できる。(viewsに縛られないかは要確認)

  • メンテ状況

    • django_replicatedで代替として上げられているが、3年ほどメンテされていない。(別某PJで実績あり)
    • Django4.2まではテストが通るPRを上げている人がいる。
    • テストコードがdjango-noseなので、Python3.10以降だとテストコードが通らない...
    • PinningReplicaRouterをtokibitoさんのプロジェクトでは使っているが、ほかは別にDjango標準の機能でできるのでいらない。
  • Django Packages : Reusable apps, sites and tools directory for Django で探しても特に他に定番は見つからず

独自実装のアプローチ

  • 独自でDjango Middlewareを作成して、APIリクエスト単位でルーティング設定。GETリクエストの場合はReplicaを参照させる
  • DjangoのDATABASE_ROUTERS とMiddlewareを作成して実装する例。モデル単位で接続先を分ける例も説明されている。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment