2

PHPからPython+Djangoに切り替えて、PHPの「配列キャッシュ」に相当するものを探しています。

非常にまれにしか変更されないが非常に頻繁にアクセスされる「カテゴリ」のようなDBからの小さなデータセットの場合、配列キャッシュを使用していました。

http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/

その概念は、カテゴリのツリーを使用してPHPソースを生成することであり、オペコードをオンにすると、アプリケーションソースにデータを埋め込むように機能していました。これは想像できる最速のキャッシュであり、大きな負荷に非常に役立ちました。

Djangoマニュアル(https://docs.djangoproject.com/en/1.4/topics/cache/)には次のように記載されています。

Djangoで利用できるキャッシュの中で群を抜いて最も速く、最も効率的なタイプのMemcached。

したがって、質問は次のとおりです。

  • Pythonの辞書/リストを使用して.pyファイルを生成することは意味がありますか?
  • これはMemcachedよりも高速ですか?そうでない場合はなぜですか?
  • これの既知の実装はありますか?
  • PythonにはPHPのvar_export()関数のようなものがありますか?

編集:

回答で指摘されているように、repr()を使用できます。これは簡単にベンチマークできるため、簡単なベンチマークを作成しました。

https://github.com/fsw/pythonCachesBenchmark

私のローカルマシンでのこれの出力は次のとおりです。

FIRST RUN
get_categories_from_db
6.57282209396
get_categories_from_memcached
(SET CACHE IN 0.000940)
4.88948512077
get_categories_from_pickledfile
(SET CACHE IN 0.000917)
2.87856888771
get_categories_from_pythonsrc
(SET CACHE IN 0.000489)
0.0930788516998
SECOND RUN
get_categories_from_db
6.63035202026
get_categories_from_memcached
4.60877108574
get_categories_from_pickledfile
2.87137699127
get_categories_from_pythonsrc
0.0903170108795

get_categories_from_pythonsrcは、私が話していたPHPのarraycacheの単純な実装です。

def get_categories_from_pythonsrc():
    if not os.path.exists('catcache.py'):
        start = time.time()
        f = open( 'catcache.py', 'wb' )
        categories = get_categories_from_db()
        f.write('x = ' + repr(categories))
        f.close()
        print '(SET CACHE IN %f)' % (time.time() - start)
    import catcache
    return catcache.x

これは私の単純なpickledfileキャッシュの実装です。

def get_categories_from_pickledfile():
    path = 'catcache.p'
    if not os.path.exists(path):
        start = time.time()
        pickle.dump( get_categories_from_db(), open( path, 'wb' ) )
        print '(SET CACHE IN %f)' % (time.time() - start)
    return pickle.load(open( path, 'rb' ));

完全なソース:

https://github.com/fsw/pythonCachesBenchmark/blob/master/test.py

後で「Djangoの低レベルキャッシュAPI」をこのベンチマークに追加して、それらが何であるかを確認します。

だから私の直感が示唆したように、Python .pyファイルに辞書をキャッシュするのが私が得ることができる最速の方法です(cPickle +ファイルよりも30倍以上速い)

言ったように、私はPythonを初めて使用するので、おそらくここで何かが足りませんか?

そうでない場合:なぜこのソリューションは広く使用されていないのですか?

4

2 に答える 2

1

Python には、ここで機能する可能性のあるソリューションがいくつかあります。

  • Memcached (ご存じのとおり)、
  • ピクルス(ブレンダーが述べたように)-もちろん、たとえば. Memcached、
  • いくつかの他のキャッシング (例: ローカル メモリ用) & シリアライゼーション (例: simplejson) ソリューション、

一般pickleに非常に高速で (cPickleさらに速度が必要な場合に使用します)、Python では次のようなものは必要ありませんvar_export()(ただしrepr()、変数がプリミティブ型の場合、有効なリテラルを持つために on を使用できます)。Python のほうが PHPpickleのほうに似ています。serialize

あなたの質問はあまり具体的ではありませんが、上記はあなたにいくつかの洞察を与えるはずです. また、PHP と Python には異なる哲学があるため、同じ問題に対する解決策が異なって見える場合があることも考慮する必要があります。この特定のケースpickleでは、モジュールが問題を解決するはずです。

于 2013-02-05T20:57:29.970 に答える
1

もう 1 つのアプローチがあります。gevent のような ASYNC サーバーを使用して、グローバルな名前空間にライブ オブジェクトを配置できます。
このようなワークフローにどれだけ精通しているかはわかりませんが、Apache/php の「各リクエストはむき出しで始まる」とは異なります。

基本的に、アプリケーションをロードし、それを使用してリクエストを処理します。常に生きていて、リクエストがなければ眠っています。データベースから「カテゴリ」をロードしたら、それらをグローバル変数またはいくつかのモジュールに保存します。

WSGI インスタンスを起動して app という名前を付けたとします。その後、そのアプリに辞書を置いて、そこにキャッシュを保存できます。そのため、シリアライゼーションやネットワーク プロトコルはなく、すべてのデータは RAM で直接利用できます。

EDIT1:グローバルを頻繁に使用しないでください。これは、global名前空間に何かを保存しても問題ない非常にまれなケースの1つにすぎません(私の意見では)。

于 2013-02-05T22:22:34.990 に答える