スキップしてメイン コンテンツに移動

[Python][Google App Engine]db.Modelのput/getで勝手にmemcacheを使うよう拡張してみた

GAEを使う必ずみんな意識するのがDataStoreへのアクセスをいかに減らすか。
それすなわちキャッシュの使い方なり!

と考えているわけですが、やることなんて以下の2点だと思います。

・Model.put()するときにはmemcache.set()しろ
・Model.get()するまえにmemcache.get()しろ

そこで、db.Modelを拡張しました。
まず、ModelAbsというdb.Modelを継承した中間のクラスを作って。

==========
class ModelAbs(db.Model):
    def put_with_cache(self,key_name):
        self.put()
        memcache.set(key=key_name,value=self)
        return self.key()
    @classmethod
    def get_with_cache(cls,key_names,**kwargs):
        if isinstance(key_names,list) == False:
            key_names = [str(key_names)]
        models = list()
        for key_name in key_names:
            ent = memcache.get(key=key_name)
            if ent == None:
                ent = cls.get_by_key_name(key_names=key_name)
                memcache.set(key=key_name,value=ent)
            models.append(ent)
        if len(key_names) > 1:
            return models
        else:
            return models[0]
==========

そのModelAbsを継承したエンティティのクラスを作りました。

==========
class SPOTS(ModelAbs):
    update = db.DateTimeProperty(required=True)
    USDJPY = db.StringProperty(multiline=False)
    EURJPY = db.StringProperty(multiline=False)
    EURUSD = db.StringProperty(multiline=False)
    AUDJPY = db.StringProperty(multiline=False)
    GBPJPY = db.StringProperty(multiline=False)
    NZDJPY = db.StringProperty(multiline=False)
    CADJPY = db.StringProperty(multiline=False)
    CHFJPY = db.StringProperty(multiline=False)
    HKDJPY = db.StringProperty(multiline=False)
    GBPUSD = db.StringProperty(multiline=False)
    USDCHF = db.StringProperty(multiline=False)
    ZARJPY = db.StringProperty(multiline=False)
==========

基本的にdb.Modelのkey_nameでの読み書きになります。

==========
class MainHandler(webapp.RequestHandler):
    def get(self):
        now = datetime.datetime.now() + datetime.timedelta(hours=9)
        str_now = datetime.datetime.strftime(now,'%Y%m%d%H%M')
        key = 'SPOTS:'+str_now
        rate = commons.GetCurrentRate()
        spot = models.SPOTS(key_name=key,
                            update=now,
                            USDJPY = rate['USDJPY'],
                            EURJPY = rate['EURJPY'],
                            EURUSD = rate['EURUSD'],
                            AUDJPY = rate['AUDJPY'],
                            GBPJPY = rate['GBPJPY'],
                            NZDJPY = rate['NZDJPY'],
                            CADJPY = rate['CADJPY'],
                            CHFJPY = rate['CHFJPY'],
                            HKDJPY = rate['HKDJPY'],
                            GBPUSD = rate['GBPUSD'],
                            USDCHF = rate['USDCHF'],
                            ZARJPY = rate['ZARJPY'])
        ds_key = spot.put_with_cache(key_name=key)
        entity = spot.get_with_cache(key_names=key)
        self.response.out.write(str(key)+'<改行>')
        self.response.out.write(str(ds_key)+'<改行>')
        self.response.out.write(str(entity.key())+'<改行>')
        self.response.out.write(str(rate))
==========

これでたくさんのif文を書かずにシンプルにキャッシュが利用出来るようになりました。

コメント

このブログの人気の投稿

[Python]redis-pyでRedis Pub/Sub実装

前から面白そうと思っていたRedisのPub/Sub機能。 redis-pyでどう実装すれば使えるか確認してみた。 ■Pub/Subについて http://ja.wikipedia.org/wiki/出版-購読型モデル ■pub.py from redis import StrictRedis def publish(channel,msg): """ redis-pyにはPUBLISHするためのメソッドがないので、 Redisのコマンドをそのまま実行する為のクラスを使う。 """ sr=StrictRedis() """ 第1引数にRedisのコマンド、第2引数以降は そのコマンドの引数をそのままセット """ sr.execute_command("PUBLISH",channel,msg) if __name__=="__main__": # チャネル"hoge"に"Hello"というメッセージを出版(Publish) publish("hoge","Hello") ■sub.py from redis import Redis def listen(channel): r=Redis() ps=r.pubsub() ps.subscribe(channel) while True: for i in ps.listen(): print i["data"] if __name__=="__main__": # チャネル"hoge"を購読(Subscribe) listen("hoge") ■実行方法・実行結果 (ターミナル1-準備) [user@localhost ~]# python sub.py 1 # => チャネ

[OS]VirtualBoxでCentOS6.5(x86_64)がKernel panicを起こした

完全に対処療法。 恥ずかしながら自分では原因がわかっていない。 忘れないようにメモしておく。 いろいろ設定したあと、何度目かの再起動のタイミングでKernel panicが発生して起動しないという事象が発生。 こちらの方法でなんとか起動させて。 [CentOS] SELinux 無効化後のカーネルパニック http://kuni255.blogspot.jp/2013/04/centos-selinux.html こちらの通り、/boot/grub/grub.confに設定を追加。 Kernel panic – not syncing: Attempted to kill init! http://h2np.net/mynotebook/post/130 設定変更後、以下の操作をそれぞれ10回ほど試した限りでは再発していません。  (1)halt+起動 (2)reboot 追記:と思ったらまた発生した。なんかもう解決できる気がしない。

[Python]システムトレード環境

最近、システムトレードをしている。 日本株は、自動売買までは実現できていないが、トレンド分析くらいはできるようになっている。 とりあえず、現時点の環境を整理しておきたい。 ■日本株 H/W:さくらVPS(2GBだったかな?) OS:CentOS6.4(x86_64) 言語:Python DB:SQLite3 データソース: http://www.data-get.com/main/ (有料) データ種別:株価データ、銘柄情報データ、分割併合データ ■FX H/W:DELL T100(6年前のもの)+CPU4コアに換装済+メモリ8GB化済 OS:Windows 7 64bit プラットフォーム:MetatTrader 4 言語:MQL4 取引業者:Alpari Japan ■クライアント H/W:MacBook Pro 13インチ(2010-Mid) 特に不満はないけど、さくらVPSが高い。 自宅のT100は古いけど重い処理をさせるわけじゃない。 そのうちさくらVPSから自宅PCのVirtualBoxかなんかの仮想環境に引っ越す可能性もある。 こんなところ。