4

ほとんどのドメイン固有のモデルに何らかの NoSQL データ ストアを使用する REST 中心のアプリケーションを作成しています。REST データ フレームワークを中心に構築する予定のプライマリ サイトでは、ユーザー、請求情報、およびドメイン データ モデルの範囲外にあるその他のメタデータ用に従来のリレーショナル データベースを引き続き使用したいと考えています。

このアプローチは、RDBMS と NoSQL の両方のデータ ストアに対して同じ要求で I/O を実行することをできるだけ回避できる場合にのみ有効であるとアドバイスされています。

私の質問:

  1. これは良いアドバイスですか?(私はそう仮定していますが、最初の前提が間違っている場合、残りの質問は役に立ちません。)
  2. 少なくともログオンしているユーザーを可能な限りキャッシュしたいと思います。Django セッションを使用して、安全で、確実に正しく、フォールト トレラントな方法でこれを行うことは可能ですか? 理想的には、ユーザー テーブルとのやり取りをできるだけ少なくして、現在のユーザーを取得するための、安全な一時的な代替手段としてセッション API を使用したいと考えています。すべてを接続するには、どのような準備が必要ですか?
  3. これが非常に面倒な場合、django-nonrel を使用せずにユーザー情報を NoSQL ストアに格納する (つまり、RDBMS を完全に排除する) のはどれほど簡単でしょうか? カスタム認証/承認バックエンドでこれを行うことはできますか?
4

1 に答える 1

8

私は自分のアプリケーションに同じアプローチを使用することを考えています。一般的には安全だと思いますが、キャッシュの一貫性の問題に取り組むには特別な注意が必要です。

Django が通常動作する方法は、リクエストが受信されると、Session テーブルに対してクエリが実行され、リクエストから Cookie に関連付けられたセッションが検索されます。次に、 にアクセスrequest.userすると、User テーブルに対してクエリが実行され、特定のセッションのユーザーが検索されます (存在する場合、Django は匿名セッションをサポートしているため)。そのため、デフォルトでは、Django は各リクエストをユーザーに関連付けるために 2 つのクエリを必要とし、コストがかかります。

Django セッションの優れた点は、モデル クラスを拡張せずにキー、値ストアとして使用できることです (たとえば、フィールドを追加して拡張するのが難しい User クラスとは異なります)。request.session['email'] = user.emailしたがって、たとえば、セッションに追加のデータを保存することができます。これはある意味では安全であり、request.session辞書から読み取ったものは確かにそこに置いたものであり、クライアントはこれらの値を変更する方法がありません。したがって、実際にこの手法を使用して、 User テーブルへのクエリを回避できます。

セッション テーブルへのクエリを回避するには、セッション キャッシングを有効にする必要があります (または、セッション データを を使用してクライアント Cookie に格納しますdjango.contrib.sessions.backends.signed_cookies。このような Cookie はクライアントによる変更に対して暗号で保護されているため、安全です)。

キャッシュを有効にすると、リクエストをユーザー データに関連付けるために必要なクエリは 0 になります。しかし、問題はキャッシュの一貫性です。ライト スルー オプション ( django.core.cache.backends.locmem.LocMemCachewith django.contrib.sessions.backends.cached_db) を指定してローカル インメモリ キャッシュを使用する場合、セッション データは変更のたびに DB に書き込まれますが、キャッシュに存在する場合は DB から読み取られません。これにより、複数の Django プロセスがある場合に問題が発生します。1 つのプロセスがセッションを変更した場合 (変更などsession['email'])、他のプロセスはキャッシュされた古い値を引き続き使用できます。

共有キャッシュ (Memcached バックエンド) を使用することで解決できます。これにより、1 つのプロセスによって行われた変更が他のすべてのプロセスに表示されることが保証されます。このようにして、Session テーブルへのクエリを Memcached バックエンドへのリクエストに置き換えます。これははるかに高速になるはずです。

セッション データをクライアント Cookie に保存すると、キャッシュの一貫性の問題も解決できます。Cookie の電子メール フィールドを変更すると、クライアントから送信される今後のすべてのリクエストに新しい電子メールが送信されます。クライアントは意図的に古い Cookie を送信することができますが、古い値がまだ保持されています。これが問題になるかどうかは、アプリケーションによって異なります。

于 2013-01-20T12:22:51.127 に答える