2010-11-24 11 views
2

私はPython(2.7)スクリプトをサーバーとして動作させるため、非常に長い時間実行されます。このスクリプトには、クライアントの入力に基づいていつでも変更できる値を追跡するための値が用意されています。 、メモリを除いて(私はしかし私が欲しいそれを更新させる -長時間実行されるPythonスクリプトのファイルと同期したメモリ内データの保持

は、私が理想的に後だと、(JSON、基本的なタイプdictlistunicodeintfloatの値を持つ)Pythonのデータ構造を保つことができるものです人間が読める形式でこのデータを最新の状態に保ちながら、電源プラグが引っ張られたとしても、サーバはただ起動して同じデータを継続することができます。

私は基本的にデータベースについて語っていますが、私が保管しているデータは非常にシンプルで、たいてい1kB未満である可能性があるので、私は可能な限りシンプルなソリューションを探しています説明されたデータの完全性と私。このようなことをさせる良いPython(2.7)ライブラリがありますか?

+1

のMemcachedまたはRedisの程度はどのようのConfigParserモジュール – Falmarri

+0

を見上げて? – slezica

+0

デーモンはオプションではないので、私はそれが自己完結型であることを望んでいます。 – Blixt

答えて

2

私はあなたが完全に吹き飛ばされたデータベースを必要としないことに同意します。あなたが望むのは、すべてアトミックファイルがです。この問題は、シリアライゼーション/デシリアライゼーションとアトミック・ライティングの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は既存のファイルを上書きし、POSIXでは不可分ですが、これは悲しいことですがWindowsではそうではありません。 Windowsでは、成功しますが、os.unlinkos.renameはあなただけbackup_filenameなしfilenameを持っていることを意味し、失敗する可能性があります。 Windowsをターゲットにしている場合は、filenameの存在を確認するときにこの可能性を考慮する必要があります。

つ以上の同時ライターの可能性がある場合は、同期構造を検討する必要があります。

+0

Sweet!あなたは正しい、それは私が探していたものだった。私は持ち去られ、私の質問を必要以上に一般的にしました。 – Blixt

+0

これはアトミックではありません。 1つはファイルロックがありません。 2つのクライアントが同時に接続すると、未定義の結果が得られます。クライアント1またはクライアント2の変更が失われるか、またはインターリーブされる可能性があります。名前を変更する前にランダムではあるが一時停止するこのスクリプトの2番目のバージョンを作成し、その後両方のバージョンの複数のインスタンスを同時に実行し、アトミック性の欠如を目撃してください。 OPはオブジェクト・パーシスタンス・レイヤーを要求し、*これは受け入れられた答えですか? –

+0

@Jesse Dhillon合意した、これは複数の作家の可能性のもとでは原子的ではありません。私はOPが望んでいたとは信じていませんが、その質問は多分不正確に表現されていたことに同意します。 – fmark

4

私たちは基本的にデータベースについて話していますが、非常に単純ですが、sqlite3モジュールを見ることをお勧めします。

+0

あなたは正しいです。 :)私はそれを考慮していますが、データの整合性を保証できるさらに簡単なソリューションがあれば好きです。人間が読める形式でデータを保存すると、巨大なボーナスになります(もちろん、書き込みはずっと効率が悪くなりますが、書き込みは比較的少なく、あまり頻繁ではないので、それで生きることができます)。 – Blixt

+0

@Blixt、まあ、私は*データの完全性を保証することができる*よりシンプルなソリューションは知らないし、人々はXML対応のデータベースカラムでかなりの時間をかけてやってみようとしている。それほど単純ではありません。たぶんあなたのデータに実行されたすべての操作の人間が読める(XMLなどの)*ログ*を保持し、そのログを再生するコードを書く必要があります。 –

+1

@Blixt:代わりに保存しないでください毎分の設定ファイル?そうすれば、書き込み中にサーバーが消滅した場合、1分前からデータが取得されます。 – katrielalex

0

ACIDの保証を提供するデータベースの実装方法を尋ねていますが、既製品を使用できない理由はまだありません。 SQLiteはこの種のものには完璧であり、あなたにそれらの保証を与えます。

ただし、KirbyBaseがあります。私は決してそれを使用していないと私はそれがACIDの保証を作るとは思わないが、あなたが探しているいくつかの特性があります。

+0

私はACIDのすべての要件を実行する必要はありませんSQLiteを使用していないということは、これが本質的には設定ファイルだけであり、破損していないことを確かめたいからです。人間が読み取り可能な設定ファイルが望ましいです。 :) – Blixt

+0

設定ファイルは通常、人身売買の対象とはならず、変更は文書化されており、意図的です。常に変更されている設定ファイルがある場合は、システムの設計に関する質問をします。ところで、私はKirbyBaseに言及するために私の答えを変更しました。完全なACID準拠を必要としない場合は、これが私が賭けるベストな答えです。 –

+0

基本的には、クライアント側のサーバー側の構成です。クライアントは、永続的な状態なしで愚かです(彼らはサーバーに依存しています)。クライアントは何かの名前を更新したいかもしれません、そして、それはこの設定に保存されるべきです。だから私は、それはデータベースでなければならないという点を除いて、設計上の誤りはないと信じていますが、その場合、私はSQL実装ではなく、キーバリューストアを探しています。しかし、やはり、私はデータが壊れていないことを保証する必要があります.dbの実装には他に何もありません。 – Blixt

2

人間が判読できる要件の理由は何ですか?

シンプルなデータベースソリューションの場合はsqliteを、オブジェクトをシリアル化してディスクに書き込むシンプルな方法の場合はpickleをお勧めします。しかし、どちらも特に人間が読むことはできません。

その他のオプションは、JSONまたはXMLです。組み込みのjsonモジュールを使用してオブジェクトをシリアル化し、ディスクに書き込むことができます。起動時に、そのファイルの有無を確認し、必要に応じてデータをロードします。 docsから

>>> import json 
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4) 
{ 
    "4": 5, 
    "6": 7 
} 
+0

ええ、私はJSONモジュールについて知っていて、それを使用していることは間違いありませんが、通常のファイル書き込み中にサーバーが死んでも、すべてのデータを失う危険はありませんか?基本的には高度な設定ファイルなので、サーバが動作していない間に任意のテキストエディタで変更できるようになります。また、構成を更新するためにSQL文を実行することで、過度の過労を感じるだけです。 – Blixt

+0

古いファイルを上書きしないでください。書き込みごとに新しいファイルを作成し、不要な古いファイルは削除してください。次に、最新のファイルの整合性をチェックし、チェックに失敗した場合は前のファイルにフォールバックする方法が必要です。 –

+0

また、dbをラップしてsqlを処理する様々なORMライブラリを見てください。たとえば、次の例を参照してください。http://www.sqlalchemy.org/docs/orm/tutorial.html#creating-table-class-and-mapper-all-at-once-declaratively –

1

あなたのデータを述べたが小さいので、私はシンプルなソリューションで行くとあなたがラインvery easilyにPythonオブジェクトをダンプすることができますpickleモジュールを、使用したいです。

次に、指定した時間間隔でオブジェクトをファイルに保存するThreadを設定します。

「ライブラリ」ソリューションではありませんが、要件を理解していれば、実際には必要ないほど簡単です。

EDIT:書き込み自体の間に問題が発生した場合、効果的にアトミックトランザクションにするケースをカバーしたかったとお伝えしました。この場合、伝統的な方法は「ログベースの回復」を使用することです。これは基本的にログファイルに "write transaction started"と書いたレコードを書き込んだ後、完了したら "write transaction comitted"と書いています。 「開始済み」に対応する「コミット」がない場合は、ロールバックします。この場合

は、私はあなたがSQLiteのような単純なデータベースを持つ方が良いかもしれないことに同意します。それは少し過度のかもしれませんが、一方で、あなた自身の原子性を実装することは、ホイールを少し改革するかもしれません(そして私はあなたのためにそれを行う明白なライブラリを見つけませんでした)。

あなたは狡猾な道を行くことに決めるならば、このトピックはセクション「アトミック・トランザクション」の下で、Silberschatzのオペレーティングシステムブックのプロセス同期の章に覆われています。 1が破損した場合、あなたが歴史を持つように

(多分「トランザクション完璧」ではないが)非常に単純な代替手段は、単に新しいファイルにすべての時間を記録することです。各ファイルにチェックサムを追加して、ファイルが壊れているかどうかを自動的に判断することもできます。

+0

ええ、私はおそらく行くでしょう'' pickle 'の上に '' json''を付けていますが、私はそれを考慮しています。私の唯一の心配は、単純なファイル操作を使用するだけでは、サーバーが書き込み中に消滅した場合にファイルが壊れる危険性があります。 (非常にありそうもないが、私がカバーしたい場合)。 – Blixt

+0

私の編集を確認してからD = –

関連する問題