質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

5686閲覧

pythonのDjangoで、変数の値を共有する方法

TeSe

総合スコア17

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2017/07/30 10:59

編集2017/07/30 13:25

python3系で、Djangoを用いたWEBアプリを開発しています。

その中で、キャッシュの仕組みを作るところで悩んでいます。
下記の場合のそれぞれで、変数の値を共有する方法を教えていただけませんでしょうか。

<調べて分かったこと>
関数(def ~)の外側で宣言した変数は、各関数で値を共有出来る。
ただし、関数内でglabalを付けて変数を呼び出さないと、変更できない。

<調べても分からなかったこと>
1.WEBで、ユーザーAとユーザーBで変数の値を共有する方法。
ユーザーAが呼び出した関数で変数が変更されると、次にユーザーBがその変数にアクセスしたときに、
変更された値を参照したい。
2.上記は、同じページを前提としていますが、異なるページ間でも変数の共有を行いたいです。
具体的には、DBから取得したマスタデータをキャッシュしたく、
アプリを立ち上げで1度だけDBにアクセスすれば、後はその値を変数にもっておき、
次からはどのユーザーがどのページから実行した関数でも、キャッシュを利用できるようにしたいです。

また、1と2で、値の更新の衝突が起こりうる場合に、それを防ぐような工夫は何かありませんでしょうか。

よろしくお願いいたします。

<追記>
2は下記のようなイメージです。
http://www.atmarkit.co.jp/fdotnet/dotnettips/122globalobj/globalobj.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

1.WEBで、ユーザーAとユーザーBで変数の値を共有する方法。
ユーザーAが呼び出した関数で変数が変更されると、次にユーザーBがその変数にアクセスしたときに、変更された値を参照したい。

通常はデータベースに記録すると思いますが、どうしても「キャッシュの仕組み」でやろうとするのであれば、Djangoのキャッシュフレームワークを使えばできそうです。
https://docs.djangoproject.com/en/1.11/topics/cache/

2.上記は、同じページを前提としていますが、異なるページ間でも変数の共有を行いたいです。
具体的には、DBから取得したマスタデータをキャッシュしたく、アプリを立ち上げで1度だけDBにアクセスすれば、後はその値を変数にもっておき、次からはどのユーザーがどのページから実行した関数でも、キャッシュを利用できるようにしたいです。

これもDjangoのキャッシュフレームワークで解決できますね。

また、1と2で、値の更新の衝突が起こりうる場合に、それを防ぐような工夫は何かありませんでしょうか。

通常はデータベースのトランザクションを使います。
データベース以外の(キャッシュなどの)方法で行う場合、 セマフォ, スピンロック, クリティカルセクション といった仕組みをキャッシュか何かの、共有された領域を使って実装する必要があります。

簡単に説明すると、キャッシュに「これから更新するフラグ」を用意して、このフラグが立ってるときは別の処理はフラグを立てられなくする、という考え方です。

しかし、書かれている内容からすると、必要なのはデータベースのトランザクションのように思えるので、先にそちらを検討した方が良いかもしれません。

なお、キャッシュについては、以下の2つの回答も参照してみてください。

投稿2017/07/30 13:15

shimizukawa

総合スコア1847

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TeSe

2017/07/30 13:27

早速ありがとうございます。 DBへの値の保存が一般的のようですね。 追記させていただきましたが、ASP.NETにおけるGlobalやApplicationオブジェクトのようなものがあれば、大変助かりました。 pythonやDjangoでは、同じようなことは出来なさげですね。。。
shimizukawa

2017/07/30 13:45

そこまでフレームワーク化されたものはDjango標準にはなさそうですね。
guest

0

キャッシュが必要ということは、毎分1万PVとかのオーダーでリクエストが突っ込んでくる高負荷なWebアプリを作っているんでしょうか?

そもそも変数をキャッシュとして使うのはおすすめできません。マルチプロセスで Django が動いている場合はそもそもメモリ空間が全く別なので互いにキャッシュの更新を検出できませんし、マルチスレッドでも考え無しに同時書き換えした場合にデータが容易に破壊してしまいます。

一般的には高速なキャッシュサーバーを別に立てて利用することが多いようです。Django の公式リファレンス: Django のキャッシュフレームワーク — Django 1.4 documentation にあるように、Memcached をバックエンドとして 低水準のキャッシュAPI を使うのがよい落としどころだと思います。

またキャッシュサーバーは基本的に更新の競合を防ぐ仕組みを持ちません(だから速いんです)。マスターデータは RDBMS (MySQL, PostgreSQL など)にあると思いますので RDBMS のロック機能を使わせてもらえばよいと思います。具体的にはキャッシュミス時や更新時に排他ロックをかけてマスターデータの読み書きを行いつつ、その間にキャッシュサーバーのデータを更新するようにすれば競合が回避できます。ただ万が一トランザクションが失敗してロールバックが走ると、マスターデータは前のままでキャッシュは失敗したデータと不整合が起きます。更新がガシガシ走るようなパラメーターはそもそもキャッシュの効果は薄いですし、本当にキャッシュが必要なのか慎重に検討すべきだと思います。

投稿2017/07/30 13:27

編集2017/07/30 13:36
miyahan

総合スコア3095

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問