2011-07-31

Plone & Zope / メモリ関連のメモ

PloneをZEO化して少し幸せになったのもつかの間…。

プロセス起動直後は問題ないとして、時間がたつとプロセスが利用するメモリがどんどん増えていきます。よくよく考えると、このような状態の模様。

  • Ploneの使うZODBはトランザクションログも同じファイルに書き出すため、放っておくとどんどん大きくなる。
  • ZODBが大きくなると、その分プロセスに使われるメモリも増えてくる。(実メモリで、ZODBのファイルサイズ分くらい使う)
  • ZODBはパックすればサイズは小さくなるが、プロセスは再起動しないとメモリを解放してくれないっぽい。
    本来はGCがきちんと働いてメモリが解放されるはずですが、その通りにはいかないようです。(後述)
  • キャッシュを利かせる調整をしているため、ユーザのアクションが増えるにしたがってキャッシュに使われる分だけプロセスの消費するメモリも増える。

メモリを解放するには、どうやらプロセスを再起動というのが素直な方法の模様。(まあ、APサーバとしては良くある話のようです)

ただ、DBのパックは毎日行ったほうが良い、という他には、あまり情報を見たことが無かったので、”Zope, process, restart” なキーワードで検索をしてみました。

すると、案の定 plone.org にそれらしきエントリが…(^^;

ざっと読んだ限り、冒頭の説明はこんな感じ。

* * *

Zopeを定期的に再起動させる必要はないが、サイトのサイズや動作によっては、再起動がベストプラクティスとなることも考慮すべき。

なぜなら、ZopeはPythonのプロセスとして動いているので、状況によってはホストシステムの利用可能なメモリを使い切ってしまう可能性もある。

これはPythonのバグではなく、Pythonのコードのせいというわけでもない。Pythonがreference-countingなガベージコレクションの構造を持っている点が大きい。

本来は参照されなくなった、削除されたオブジェクトはGCの対象になって、メモリの増加も抑えられるはず。しかし、状況によっては、オブジェクトが利用されているかどうかを判断できないことがある。また、相互参照しているオブジェクトが多ければ、どうやって適切な順番でオブジェクトを削除していいか判断が付かないということが起こり得る。

こうなると、オブジェクトの破棄が行われず、占有されてしまったメモリが解放できないので、プロセスを停止してPythonのメモリをいっさいがっさいクリーンアップさせるしかない。

(こういう動作を妙に思うのであれば、Pythonの__del__ method, か、gc module のドキュメントを読むべし)

結果的に、長期間稼働しているZopeのプロセスは、実際のアクティビティに必要としている以上の、非常に大きなメモリを占有してしまうことがある。そして、メモリを解放するためには、プロセスを再起動させるしかない。

* * *

…とまあ、やはりOSの状況を確認しながら、再起動は必要になってくるようです。

あとは再起動の方法、その他考慮すべきことが書かれています。

幸い、ZEOでクラスタ化したので、うまく負荷分散させながら順番にプロセスを再起動していけば、サービス停止を最小限に抑えられそうです。確かにこの点で、切り替えて良かった…と思います。

なお、ZEOクライアント(Zopeのプロセス)だけを再起動すればよく、ZEO Server(DB側) はメモリを占有することはあまりないそう。

ただし、大きく膨れてしまったZODBを pack する際には、非常に大きなメモリを必要とするらしいので、定期メンテナンスを行う時はZEO Serverのプロセスの状況も鑑みて、再起動を検討するほうがよさそう、とのこと。

この辺は、こまめにpackすれば大丈夫なのかもしれませんが、結局は良くOSの状況、パフォーマンスを監視し、自分の判断で再起動を実施するのばベストのようです…。

将来のバージョンでは、再起動も減らせるだろうと述べられていますが、Ploneのバージョン4までは、やはりPython2.4ベースなので、このエントリに従った方がよさそうです。

やっぱり、運用しないと判らないことってあるんですね。プログラムの知識とか本当に何ともし難いのですが、このへんの体験談が、何かのお役に立てれば幸いです…。

2011-07-29

東京電力電力供給状況API と QlikViewでチャートを表示

日本だと、まだ QlikView の話題が少ないなあと思うこのごろ。

Personal Editionは無償という状況ですが、やはりライセンスを持っていないと、他人とデータ・レポートがやりとりできないのは厳しいのかもしれません。

いろいろグラフ用のオブジェクトがあるのにちょっと勿体ないなあ~と考えていたので、周りにUIの紹介をするために、簡単なサンプルを作ってみました。

今回試したのは、東京電力電力供給状況API からデータを取得し、メータ表示するというものです。

APIはいろんな方が創られているんですが、QlikViewが解析できるフォーマットは、CSVかXML。JSONはまだQlikView自体では解析できません。

そこで、読み込むタイミングの最新のデータはAppspotのAPIのうちCSVで提供されているデータを使い、1時間あたりの使用率はYahoo!のAPI(2番目)のものを利用させていただくことにしました。

  1. http://tepco-usage-api.appspot.com/
  2. http://developer.yahoo.co.jp/webapi/shinsai/setsuden/v1/latestpowerusage.html

 

tepco-usage-qlikview

tepco-usage-qlikview

作った画面はこんな感じ。

ブラウザで表示できるんですが、やっぱり画面リロードしたらデータが更新される、もしくは定期的に更新してくれるという代物ではないのがちょっとさびしい(^^;

それでも、UI中心のプログラマじゃなくても、こういったタイプのグラフを使ってデータを割とすぐに表示できるのはQlikViewのいいところですね。

* * *

ちなみに、データはコマンドラインで定期的に更新(リロード)処理をかけています。

QlikViewはサーバがあればサーバのスケジューラを利用できますが、私はクライアントで閉じたかったので、Jenkinsを利用してバッチジョブ化しております。

過去のデータを蓄積したり、気温と連動して表示していけば、何曜日の何時が使用量が高い、とかが見えてきて面白いのですが、まだそこまでは作り込めていません。

JSONのフォーマットも解析できるようになってくれるといいんだけどなあ。

参考までに、ロードスクリプトはこんな感じです。

※YahooのAPIには開発者用のIDが入ります。

-- 1時間あたりの平均はYahoo APIから

ElectricPowerUsage:
LOAD
    Area,
    Usage,
    Capacity,
    Date,
    YEAR(Date) AS target_year,
    MONTH(Date) AS target_month,
    DAY(Date) AS target_day,   
    Hour,
    [Capacity/unit],
    [Usage/unit]
FROM [
http://setsuden.yahooapis.jp/v1/Setsuden/latestPowerUsage?xxxxxxxxxxx (XmlSimple, Table is [ElectricPowerUsage]);

-- 読み込み時の最新は、tepco-usage-api.appspot.com のCSVデータから

CurrentData:   
LOAD @1 as CurrentTime,
     @2 as CurrentUsage,
     @3 as CurrentCapacity
FROM
[
http://tepco-usage-api.appspot.com/quick.txt]
(txt, codepage is 932, no labels, delimiter is ',', msq);

2011-07-24

Cacooのステンシル使ってみました。

お仕事でFlash(Flex)アプリをちょっとやっていたので、そもそもFlashベースらしいCacooには親しみを感じていたんですが、いつの間にか、Cacoo大好き人間になってしまいました :)

そうして、今回は初めてのCacooの話題になります。

* * *

先日、ステンシル機能がリリースされたということで、さっそく試してみることにしました。(使う当てはないのですが…)

何にしようかな~と思って、最初に登録したのは、アイコン替わりにしている、うさぎの絵です。

Cacooのステンシルの中には、人物やフェイスマークなど、グラデーションが綺麗で可愛いものも多いので、わたしもそれに近いものが登録できるといいな…と思った次第。

イラストレータで作成し、SVGに変換し、登録!とまでは割とスムーズに進んだのですが、Cacoo上に上げてみると、色味が変わったり、透明度指定していたものが無効になっていたり、グラデーションが消えてしまった部分がありました。

この件については、Cacooの方が教えて下さり、のちほどCacooのBlogでも作成時の注意が書かれていたので、納得。ありがとうございます。

それでも、やっぱり『自分で書いたものを取り込めるなんて、凄い~!』と思うばかりでした。

redbull

さて、うさぎに続いて、何がいいかしら…と思って、取り上げた素材がRed Bull…(^^;

どうもIT系の皆さんに人気のようらしく、最寄りのコンビニでもドリンク剤コーナーに並んでいたのを思い出し、さっそく描いてみることに。

ただ、わたしはイラストレーターはあまり使いこなせていないので、どうやったら空き缶や円筒形のものが描けるか、まったく見当が付きません。(実は、普段はFlashの鉛筆ツールで描いて、イラストレーター形式に変換するという方法を取っているのでした)

「イラストレーター、缶」というキーワードで検索してみると、有難いことに、3Dのフィルタを使うという技を発見!

半信半疑でやってみると、ホントに缶らしくなるではありませんか!

そして、調子に乗ってラベルも書き起こしてみると、やはりうまく3D風の缶に貼り付けが出来た!

 

harituke

 

「これはイケる~!」と大喜びでSVGに変換し、Cacooに取り込んでみると……。

……『重い』のです。

よーくデータを見てみると、3Dの陰影と曲線を描くために、線のデータがびっしり詰まっているんですね。お手軽にしかも綺麗に出来た、と思ったけれど、ステンシルとしては使え無さそう…。

パスの単純化をすれば軽くなるかな、と思いましたが、それでもあまり変わりません。(良い方法があればどうか教えてくださいませ)

結局、楕円と長方形を組み合わせて円柱を描き、グラデーションを付けてそれっぽくする、という方法にしました。

* * *

わたしの描いたものはあまり綺麗ではないし、大人気のRedBullのことですから、おそらくどなたかが今後ステンシル化してくれるのではないでしょうか(^^;

それにしても、久しぶりにBlogを書いてみる気になったのですから、Cacooって凄い!

もっと上手に使えるように、がんばります~。

 

 

2011-07-19

Jenkinsのポート33848を確認してみる

JenkinsのRemote Access APIを利用しようと思い、JenkinsのWikiを見直したところ、内容がだいぶ更新されていました。
APIのサポート情報にPythonが追加されていたり、パラメータ付きジョブの実行の説明が追加されていました。


* * *


勉強がてら、日本語版の方のWikiを修正させていただいたのですが、JenkinsがUDPポート33848でリッスンしているという説明があったので、せっかくなので確認してみることにしました。

さて、相手はTCPではなくUDPなので、telnetは使えなさそう…。(もしオプション指定で使えるなら、どなたか教えて下さい!)

ちょっと検索したところ、hping というコマンドが使える模様。
わたしの環境はCentOS(実は、RPMを利用したところちょっと難があった…)なので、yum installでひとまず追加。
オプションが色々あるのですが、こんな指定をしたところ、なるほどJenkinsからのレスポンスが確認できました。
# hping localhost -2 -J -p 33848
HPING localhost (lo 127.0.0.1): udp mode set, 28 headers + 0 data bytes
len=196 ip=127.0.0.1 ttl=64 DF id=0 seq=0 rtt=408.2 ms

……………
ICMP Port Unreachable from ip=127.0.0.1 name=xxx.xxx.xxx
                E.......@...................E...
                ..@.@.<'.........8.;....<hudson>
                <version>1.418</version><url>htt
                p://xxx.xxx.xxx/</u
                rl><server-id>4bcf5847fc6bbbf4b5
                43095658affb98</server-id><slave
                -port>9999</slave-port></hudson>
認証に関しても、若干記述が追加されています。英語のコメントもたくさんついていたり、PythonのサンプルコードもPOSTされていました。
API経由での利用はまだ行っていないのですが、日本語版への反映も含めて、いろいろ試してみようと思っています。