2017年09月28日

最近のPython-dev(2017-09)

はてなブックマークに登録

バックナンバー: 8月号 | 6月号 | 5月号 | 4月号 | 3月号 | 2月号 | 1月号

今月は Sprint がありました。去年の Sprint はベータ版直前だったのでたくさんの実装が入りましたが、次の Python 3.7 のベータは来年のはじめなので、今回は実装よりも提案(PEP)が多めです。とても全部は紹介しきれない(そもそも一部を除いて議論を追えていない)ので、今月からは提案については受理されたものや受理間近のものだけ紹介していきます。

namedtuple 生成の高速化

bpo-28638: Optimize namedtuple() creation time by minimizing use of exec()

namedtuple という、タプルの要素に整数の添字ではなく属性名でアクセスできるようにするデータ構造があります。 例えば次のようにして使われます。

_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])

これは動的にクラスを作るのですが、そのためにクラス宣言の Python コードを文字列置換で生成し、 eval() することでクラスオブジェクトを生成していました。このメタプログラミングの方式は、リフレクション的な機能を使ってクラスを生成するよりも、何をやっているのかが判りやすいというメリットがあります。

しかし、通常のPythonのコードはバイトコードにコンパイルされて pyc ファイルにキャッシュされるのに対し、この方式ではクラスを生成するコードは都度コンパイルされてしまいます。そのため、 namedtuple をたくさん使っているモジュールの読み込みは遅くなります。

そこで、より一般的な type() 関数を使う方式で namedtuple が書き直されました。とはいえ、生成されたクラスのインスタンス生成速度に影響する __new__ メソッドだけは、性能を落とさずに完全な後方互換性を維持できなかったので、1関数だけのごく短いコードに対するevalはまだ残っています。それでも、CPythonでもPyPyでも数倍速くなっているので、namedtupleをたくさん利用するライブラリをインポートする時間が短縮されます。

その他、複数の namedtuple で作ったクラス間で共有できる部分を共有するなどの最適化が盛り込まれ、(インスタンスではなくて)生成されたクラスオブジェクトのメモリ使用量も削減できています。

なお、従来は生成されたクラスに ._source という属性があり、 eval 対象になったクラス定義のソースコードが入っていたのですが、今回の改良でなくなりました。

OrderedDict のコンパクト化

去年私が dict をコンパクト、かつ挿入順を維持する実装をしたのですが、まだ collections モジュールの OrderedDict は dict と別にキーの双方向リンクリストを持っていて、 dict の倍のメモリを利用します。

OrderedDict の典型的な用途は単に json などで順序を維持したいというものですが、その用途なら dict を使ったほうが、メモリ使用量は半分になり、構築も列挙も高速です。しかし、 dict の順序は実装依存であり、CPythonとPyPyは順序を維持するものの、それに依存するのはお行儀が悪いです。

そこで、OrderedDictをdictの構造をそのまま利用するように書き換えて見ました。メリットとしては典型的な操作の性能があれこれ上がっているのと、メモリ使用量が1/2に、そしてソースコードも1000行以上削ることができました。

しかし、デメリットとして OrderedDict と dict が密結合する(今は分離されているソースコードを1つにマージしてしまう)ことと、 OrderedDict だけに存在する move_to_end() というメソッドの速度が数割落ちています。他にも、要素の移動や追加削除の平均計算量は O(1) のままだけれども、最悪計算量が O(n) になってしまうようなパターンが増えている可能性もあります。

この部分のエキスパートである Raymond Hettinger さんは特に大きな書き換えに厳しい人なので、説得するには実装の磨き上げとより詳しい検証が必要です。多分 ISUCON 後になるけれど、 Python 3.7 に間に合わせたい。

PEP 539 v3: A new C API for Thread-Local Storage in CPython

Yamamoto Masayuki さんが活動されていた、スレッドローカルストレージを利用するCレベルの新APIの提案が受理されました。

旧APIはかなり古くからあるのですが、TLS key として int 型を使っていて、LinuxやメジャーなUnix、Windowsでは問題ないもののPOSIXには準拠していませんでした。そのためCygwinなどで問題が有ったらしいです。

PEP 557: Data Classes

主にデータの入れ物となることを目的としたクラスをより手軽に作れるようにするためのAPIが提案されています。

@dataclass
class InventoryItem:
     name: str
     unit_price: float
     quantity_on_hand: int = 0

     def total_cost(self) -> float:
         return self.unit_price * self.quantity_on_hand

のように宣言すると、

   def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0) -> None:
       self.name = name
       self.unit_price = unit_price
       self.quantity_on_hand = quantity_on_hand
   def __repr__(self):
       return f'InventoryItem(name={self.name!r},unit_price={self.unit_price!r},quantity_on_hand={self.quantity_on_hand!r})'

のようなメソッドが自動で生成されます。

namedtuple と目的が被っているものの、 namedtuple はタプルであるために一部の用途には向かない事があります。例えば immutable だとか、普通のタプルと比較可能であるなどです。

Data Class はタプルではなく、そのためより柔軟です。同一性でなく同値性による比較可能にするかどうかなどが選べます。構文も Python 3.6 からの新しいスタイルを活用したもので、例えば namedtuple だと独自のメソッドを追加するにはもう1段継承したクラスを作るなどの面倒があったのですが、こちらは上の例の total_cost() メソッドのように普通に書くことができます。

このPEPは受理一歩手前で、あとはもう名前を決めるだけです。個人的には Record がいいな。

PEP 552 -- Deterministic pycs

pyc ファイルには py ファイルのタイムスタンプが格納されていて、 py ファイルが更新されると自動的に pyc ファイルも作り直されるようになっています。

このためにpyファイルが同じでもpycはバイナリレベルでは一致しません。これが最近の ビルド再現性(Reproducible Builds) というプラクティスには都合がよくありません。 (Debian/Ubuntu では pyc はインストール後にビルドされますが、 pyc を一緒にパッケージに含めているディストリビューションもあります)

また、Bazelというビルドシステムでもこれは都合が悪いらしいです。

この PEP ではヘッダーの形式を追加し、従来通りのタイムスタンプ+自動ビルド方式の他に、pyファイルのハッシュ値を持つ事ができるようになります。この場合、 pyc を読み込むときに py ファイルのハッシュ値を計算するコストが気になるところですが、新しいヘッダはpy ファイルのハッシュをチェックして自動リビルドするか無条件に pyc を使うかを選択するフラグを持っています。

pyファイルをチェックしない方を選択した場合も、 import 時にチェックしないだけで、コマンドを使って明示的にチェックしたりリビルドすることはできます。なので root しか書き込めないディレクトリに Python やライブラリをインストールする場合など、ユーザーがうっかり py ファイルを変更する危険が無い場合は問題ないでしょう。

このPEPはAccept直前(他に意見がなかったらAcceptするよとGuidoが宣言中)です。なお、このPEPはファイルフォーマットレベルでの問題を修正するだけで、それ以外にも pyc ファイルが一定にならない実装上の理由は幾つかあります。しかしこのPEPがAcceptされたということは、 deterministic pyc をサポートするという方向性が決まったことでもあるので、実装面の課題も今後修正されていくと思います。

起動高速化

インタプリタの起動高速化は難しい問題なのですが、実際のアプリケーションの起動ではその何十、何百倍の時間が、ライブラリのロードに消費されています。

あるモジュールを import しても、そのモジュールの全部の機能を使うわけではありません。そのモジュールの中で、あまり使用頻度が高くないと思われる関数でだけ使われる依存関係は、モジュールの先頭ではなくその関数で import することで、アプリケーションの起動時間を減らすことができるかもしれません。

一方で、それは PEP 8 違反(明確な理由やメリットがあったら違反しても良いです)ですし、その関数の実行時間は若干遅くなってしまいます。だから、利用頻度が少なく、かつその利用頻度に比べて import が重いモジュールに絞って書き換えが進んでいます。

argparse が直接、間接的に import しているモジュールが減らされました。(マージ済み) https://github.com/python/cpython/pull/1269

functools の singledispatch でしか使われないモジュールを singledispatch 内に移動します。 (accept待ち) https://github.com/python/cpython/pull/3757

uuid モジュールが、 uuid1 のために libuuid や UuidCreateSequential をロードする処理が重いのでそれを遅延する提案。(これからレビューします)

https://github.com/python/cpython/pull/3684

また、重い import を見つけるために私がローカルで使っていた import に掛かる時間を表示するパッチを、だれでも(特にライブラリやフレームワークの作者が)簡単に使えるように -X importtime オプションとして提案しています。今はその出力フォーマットについて自転車置き場の議論をしています。 https://github.com/python/cpython/pull/3490

余談ですが、昔幾つかのサードパーティーライブラリの import 時間を調べて居た所、 Jinja2 の import がすごく遅いことに気づきました。

実は今年のはじめにメモリ使用量を解析していたところ、 Jinja2 は Python 3 ではユニコードのシンボルも(テンプレートエンジン内の変数名として)使えるようにしようと、シンボル名として有効な名前を表現する正規表現をかなり強引な方法で作っていたのを見つけて報告していたのですが、その正規表現のコンパイルが import 時に実行されていて遅かったのです。

すでに Jinja2 の開発ブランチではずっと良い実装に切り替わっているので、次の Jinja2 のリリースを楽しみにしています。

songofacandy at 18:52
この記事のURLComments(0)Python 
2017年09月26日

LVSの高負荷対策 その2 ~障害の再現とその原因~

はてなブックマークに登録

こんにちは。インフラ担当の岡村です。
LVSの高負荷対策 その1 ~障害発生~」の記事で、大量のSYNパケットを受信した際にロードバランサの再起動が発生したことと、その緊急の対策についてご紹介しました。
今回は、再現確認を行い判明した再起動の原因と、LVSに備わっている高負荷対策の機能についてご紹介します。

検証

前回ご紹介した通り、障害発生時のログからメモリ周りが怪しそうでした。 そこで、ロードバランサにSYNパケットを送り、メモリの使用量の推移を観察しながら、再起動が発生するかどうかを確認しました。

検証環境の構成は次のようになります。

検証環境の構成
dsas_lvs_test_environment

パケット送信用サーバを複数台、ロードバランサを1台、Webサーバを1台使用し検証を行いました。
ロードバランサの検証を行う上で、本番環境と同様にロードバランスの処理をさせたかったため、LVSに振り分け先のWebサーバのIPアドレスを複数登録しています。
DSASのロードバランサではDSR(Direct Server Return) 方式を採用しており、Webサーバからの戻りパケットはLVSを経由しません。本検証を行う上ではWebサーバはパケットを返す必要はないので、ロードバランサから振られたパケットはWebサーバでdropしています。
パケット送信にはhping3を使用しました。オプションが豊富で様々なパケットを送信することができます。今回は障害時に検出したパケットに似せて、次のコマンドでwindowサイズ0のSYNパケットをロードバランサのVirtual Service宛に大量に送信しました。

hping3 -S -w 0 “Virtual ServiceのIPアドレス” -p 80 --rand-source --flood

DSASのロードバランサは、64bitOSのものだけではなく、32bitOSのものが残っている状態でした。今回の問題が発生したのは32bitOSの方だったため、まず32bitOSで検証を行いました。

32bitOSでの検証

上述の通りhping3を使用して、複数のサーバからロードバランサに向けて一斉にSYNパケットを送信します。
SYNパケットが届くと、IPVS ( LVSのレイヤー4の負荷分散機能を提供するカーネルモジュール ) はSYN_RECV状態のエントリを作成します。そのためSYN_RECV状態のエントリがどんどん増加していき、それに伴いLowメモリの使用量が増加していきました。
Lowメモリの使用量の推移を確認したところ、パケット送信前の状態では約750MB あったLowメモリの空き容量は刻々と減少し、最終的に枯渇してカーネルパニックが起こり、再起動が発生しました。

Kernel panic - not syncing: Out of memory and no killable processes...

64bitOSではLowメモリの制限がなくなるので耐性は向上すると予想できます。しかしメモリが枯渇すれば同様に再起動が起こりそうです。64bitOSを使用して、もう少し詳しくロードバランサの挙動を追っていきます。

64bitOSでの検証

結論から言うと、IPVSのエントリが増加しメモリが枯渇すると、やはり再起動が発生しました。ログを確認してみると本番環境での再起動の時と同様、再起動の直前でoom-killerが多発しており、また、カーネルのバージョンの違いから若干出力は異なりますが、IPVSのメモリ割り当てのエラーが出ていました。

IPVS: ip_vs_conn_new(): no memory

本番環境で起きた再起動も、IPVSのエントリが増加することによるメモリ枯渇に起因すると考えて良さそうです。
負荷試験中のSYN_RECV状態のエントリ数と消費メモリの推移を確認し、グラフにしました。(グラフ1)
今回の検証で使用したサーバはメモリを8GB搭載しており、負荷をかける前のMemFree値がおよそ7GBであったことから、以下の全てのグラフの「消費メモリ」の値は、「 7GB - 観測したMemFree値 」で算出しています。

dsas_lvs_graph1

負荷をかけ始めてから約49秒で消費メモリが7GB、すなわち、8GBのメモリを使い切り、再起動が発生しました。
さて、IPVSの挙動を確認するため、先の試験より負荷を抑え、再起動が起きなかった場合のグラフを見てみましょう。(グラフ2)

dsas_lvs_graph2

およそ60秒間はエントリ数とメモリ消費量は増え続けますが、それ以降は一定の値で推移しているのがわかります。
これは、SYNパケットが届くとIPVSはSYN_RECV状態のエントリを作成しますが、SYN_RECV状態のままだと60秒でタイムアウトになり、エントリが削除されるためです。
今回の試験では一定の強さの負荷をかけ続けたため、60秒以降は「タイムアウトで削除されるエントリ数」と「新規に作成されるエントリ数」が釣り合い、一定になったと考えられます。
(ピークが60秒から少しずれているのは、複数のサーバからパケットを送って負荷をかけているため、それぞれのサーバで負荷の開始時刻の誤差があったためです)

対策について

64bitOSでも再起動は発生したものの、32bitOSの場合と比較すると大幅に負荷耐性が向上しました。32bitOSでLowメモリが制限されてしまっている環境の場合は、64bitOSに変更することで耐性を上げられます。その上でメモリを追加すれば更に負荷耐性が上がり、再起動の対策になりますね。
では、他に有効な対策はないでしょうか?
調べてみると、LVSは高負荷対策の機能をいくつか備えているようです。(参考)
今回は、そのうちの機能の一つであるdrop entry機能を使用してみたのでご紹介します。

drop entry 機能の紹介

IPVSのエントリをランダムに削除してくれる機能です。
SYN-RECV状態とSYNACK状態のエントリを削除するアルゴリズムは、毎秒IPVSのコネクションハッシュテーブルからランダムに選んだ範囲(全体の32分の1)をスキャンし、その中のSYN-RECV状態、SYNACK状態のエントリを削除する、というもののようです。
ESTABLISHED状態のエントリとUDPのエントリは共に、次の2つの条件を両方とも満たしている場合に削除される可能性があります。
・最後のパケットが届いてから60秒以上経過
・最初のパケットが届いてからの受信パケットの合計数が8以下
受信パケットが8以下の場合でも、受信パケット数が大きくなるに連れて削除される可能性は低くなるようです。

drop entryは、使用可能なメモリ量が設定した閾値を下回ったときに、自動で有効にすることが可能です。その場合は、以下に1(または2)を設定します。

/proc/sys/net/ipv4/vs/drop_entry

メモリの空きが閾値を下回ると自動的に値が2になり、機能が有効になります。
( 閾値を下回っていないときに、2を設定すると、自動で1になります。)
また、閾値によらず常にdrop entryを有効にしたい場合は、3 を設定します。
閾値は以下で設定可能です。

/proc/sys/net/ipv4/vs/amemthresh

単位は memory pageなので、例えばメモリが残り1GB(=1048576KB)を下回った時に有効にしたい場合は、"1048576KB÷(ページサイズの)4KB"を計算して、262144 を設定します。

drop entry有効時の動作確認

閾値を6GB,3GB,1GBとし、SYNパケットを送って負荷をかけたときの、SYN_RECV状態のエントリ数と消費メモリの値の推移をそれぞれグラフにしました。

dsas_lvs_graph3
dsas_lvs_graph4

負荷は上の64bitOSの検証で再起動を発生させたときと同じ強さなので、drop entryなしでは再起動してしまいます(グラフの青線)。しかし、drop entryを有効にすると、3つのどの閾値の場合も消費メモリを抑えることができ、再起動は起こりませんでした!
例えば閾値を3GBに設定したときの推移(グラフの黄線)を見ると、消費メモリが4GB、すなわち残りのメモリが3GBになった時点から、エントリ数とメモリ消費量の増加が緩やかになっているのがわかります。
閾値を大きくすればするほど、消費メモリの最大値は小さくなり、耐性が向上することも見て取れます。

ただ、drop entryを有効にすれば必ずしも再起動を防げるというわけではなく、負荷に対して閾値を小さくし過ぎると、例えば上の環境で閾値を150MBにすると、drop entryが間に合わず再起動が起きました。また、負荷と比較して搭載メモリが少ない場合は、drop entryを常に有効にしていてもメモリが枯渇する可能性がある点も注意が必要です。

しかし、メモリ増強などの追加投資なしで、すぐに耐性を上げることができるので、とても便利な機能です。
もちろんdrop entry有効時には、IPVSを経由するどの接続もエントリ削除の影響を受ける可能性がありますが、ロードバランサが落ちてサービス停止してしまうよりはずっと良いのではないかと思います。LVSを使用されている方は是非お試しください。

次回、LVSの高負荷対策 その3でも、引き続きdrop entryの検証結果を紹介しようと思っています。

okamura_h at 11:57
この記事のURLComments(0)lvs 
2017年09月21日

40年前の「子供の科学」誌との再会を通じて

はてなブックマークに登録

子供の科学」は株式会社誠文堂新光社様の発行する小中学生向けの月刊科学雑誌です。創刊は関東大震災の翌年 1924年(大正13年)とふるく、世代をまたいで読み継がれています。この記事をご覧になっている方の中にもかつての読者(現役の読者も?)が少なくないことでしょう。

手元では 1977年前後にこの「子供の科学」(以下 "同誌")を購読していました。それからずっと長い間忘れていたのですが、先日実家に残っていた当時の何冊かを見つけました。
懐かしい気持ちで久しぶりに 40年前の誌面を読み返したところ、子供と同じ目の高さで科学や技術、未来に向き合っていた当時の大人たちの懐の深さと真剣さを現在の年齢なりに強く感じました。商業誌である以上、誌面には小さな読者たちからの要望のいくばくかも反映されていたであろうことを考え合わせるとさらに興味ぶかく感じられます。

この機会に印象に残ったいくつかの記事を電子化しておくことにしました。その内容を「子供の科学」編集部様のご承諾のもとに紹介します。あわせて、40年を経た 2017年現在の誌面と 93年前の創刊号にも目を向けてみたいと思います。


1977年 第12号より

表紙

遺物の写真のまわりに 4つの記事のタイトルのみが淡々と並ぶシンプルな装丁。「マリモはどうして丸くなる?」という取り立てて派手さのないタイトルが堂々と表紙に据えられていることも印象的。

目次

同誌の内容は多岐に渡る。「原子力製鉄」という記事と「実用工作 ちりとり」という記事が何の違和感もなく共存していることに守備範囲の広さが感じられる。

「針のいらないレコードができた」

         :
もし, プレイヤーにレコードをのせ, 回転させるだけで, 針の付いたピックアップがないのに, 実際に演奏を聞くのと少しも変わらない, すばらしい音質(これを超ハイ・ファイと言います)で再生できたら, おそらくみなさんはびっくりさせられることでしょう.
         :
このレーザー光線による微小ビットの記録再生技術は, さらにいろいろな応用が考えられています.
 テレビに接続すると映像の出るレコードとか, 超長時間録音とか, 例えば100曲ほど入ったジュークボックスが, たった1枚のディスクでできるとか, あるいは楽器別に同時記録ができるマルチ・チャネル方式への応用など、研究者達の夢は限りなく広がっています.

PCM レーザサウンドディスク」は、コンパクトディスク(CD)が製品化されるよりも前に三菱電機ティアック東京電化の三社によって開発が進められていたディジタルオーディオシステム。音楽愛好者の重要な音源だった FM 放送の周辺で「PCM 録音」のキーワードが話題になり始めていた時分であり現在が過去の未来であることをあらためて感じさせられる。時代を経てアナログオーディオの価値が再認識された現代ではむしろ「針を使うレコード」のほうが新鮮で贅沢であることもまた興味深い。

関連記事

「自由に曲線が切れるカッター」

ナイフなどで紙や布を曲線に切る事は, たいへんむずかしい事です. この道具は, ゴムのローラーを利用して自由に曲線が切れるようにしたものです.
         :
ローラーが付いているので, 紙や布の上を自由に動かす事ができ, ジグザグにでも, 曲線状にでも切れるというわけです.
         :

世界初のロータリーカッターである オルファ株式会社の「マルカッター」の解説。短くさりげない記事だが曲線の切れるカッターのしくみが丁寧にわかりやすく説明されている。 この記事を書いた青木国夫氏(故人)は当時国立科学博物館工学研究部長の要職にあった著名な研究者。

関連記事

「自動焦点カメラのしくみ」

ひと昔前にはまったくの夢だった自動焦点カメラの出現です.
         :
月の探索用に積み込まれた無人操作カメラや, 8ミリシネマカメラには前から使われていましたが, この種類の普及カメラに組み込まれたのはこれが最初で, 文字どおり「シャッターを押すだけ」のカメラがここで実現したわけです.
         :
その仕組みは, これまでの距離計とレンズの焦点調節用の伸縮を自動連動させ, 二つの距離計映像の合致を2個の電子の目が見くらべて, 同じになるとそこでストップ, 実際には, シャッターを押すだけでピントも露出もピッタリ, その間は一瞬の手早さで, 撮影完了ということになります.
その仕組みを, もう少しくわしく説明しますと, ざっとこんなところです(図1)
         :
この方式は, 短焦点レンズ用(もともとピント幅が広い)には好適ですが,(中略)一眼レフなどの高級機用としては, 今後の研究をまたねばなりません.

コニカ株式会社(現コニカミノルタ株式会社)の C35AF は 1977年に発売された世界初の普及型オートフォーカスカメラ。この記事は発売されたばかりの同製品に用いられている当時最新の AF 技術を子供に理解することの可能な表現と内容で正面から解説している。ちなみに、記事を執筆した故・松田二三男氏は同誌で人気のあった読者投稿写真コーナー 目次 の選者を長らく務めた。

関連記事

「触媒について調べよう」

触媒とは, そのもの自体, 反応の始めと終わりで少しも変化しないで, ほかの物質の反応の速さを変えるものをいうのです.
         :
塩素酸カリウムという薬は, 熱すると酸素を発生するのですが, ガスバーナーで熱するぐらいではなかなか酸素はでてきません.    :
あらかじめ, 二酸化マンガン(触媒)を少し加えておくと, 200℃くらいの温度で完全に分解します.
         :
過酸化水素水(市販品のオキシフルとかオキシドールという消毒薬)を使って触媒の研究をしてみましょう.
         :

特にこれといった脈絡もなく「触媒」を扱う化学実験の話題が急にさらりと出てくるのがまた面白いところ。前述のように同誌は広く自然科学分野全般をカバーしており(時には社会科学方面の話題も)、毎回こうした単発の記事が何本も掲載されていた。当時市立中学校の理科教諭だった執筆者の岩崎幸敏氏は 70年代から 90年代にかけて中学生向けの多くの著書を上梓している。

「ぼくの発明 きみのくふう」(読者投稿コーナー)

● カッターナイフの改良 ●

今までカッターの刃を折る時, 手がしびれることがあったので, つめ切りと同じしくみのものをとりつけ, 手がしびれることなく簡単に刃が折れるようにしました. (B)のねじを回しカッターの刃に, (1)を近づけ, あとはつめを切るのと同じ方法で折る. (川上○○ / 北海道沙流郡)


この案は不安解消策として有効です. ただし, カッターにこのようなしくみを付けると, 価格が高くなったり, 使用しにくくなるなどの問題点も出てきそうです. 小学生にしてはいい着眼です.

ネットも PC もなく一個人が自由に情報発信を行う手段がほぼ皆無だった時代には新聞・雑誌等の投稿欄の存在感が現代よりもずっと大きく、同誌のこのコーナーにも人気があった。

子供が真剣に何かを考え工夫をこらして自分なりの結論を出し、それを第三者が理解できるように説明する努力を経て意見を求めるという一連の構図の素晴らしさをあらためて考えさせられる。 さらに、子供から寄せられたアイディアに決して安易に迎合することなく、むしろ大人である自分の視点での率直な意見を時に助言を添えつつストレートに伝えようとする選者の一貫した姿勢がそのことをさらに際立たせている。この号に掲載された応募作品は以下のとおり。彼らは今どんな大人になっているのだろうか。

  • コンパスの改良
  • つめが飛ばないつめ切り器
  • ボックス・ドライバーの改良
  • カッターナイフの改良
  • 豆英単語練習機
  • 自転車用高圧発生機
  • 小鳥のさえずりまくら
  • 黒板用三角定規
  • 音振動力紙ずもう

余談:エポック社「システム10」の広告ページ

この号には発売から間もないエポック社製の家庭用ビデオゲーム機「システム10」の広告が掲載されている。スペースインベーダーが大ヒットしたのが翌 1978年。ちなみに「機動戦士ガンダム」の初放映は翌々年の 1979年。のち 1983年のファミコンの登場によりビデオゲーム機市場の様相は一変するが、そこに至るにはまだしばらくの時間を要した。

  • 当時この「システム10」がとても欲しかったのですが自分でまかなうことはもちろん子供心にも親にねだれるような値段ではなく、ゼロがひとつ少なければ、、と何度も思っていました (> <)

2017年 6月号より

1977年当時の誌面との印象的な再会からほどなくして、本年 2017年の6月号を購入しました。創刊からすでに 90余年、現在は紙媒体とは別に Kindle 電子版も発行されていることを知って驚きました。

40年ぶりに買った同誌はこの時代相応に表現や文体がマイルドになってはいるものの、ガンとして変わらないロゴマークと同様に、誌面から伝わってくるテイストがあの頃のそれとあまり変わっていないことに安心しました。支障のない範囲で一部を抜粋してみます。

表紙と目次

  

記事より

  • 「水中の食虫植物 タヌキモ」
    定番の水棲動植物の特集記事。前掲の 1977年12号では「マリモ」でしたね :−)
  • 「ジブン専用パソコン 第3回ラズビアン(OS)を設定しよう!」
    食虫植物の解説とラズパイの連載記事がやっぱり普通に共存
  • 「ぼくの発明 きみの工夫」
    ボリュームは減ったもののこのコーナーが今も健在であることが嬉しい

創刊号(1924年 10月 第1巻 第1號)より

この記事の冒頭にもリンクを掲載した「子供の科学」公式サイトの次のページから 1924年(大正13年)の創刊号を閲覧することができます。

非常に貴重な誌面がこのような形で公開されていることはとても興味深く読み入ってしまいます。とりわけ、最初のページに掲載されている「この雑誌の役目」という文章に感銘を受けました。93年前に書かれたその全文を以下に引用します。

巻頭の辞「この雑誌の役目」


www.kodomonokagaku.com

この雑誌の役目  主幹

 愛らしき少年少女諸君!!!子供科学画報は、皆さんのために、次のような役目をもって生まれました。
 およそ天地の間は、びっくりするような不思議なことや、面白いことで、満ちているのでありますが、これを知っているのは学者だけで、その学者のかたは、研究がいそがしいものですから、皆さんにお知らせするひまがありません。したがって、多くのかたは、それを知らずに居ります。そのなかで特に少年少女諸君の喜びそうなことを学者のかたにうかがって、のせて行くのも、この雑誌の役目の一つです。

 皆さんが学校で学んでいる理科を、一そうわかりやすく、面白くするために、その月々に教わることがらについての写真や絵を皆さんのためにそろえるのも、この雑誌の一つの役目でもあります。理科の本にかいてある事がらに限りません。読本のなかにある理科の事がらに関するものも、のせておきます。

 毎日のように見たり使ったりしているもの事について、皆さんは、くわしく知りたいと思われることがありましょう。皆さんの御望みを満たすため、絵を入れてできるだけわかりやすく、そういうもの事を説明するのも、また、一つの役目であります。
 簡単な器械の造りかたをお伝えして皆さんの発明の才をあらわし、面白い理科の遊びのできるようにするのも、役目の一つであります。

 しかし、この雑誌の一ばん大切な目的は、ほんとうの科学というものが、どういうものであるかを、皆さんに知っていただくことであります。ちかごろは、「科学科学」とやかましくいいますが、ほんとうに科学というものを知っている人は、沢山ないようです。人は生まれながら、美しいものを好む心を持っておりますが、それと同じように、自然のもの事についてくわしく知り、深くきわめようとする欲があります。昔から、その欲の強い人々がしらべた結果、自然のもの事のあいだには、沢山の定まった規則のあることがわかりました。科学ということは、この規則を明らかにすることであります。多くの人が科学といっているのは、大ていは、その応用に過ぎません。この規則を知ることによって、人間は、自然にしたがって、無理のないように生き、楽しく暮らすことができ、これを応用して世が文明におもむくのです。
※書き起こしに際し、旧かな遣い・旧漢字・旧かな送りをあらためています

個人的な雑感

久しぶりに「子供の科学」誌に接し、私自身がもっとも強く印象に残ったのは、それぞれの分野の専門家の大人たちがそれぞれに子供たちに本気で向き合い、本気で何事かを伝えようとしている姿勢です。過剰に機嫌をとりながら話を聞かせようとするのではなく、興味をもった子供たちへ度合いに応じた「努力」の余地を残しながら適度な大きさの粒度まで知識や情報を砕いた上でそれを示し、あとは読み手側の好奇心と探求心にゆだねつつ同時にそれらを育んでいこうとする共通の意思のようなものを感じました。

難しいことをわかりやすく説明できることが最良とよく言われますが、そこに相手を受け身にすることなく相手の向上心を呼び誘うための配慮を加える余裕があればさらに素晴らしいことでしょう。そして、そういった配慮こそがその道に精通していなければなかなか果たすことの難しい命題ではないかと思います。同誌の記事の執筆者はすべて第一線の専門家であり、「子供だまし」ではなく真剣に世代のバトンを引き渡すためにはまさに適役でしょう。この誌面に限らずこういったあまり表には出てこない場所にもまたこれまで静かにこの国を支えてきた多くの大切な要素が脈々と息づいているのかもしれません。

どの世代にもそれぞれの役割があります。現役の大人の世代は年齢とともにいずれ順番に次の世代と交代していくことになりますが、科学や技術、学問の分野の話題に限らず、自分を含め今の大人たちが新しい世代に対する役割を適切に果たせているのか? 彼ら彼女らからの問いかけや疑問に対して都合よく言いくるめたりはぐらかしたりせずまっすぐに答えることができているのか? そういったことは大人から子供への一方的なプレゼントではなく、やがて次の世代との交代を終えた未来の自分の生きる世の中を支える礎にもなるものでしょう。つまり、今の子供たちに真剣に向き合うことはこれからの時代へ向けてのメッセージであると同時にこれからの自分自身に対する応援でもあるはずです。誰もが先人たちから受け継いだこの大きなループの中で生きています。その片隅で自分が少年時代に読んだこの雑誌をすっかり大人になった今の年齢でふたたび読み返しふとそんなことを考えました。


(tanabe)
klab_gijutsu2 at 12:45
この記事のURLComments(0)その他 
2017年09月01日

最近のPython-dev(2017-08)

はてなブックマークに登録

バックナンバー:

https://docs.python.org/ja/3/

docs.python.org に言語スイッチのドロップダウンリストが追加されました。docs.python.org は Fastly を使っているので、 docs.python.jp よりも高速に閲覧できると思います。

docs.python.jp にあるセクション単位での英語ドキュメントへのリンク機能などがまだなくて単純な翻訳でしか無いので、すぐには docs.python.jp を止めるつもりはありませんが、将来的には docs.python.jp は docs.python.org/ja/ にリダイレクトすることを考えています。

PEP 550: Execution Context

Flask などのフレームワークではスレッドローカルストレージを利用して「コンテキスト」を作り、現在のユーザーの情報とかリクエストIDとかをそこに格納する事があります。しかし asyncio などのコルーチンではこれが使えません。

そこで、もっと高度に抽象化された、コンテキスト変数を扱うための仕組みが提案されています。

Hide implementation details in the C API

サードパーティーの拡張モジュールが利用している Python/C API が、 Stable ABI 以外は公開/非公開、マクロ/C関数が混ざり合っていて、 Cython なんかは非公開APIも積極的に使って性能を稼いだりしています。

現状のデメリットとして、 Stable ABI は使いにくいので余り使われていないのに対して、 API は雑然としていて他の Python 実装が Python/C API 互換の API を提供するハードルが高くなってしまっていたり、意図せずに実装詳細に依存したサードパーティーのライブラリが増えて将来の性能向上のための内部の大幅な書き換えをする場合に互換性の問題が起こる確率が増えてしまっています。

そこで、 Stable ABI と #include <Python.h> の間を埋める、整理された Python/C API を用意しようという提案がされています。

個人的には、これによって今までマクロだったAPIがC言語の関数になり、RustやGoなどC言語以外の言語から Python/C API を呼び出しやすくなることに期待しています。

PEP 539: A new C API for Thread-Local Storage in CPython

Python の TLS のための C API が pthread_key_t を(90年代から) int 型にキャストして使っているのですが、これは posix 準拠ではありません。メジャーな環境では問題になっていないのですが、 Cygwin や CloudABI で問題になっていたそうです。

しかし、ABIレベルの後方互換性の問題があり、簡単に変えることもできません。ということで新しいAPIが提案されていたのですが、最近 Yamamoto Masayuki (ma8ma)氏がこの PEP に最近取り組んでいてもうそろそろ解決しそうです。

Cレベルの話で Python からは見えないのですが、日本人の活躍情報でした。

songofacandy at 17:27
この記事のURLComments(0)Python 
2017年08月31日

micro:bit と ESP32 でインターネットボタンを作る

はてなブックマークに登録

今月(2017年8月)5日に国内で正式販売の始まった BBC micro:bit を楽しんでいます。遅ればせながら、世界中の子どもと大人に人気のこの素敵なコンピュータのファンになりました。


http://www.bbc.com/
http://www.kitronik.co.uk/

私が micro:bit に関心を持ったのは最近扱っていた話題にちょうどぴったりのデバイスだったことがきっかけでした。今回はその内容と手元での試作を順をおって紹介します。

BLE ボタンデバイスをインターネットボタンとして使うこと

Amazon Dash Button の成功がひとつの契機にもなり この数年の間にインターネットボタンの利用と普及が進みました。手軽さといえば何かとスマホが引き合いに出されることの多い状況あってより単純な操作でより簡単に所定の処理を呼び出せることが専用の機器であることの最大の強みでしょう。

ただその一方で、機器の性質上ボタンデバイスの多くが電池駆動式であることが今後の用途・要件の拡大に伴いより悩ましい要素となる可能性も考えられます。限られた貴重な電力を使って自力でインターネット上の所定のサービスを叩きに行くのは必ずしも効率の良いやり方でありませんから、この点への対処が今後の課題となるかもしれません。

初代の Amazon Dash Button に高容量ではあるものの傍目にもコストバランスの危なげな米エナジャイザー社製の高価なリチウム一次電池が内蔵されていたことは象徴的です

一案として、省電性に優れた BLE ボタンデバイスと仲介役のエージェントデバイスを組み合わせてインターネットボタンを構成する形を想定しました。図にしてみます。

このように考え方はとてもシンプルです。ボタンデバイスは電池駆動、据え置きのエージェントデバイスは AC 電源からの給電を想定しています。 ボタン側は BLE 通信で必要最小限の通知をエージェントへ送り、エージェント側はそれをトリガーに所定のインターネットサービスを呼び出します。インターネットボタンは通常屋内空間での利用が前提ですから、BLE と WiFi の通信距離の違いに留意して機器の設置・運用を行えばこの構成には相応の合理性があります。また、小さなボタンデバイスひとつに複雑な処理を入れ込むことに比べ、機器の組み合わせによって必要な機能を実現するやり方には柔軟性が見込まれるでしょう。

通知の方法と道具立て

通知方法について

通常、BLE ペリフェラルからセントラルへの通知はデバイス間の接続確立後に所定の手続きによりセットアップを行うことで実施可能となります。この設定は両者の接続が維持されている間のみ有効です。

もちろんそれは BLE の仕様上のまっとうな規約なのですが、前掲の案への適用にはあまり気が進まずにいました。理由は以下の三点です。

  1. 「接続の維持」が必須であることは BLE の省電性を最大限に活かそうとする主旨と必ずしも折り合わない
  2. エージェントへの通知は必要最小限の合図のみでよいにもかかわらず仕掛けが豪華すぎる
  3. 技術情報や SDK の公開されていないボタンデバイスを利用したい場合にはグレーな解析が必要

代わりに デバイスからのアドバタイジングパケットを合図として利用することを考えました。この方法ならよりコストが低くデバイス間の接続に拘束されることもありません。また、アドバタイズの内容は文字通りオープンなので一般的なツールで普通に読めるという間口の広さも利点です。
注意の必要な点としては、連続して発生するアドバタイジングパケットにエージェント側が過剰に反応しないようにすることと、当該デバイスを本件専用として扱うべきであることが挙げられるでしょう。

エージェントについて

前掲の案のポイントは BLE 通信とインターネット通信の両方をカバーするエージェントを用意する点にあります。BLE つきの遊んでいるスマホを利用する手もありますが、「据え置き」「常時稼働」を前提とする IoT 装置として利用するにはいささかオーバースペックの感があり、また、視点は異なるもののスマホ系とボタンの連携に関しては「Flic」や「Pochiru」のような先例もあるためもうひとつ食指が動きません。

そこで ESP32 モジュールを使うことにしました。ESP-WROOM-32 は今回の要件を単体ですべて満たしているためまさに適役で価格面での魅力もあります。

ボタンについて

過去にこのブログでピックアップしたもの以外にも手元には複数の BLE ボタンデバイスがあります。それぞれに個性があり並べて使ってみるとなかなか面白いのですが、上述のようにアドバタイジングパケットを利用することを想定すると次のような機能・機構がほしいと考えました。

  1. 給電中にアドバタイズの開始・停止を任意に制御できること
  2. 複数のボタンが装備されていること
    (「ひとつのデバイスでひとつの処理」ではちょっと寂しい。アドバタイズを合図とする以上、ボタンデバイスが本来の通知機能においてダブルプッシュや長押しといったボタンアクションの区別に対応していてもそれを利用することができないという事情もある)
  3. 上記 2. に関連して、アドバタイズデータの内容を変更可能であること

残念ながらこれらの要件を満たすものは手元にありませんでしたが、プロトタイピングであれこれ試したところではどのボタンもそれなりに使えるのでまあこれはこれで・・とも思っていました。そこでたまたま目にしたのが micro:bit 国内販売のニュースです。

それまでこの製品のことは名前しか知らずにいました。あらためて写真をみてふたつのタクトスイッチが目にとまり、さらに記事中の「技適」の文字が気になって情報を調べたところ実は上のみっつの要件をすべて満たしていることがわかったため迷わずこれを利用することにしました。
ちなみにスイッチサイエンスさんが去年 12月にリリースした chibi:bit のこともこの時に知りました。ショップにはよくお世話になっているのですが、一見あまり関係のなさそうなところにしっかり良いものがあったりするものですね。

micro:bit 用に追加購入したパーツ

micro:bit ボードをボタンデバイスとして扱うために欠かせないふたつのパーツを調達しました。 いずれも英 Kitronik 社の製品で、ボタン電池から給電するためのオプションボード「MI:power(直販価格 £4.16)と、同ボードを装着した状態の全体をすっぽり覆うことのできる「MI:pro Protective Case(直販価格 £4.10)です。写真はケースに収めた状態の外観です。


前面
背面
また、今回は使っていませんが、拡張コネクタ用の「Edge Connector Breakout Board(直販価格 £4.15)もあわせて入手しました。

余談ながら Kitronik 社は直販を行ってはいるものの日本への送料が最安でも £30.95 と高いため、送料の安いショップを探して英国内の Pimoroni にたどり着き、そこで「MI:power」と「Edge Connector Breakout Board」を購入しました。送料は £5.50。8月7日に発注し 1週間で到着しました。なお、このふたつの製品はスイッチサイエンスさんのサイトにも掲載されており 8月21日に同社から「ご注文いただけるようになりました」メールが届きました。

どうしても欲しかった「MI:pro Protective Case」は Pimoroni にも見当たらず、しつこい検索を経て結局その時点で送料を含め最も安く販売していた ebay 出品企業から買いました。それでも総額が日本国内での micro:bit 本体価格よりも高額ではありましたが、ちょうど 2週間後の 8月25日に届き嬉々として使っています。

スイッチサイエンスさん、ぜひこの「MI:pro Protective Case」も扱って下さい!Pimoroni さんも今のところ扱っていないようですが、もし入荷されたら少なくとも私は確実に買います!(^^;

実装

micro:bit 側

micro:bit 側のプログラムは Microsoft MakeCode で手早く作成しました。以下の内容としています。

  • 電源が入ると最上段中央の LED を 2秒間隔で点滅開始 (給電状態の確認用)
  • 左側のボタン A が押されるとボタン右の LED を点灯し Eddystone-URL パケットにダミー URL "http://A" をのせて 4秒間アドバタイズする
  • 右側のボタン B が押されるとボタン左の LED を点灯し Eddystone-URL パケットにダミー URL "http://B" をのせて 4秒間アドバタイズする

アドバタイズに Eddystone-URL パケットを使用しているのは MakeCode 上の「Bluetooth」の項に他の選択肢が見当たらなかったためです。これと言って弊害も想定されず、また、どのような形式であれデータの内容で A, B ボタンを区別できれば事足りるのでこれはこれでよしとしました。図はエディタ画面のスクリーンショットです。すでにこういう時代なのですね。 (クリックで可読大表示)

ESP-WROOM-32 側

ESP32 モジュール側のプログラムは ESP-IDF 環境で作成しました。

処理の概要

  1. 所定の WiFi アクセスポイントへ接続
  2. 所定の URL へ HTTPS アクセスを行うためのタスクを生成して待機
    〜 下記 3. での要求発生時にリクエスト送出とレスポンス受信を行い終われば再び待機状態へ
  3. 永続ループで BLE アドバタイジングパケットのスキャンを開始
    〜 対象とする MAC アドレスのデバイスからの対象とする符丁を含む Eddystone-URL パケットを検知すると上記 2. のタスクへ所定の URL へのリクエストを要求

ソースコード

ここでは一台の micro:bit のみを対象としていますが、ソースコード中の Entries テーブルへ適宜エントリを追加することで複数の micro:bit を対象とすることが可能です。

A, B ボタンの押下に呼応するアクションのサンプルとして Gmail 発信, 携帯電話のコールのふたつの処理を紐付けています。これらはいずれも Microsoft Flow 上に作成したフローの URL への GET 要求によって実現しています。ふたつのフローのスクリーンショットを以下に示します。 (クリックで可読大表示)

Gmail 発信

電話機をコール(Twilio API を利用)

動作の様子

動画:1分18秒 (途中で電話着信音が鳴ります。音量に注意して下さい)


(tanabe)
klab_gijutsu2 at 09:06
この記事のURLComments(2)IoT | Bluetooth
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント
Syndicate this site