その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Released lua-benchmarker

I've released lua-benchmarker that is a benchmarker for lua code. This benchmarker is for taking microbenchmark.

github.com

This library is available on luarocks. You can install this by luarocks install benchmarker.

luarocks.org

For example, write a benchmark code like following:

local benchmarker = require 'benchmarker'

benchmarker.new({
    ["insert append"] = function ()
        local arr = {}
        for i=1,1000 do
            table.insert(arr, i)
        end
    end,
    ["index append"] = function ()
        local arr = {}
        for i=1,1000 do
            arr[i] = i
        end
    end,
}):warmup(10):run_within_time(1):timethese():cmpthese()

then execute this code, the result is the following:

starting warming up: 10

Score:

index append:  1 wallclock secs ( 1.05 usr +  0.00 sys =  1.05 CPU) @ 51124.51/s (n=53695)
insert append:  1 wallclock secs ( 1.06 usr +  0.00 sys =  1.06 CPU) @ 9185.70/s (n=9760)

Comparison chart:

                    Rate  index append  insert append
   index append  51125/s            --           457%
  insert append   9186/s          -82%             --

Yes, this output format is taken from Benchmark.pm. This benchmarker is inspired by Benchmark.pm and tokuhirom/nanobench.

NOTE: This utility supports multi-platform (i.e. Windows is also supported!!).

Enjoy.

Elasticsearchに実際に書き込むテストなんかで「indexへの反映に時間がかかって困る〜〜」って時

Elasticsearchに実際に書き込む系のテストをするとき,例えば「fixtureを作ってindexしてクエリ打ってちゃんと結果が取れるかどうか」みたいなことをやると思うんですが,fixtureをindexする際にそのデータがindexに反映されるまでにrefresh_intervalぶんの時間がかかってつらい!!! というときにどうするかという話です.

Plan A. refresh_interval をめっちゃ短くする

要はrefresh_intervalがめっちゃ短ければ解決する(こともある)話なのでそれをやるという方法.上記のtweetで「1000ms」とか言ってるのはあくまでデフォルト値なので,それをカスタムしてやると良いという話です.

{
  "settings": {
    ...
    "refresh_interval": "1ms"
  }
}

などとしてやればindexへのdataの反映周期が1msecになるのでまあ充分でしょう,という割り切った感じです.テスト用途であればほぼ多くの場合はこれでも動作すると思います.コード自体に手を入れる必要がないのは良さそう.
が,間違えてもproduction環境に入れてはならない設定なのでindex templateを別個に管理する必要が出てくるでしょう.

Plan B. index refresh APIを叩く

www.elastic.co

fixtureを投入してから明示的にindex refresh APIを叩くという方法.叩くとデータが即座に近くindexに反映されるようになるので用途としてはマッチすると思います.これであればproductionのindex templateをそのまま流用できるので便利ですが,まいどまいどrefresh APIを叩くコードを挟まなければならないので,そこは何らかのtest utilityみたいなものでカバーするなどといった工夫が必要そうです.


Plan C. ?refreshをクエリに付ける

www.elastic.co

更新系のクエリを発行する際に?refreshというクエリパラメータをつけると,こちらも即座に近くindexにデータが反映されるようです.お手軽!




他にもあるかもですが,用途と場合に応じたものを使うと良いと思います.

テストが速くなってよかった!

Released lua-cputime

I had released lua-cputime.

github.com

This package also had been shipped to luarocks.

luarocks.org

This library provides functions to measure the CPU time (i.e. user time and system time). The lua runtime doesn't support such functions, so this library bridges to native C's sys/time.h and sys/resource.h and expose getrusage() function as get_process_cputime(), get_children_process_cputime() and get_thread_cputime() *1.

As you can see, this library doesn't support the Windows environment because it associate to sys/time.h and sys/resource.h. I have a will to support the Windows, but I'm not familiar with that. I'm happy if a patch is sent.




[following description is outdated; the implementation has been changed]

This library provides a function to measure the CPU time (i.e. utime, stime, cutime and cstime). The lua runtime doesn't support such function, so this library bridges to native C's sys/times.h and expose times() function as get_cputime().
As you can see, this library doesn't support the Windows environment because it bridges sys/times.h. I have a will to support the Windows, but I'm not familiar with that. I'm happy if a patch is sent.

*1:`get_thread_cputime()` is only supported by Linux

Released lua-url-encode

I had released lua-url-encode.

github.com

And I also had shipped that to luarocks. You can try to install this with luarocks install urlencode.

luarocks.org

This package is a URL encoder/decoder library for lua that is written in C (with lua's native extension mechanism).The library aims (and realized) to be a faster implementation of URL encoding and decoding:

  • encoding is about 64 times faster than pure lua implementation
  • decoding is about 39 times faster than pure lua implementation


Note: This library is a ported implementation from p5-url-encode-xs.

#builderscon 2018 tokyoに参加しました & 話してきました

builderscon.io

builderscon 2018 tokyoで「Java Cardの世界」というタイトルで話してきました.発表資料は以下のとおりです.

喋りたいトピックはJava Card以外にも様々あったのですが,「知らなかった、を聞く」というカンファレンスのテーマを鑑みた結果,あまり一般には知られていなさそうな *1,しかし身の回りを確かに支えている技術についてお伝えしたいと思い至り今回のような発表をした次第です.この発表で少しでも生活が豊かになってもらえれば望外の喜びであります.

さてこの発表はありがたくもベストスピーカー賞第1位を頂戴しまして,感激の極みであります.本当に嬉しい!!! もちろんこの発表は僕個人の力のみで成し遂げたものではなく,所属しているソラコムの同僚の多大なる協力があって達成したものです.特にJava Cardの偉大な知識を授けてくれたolivier,yaman,kennyには本当に感謝したいと思います.ありがとうございます!!!

副賞としてなんかすげえ量のガジェットがやってくる予定なので向こう1年くらい遊べるんじゃないでしょうか.中でも「マウス自作セット」という文字が僕の心を掴んで離しません! 作ったものについては色々このブログとかに書いていきたいですね.


[追記]

ついにガジェットが来ました!!!! すごい!!!!!!
スポンサーのGMOペパボの皆様をはじめまして関係者の皆様本当にありがとうございます!!!!!

最高!!!!!!!!!!!!!!

f:id:moznion:20180910112011j:plain

これは同僚のtomoに撮影してもらった目録の写真です!!!

[追記ここまで]


さて,参加したセッションの中でも印象的だった発表について記したいと思います.

産業でガチ利用されるRaspberry Piの話 - @kazuphさん

builderscon.io

本当に身の回りで見かけるようになった,ともすればここ最近では一番身近なコンピュータである可能性があるRaspberry Piを産業利用される話でした.発表中,「BluetoothのIoTゲートウェイなー!!! 本当に難しいんだよな!!!!!」という共感が生まれ,非常に面白い発表でした.
ansibleのようなweb app的な文脈で多く使われてきた技術がIoT分野でも利用されている事例を聞いたときは,いままで隔たりのあった技術間の融合というか,汽水域のようなものができてきているように感じ,非常に興味深かったです.これは素晴らしいことだと思います.

カクヨムでの縦組み表示の実装と、縦書きWebの将来に向けて - @nanto_viさん

builderscon.io

縦書きWebという特別な環境における開発の話が聞けて貴重でした.今まで縦書きWebの開発をやったことがなかったので……
「やっぱりブラウザのバグとか結構踏むんだな〜大変そう,うわっすげえ壊れ方してる!」みたいな感じで拝見していたのですが,しかしそういった問題に対して適切にworkaroundを入れていく,そして適切にブラウザ本体に対してバグレポートを送る,といったことを淡々とこなされており,そうした姿勢が非常に尊く大変良かったです.

実録!ある担当者がみた「謎ガジェット」開発1年史 - @uzullaさん

builderscon.io

これめっちゃ良かった,電子名札ガジェットのプロトタイプ作成から量産するという無茶ストーリーを発表されており,圧巻です.ガジェットを200個作るというのはそれはそれはすごいことなのです.明らかに個人でやることではない!!!!!
これは動画が公開されたら絶対見たほうが良いと思います.最高.

Jepsen 10 - @aphyrさん

builderscon.io

ウオー,俺はこれが見たかったんだよ!!!!!!!!!! 分散システム・DBを調べたり使ったりする時に,ほぼ必ずと言っても良いほど参照することになるJepsen testの著者の方の発表です.このブログは真に最高なので,読んだことがない方はぜひ読むと良いと思います. https://aphyr.com/
本当に最高で,分散システムが勢い良くどんどん壊れていく.ネットワークの物理的分断,タイムアウト,魔のタイミングでのノードの立ち上げ,入力する時刻を揺らすなどなど様々な破壊シナリオが紹介されていてめちゃめちゃに面白い.発表中の「分散ロックできるっていうのはだいたい嘘です」という言葉に説得力があり,大変に良かった.
発表後にRedis Sentinel/Clusterの質問や,InfluxDBの分散エディションについての話をできたのも良かった……

ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ - @aerealさん

builderscon.io

いつもお世話になっております (このブログとか).数万規模のSSL/TLS証明書を管理しなくてはならないというなかなかタフかつ珍しい要件の話を聞けて非常に楽しかったです.各コンポーネントの責務を非常にミニマルかつ明確にされており (つまり責務の境界が明確化されている),それぞれが正しく協調動作している点に非常に美しさと正しさを感じました.また「AWS Step Functionsよさそう,使ってみたい」とも思いました.

その他雑感

今年はspeakers dinnerという新たな取り組みが行われており,これも非常に面白かったです.懇親会とはまた違った感じで,ゆるーく知らない人 (しかしおそらく距離は近いであろう人) と話したり意見交換したりできる場というのはなかなか新鮮で良かったです.ただ本会の前に開催されるため,そこでうっかり話しすぎてしまい,逆に懇親会で無口になるという珍事が発生しました.ハハハ.

ところで今回はafter partyに参加できなかった,できなかったのです.なぜか? それは僕がチケットを買い忘れたからなんですけど……これにはへこみました……まいった……
だもんで「とりあえずこれ買っておけば全部OKチケットx万円!!!!!!!!」みたいなチケットが出ると嬉しいですね!

今年は非常に印象的なカンファレンスになりました,スタッフをはじめ皆さん本当にありがとうございました.
また来年お会いしましょう,お元気で!!

*1:事実僕もやるまで知らなかった

Linux Kernel 4.12以前であればhostマシンのsysctlの値がDocker container環境に引き継がれるかどうか検証した

Docker - IPVS connection timeout issue

これを読んでいたところ

From Linux kernel 4.13 onwards, sysctl default values can be modified per container basis. Container will not inherit changes from the host sysctl modified values.

とあったので,逆にhostマシンのLinux Kernelが4.12以前であればhostマシンのsysctlの値がDocker containerに引き継がれるのか? と思い検証してみました.

TL;DR

  • (手元の環境で試してみた限り) 引き継がれなかった
  • 変なことを考えず,おとなしくdocker run--sysctl オプションを使おう!!
    • Amazon ECSは早くsysctlのサポートしてくれ!!!!!

hostマシン環境

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.1 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ docker -v
Docker version 18.06.1-ce, build e68fc7a

コンテナ環境

https://hub.docker.com/_/ubuntu/

ubuntu:bionicを使用.

Kernel 4.13.16でやってみる

$ uname -a
Linux moznion 4.13.16-041316-generic #201711240901 SMP Fri Nov 24 09:02:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
7200
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200
$ sudo sysctl -w 'net.ipv4.tcp_keepalive_time=600' # <= ここでhostのtcp_keepalive_timeをいじってみる
net.ipv4.tcp_keepalive_time = 600
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
600
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200

引き継がれてないですね.

Kernel 4.12.14でやってみる

$ uname -a
Linux moznion 4.12.14-041214-generic #201709200843 SMP Wed Sep 20 12:46:23 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
7200
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200
$ sudo sysctl -w 'net.ipv4.tcp_keepalive_time=600' # <= ここでhostのtcp_keepalive_timeをいじってみる
net.ipv4.tcp_keepalive_time = 600
$ sysctl -n net.ipv4.tcp_keepalive_time # <= host
600
$ sudo docker run ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
7200

あれ,引き継がれないですね.

もちろんsysctlオプションを食わせながらdocker runすれば反映される

$ sudo docker run --sysctl 'net.ipv4.tcp_keepalive_time=600' ubuntu:bionic sysctl -n net.ipv4.tcp_keepalive_time # <= container
600

所感

Kernel 4.12.0とKernel 4.10.17でも試してみましたがhostマシン側のsysctlがcontainerに引き継がれているようには見えませんでした.なんか間違ってるんですかね? それとも引き継がれないのが普通?
とはいえ新しいKernel上ではhostのsysctlは引き継がれないし,やはりdocker runの--sysctlオプションで渡すのが良いでしょう.しかしAmazon ECSではsysctlオプションが対応されておらず*1……嗚呼