長期実行のPythonスクリプトのファイルと同期してインメモリデータを保持する
-
27-09-2019 - |
質問
私はサーバーとして機能するPython(2.7)スクリプトを持っているため、非常に長期間実行されます。このスクリプトには、クライアントの入力に基づいていつでも変更できる追跡を維持するための価値があります。
私が理想的にその後のものは、Pythonデータ構造を保持できるものです(タイプの値を使用して dict
, list
, unicode
, int
と float
- json、基本的に)メモリで、私はそれを更新させてください(参照タイプインスタンスのいずれかを複数回参照することを除く)。電源プラグが引っ張られ、サーバーはちょうど起動して同じデータを続けることができました。
私は基本的にデータベースについて話していることを知っていますが、私が保持しているデータはほとんどの場合非常にシンプルで1 kb未満ですので、説明されたものを提供できる可能性のあるソリューションを探していますデータの整合性。このようなことをさせることができる良いPython(2.7)ライブラリはありますか?
解決
私はあなたが完全に吹き飛ばされたデータベースを必要としないことに同意します あなたが望むのはアトミックファイルが書くことだけだと思われます. 。この問題を2つの部分、シリアル化/脱介入と原子執筆で解決する必要があります。
最初のセクションでは、 json
, 、 また pickle
おそらくあなたに適したフォーマットです。 JSONには、人間が読みやすいという利点があります。これがあなたが直面している主な問題のようには見えません。
オブジェクトを文字列にシリアル化したら、 次の手順を使用して、単一の同時ライターを仮定して、原子的にディスクをディスクにするファイルを書きます (少なくともPOSIXでは、以下を参照):
import os, platform
backup_filename = "output.back.json"
filename = "output.json"
serialised_str = json.dumps(...)
with open(backup_filename, 'wb') as f:
f.write(serialised_str)
if platform.system() == 'Windows':
os.unlink(filename)
os.rename(backup_filename, filename)
その間 os.rename
ISは既存のファイルを上書きし、POSIXでアトミックです。これは悲しいことにWindowsではそうではありません。 Windowsには、その可能性があります os.unlink
成功しますが os.rename
失敗します。つまり、あなたが持っていることを意味します backup_filename
といいえ filename
. 。 Windowsをターゲットにしている場合、の存在をチェックしているときにこの可能性を考慮する必要があります filename
.
複数の同時作家の可能性がある場合は、同期構造を考慮する必要があります。
他のヒント
まあ、あなたは私たちが基本的にデータベースについて話していることを知っているので、非常に単純なものではありますが、おそらく私があなたが見ていることを提案することに驚かないでしょう sqlite3 モジュール。
人間の読み取り可能な要件の理由はありますか?
シンプルなデータベースソリューションについては、SQLiteを見るか、オブジェクトをシリアル化してディスクに書き込む簡単な方法でピクルスで見ることをお勧めします。どちらも特に人間は読みやすいものではありません。
他のオプションはJSON、またはあなたが示唆したXMLです - 組み込まれたJSONモジュールを使用して、オブジェクトをシリアル化してからディスクに書き込みます。起動したら、そのファイルの存在を確認し、必要に応じてデータをロードします。
から ドキュメント:
>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)
{
"4": 5,
"6": 7
}
あなたのデータは小さいと言ったので、私は簡単な解決策を持って行き、 ピクルス モジュールでは、Pythonオブジェクトをラインに捨てることができます とても簡単に.
次に、aを設定します スレッド これにより、定義された時間間隔でオブジェクトをファイルに保存します。
「図書館員」の解決策ではありませんが、あなたの要件を理解している場合は、実際に必要としないほど簡単です。
編集:あなたは、書き込み自体の間に問題が発生し、効果的に原子トランザクションになっているというケースをカバーしたいと述べました。この場合、従来の方法は「ログベースの回復」を使用することです。本質的には、「書き込みトランザクションが開始された」と書かれ、「Write Transaction comitted」という記述が完了したときに記録を記録しています。 「開始」に対応する「コミット」がない場合、ロールバックします。
この場合、SQLiteのような簡単なデータベースを使用する方が良いかもしれないことに同意します。それはわずかな過剰かもしれませんが、一方で、自分でAtomicityを実装することは、ホイールを少し再発明しているかもしれません(そして、私はあなたのためにそれを行う明白なライブラリを見つけられませんでした)。
craftyの方法を進めることにした場合、このトピックについては、Silberschatzのオペレーティングシステムの本のプロセス同期章「Atomic Transactions」の下で説明されています。
非常にシンプルな(「トランザクションで完璧ではない」かもしれませんが)代替手段は、毎回新しいファイルに記録することです。各ファイルにチェックサムを追加して、壊れているかどうかを自動的に判断することもできます。