Galapagos Tech Blog

株式会社ガラパゴスのメンバーによる技術ブログです。

FoundationDBを試してみる

ご機嫌よう、ガラパゴスのおとめです。

先日のことですが、AppleがFoundationDBをオープンソースにしたというニュースが目に止まりました。そこでFoundationDB、て何かしらん、と調べてみたら、次のように魅力的なリストができました。

  • ACIDなNoSQL
  • SQLで操作可能
  • SSDを使う場合で、1コアで20,000書き込み/秒のスループット
  • 500コアまでリニアにスケール(1400万書き込み/秒までスケールするという記事もあり)
  • 読み込みは1ms、書き込みは5ms
  • キーはソートされている

そこで、まずは試してみることにしました。

インストールしてみる

とりあえず適当なUbuntu Server 16.04のVMに入れてみます(システム要件を満たしていないことは置いておきます)。まあ手順は公式に書いてある通りなのですが……

$ sudo dpkg -i foundationdb-server_5.1.5-1_amd64.deb
dpkg: 依存関係の問題により foundationdb-server の設定ができません:
 foundationdb-server は以下に依存 (depends) します: python (>= 2.6) ...しかし:
  パッケージ python はまだインストールされていません。

ここでガラパゴスのおとめはちょっとハマってしまいました。Ubuntu 16.04ではPython3.5が入っていて、コマンドもpython3だからなのかな? とか、python2も入れておいて、update-alternativesしないとダメなのかしらん? とか……

結論としては、sudo apt-get install pythonするだけでした。

インストールが済んだら確認してみます。

$ fdbcli
Using cluster file `/etc/foundationdb/fdb.cluster'.

The database is available.

Welcome to the fdbcli. For help, type `help'.
fdb>

次にbindingをインストールしてみましょう。この記事を書いている時点では、以下の言語が用意されています。

使ってみる

今回はRubyから使ってみます。公式のガイドでは何故かgemを直接ダウンロードするみたいに書かれていますが、gem install fdbで入ります。ダウンロードしたgemを使う場合は、ffiに依存していますので一緒に入れると良いでしょう。

では早速公式のAPIリファレンスとにらめっこしつつREPLから使ってみます(Ruby 2.5.1から使っているので時々ワーニングが出ています)。

$ irb
irb(main):001:0> require 'fdb'
=> true
irb(main):002:0> FDB.api_version 510
/home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated
/home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated
/home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated
=> nil
irb(main):003:0> db = FDB.open
=> #<FDB::Database:0x000056493f1fb808 @dpointer=#<FFI::Pointer address=0x00007f4ddc001050>, @options=#<FDB::DatabaseOptions:0x000056493f1fb790 @setfunc=#<Proc:0x000056493f1fb7b8@/home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:553 (lambda)>>>

……ここいらへんから既に公式のリファレンスが何を言っているのかわかりません。というかAPIの説明が何もないので、ソースコードの方を見てみると、どうやらFDB.openの戻りを使ってget/set/clearすることでKVSのように使えるようです。

irb(main):004:0> db.set(1, 'foo')
Traceback (most recent call last):
        6: from /home/his/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
        5: from (irb):8
        4: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:581:in `set'
        3: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:569:in `transact'
        2: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:582:in `block in set'
        1: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:877:in `set'
NoMethodError (undefined method `bytesize' for 1:Integer)

何か怒られました。Integer#bytesizeが存在しないと言われています。bytesize? じゃ文字列を入れてみたらいいのかしらん?

irb(main):005:0> db.set('1', 'foo')
=> "foo"
irb(main):006:0> db.get('1')
=> "foo"

何か入ったようです。試しにFDBコンソールから確認してみましょう。するとこのようにちゃんと登録されているようです。

$ fdbcli
Using cluster file `/etc/foundationdb/fdb.cluster'.

The database is available.

Welcome to the fdbcli. For help, type `help'.
fdb> get 1
`1' is `foo'

では何件か登録してみます。

irb(main):007:0> db.set('100', 'bar')
=> "bar"
irb(main):008:0> db.set('30', 'baz')
=> "baz"

既存のキーを書き換えてみます。

irb(main):009:0> db.set('1', 'hmm')
=> "hmm"

ところでキーは必ずソートされていると書かれていました。確認してみましょう。キーを複数取得するには、get_rangeを使うと良さそうです。

irb(main):010:0> db.get_range('1','100')
=> [#<FDB::KeyValue:0x000056493ee77970 @key="1", @value="hmm">]
irb(main):011:0> db.get_range('1','999')
=> [#<FDB::KeyValue:0x000056493eb7e520 @key="1", @value="hmm">, #<FDB::KeyValue:0x000056493eb7e160 @key="100", @value="bar">, #<FDB::KeyValue:0x000056493eb7d788 @key="30", @value="baz">]

ふむ。(とりあえずデフォルトでは)ソート順はCなのかしらん? そして、get_rangeの引数に与えるキーの範囲ですが、始点は含んで終点は含まないことが分かりました。ためしにFDBコンソールからも見てみましょう。

fdb> getrange 1 999

Range limited to 25 keys
`1' is `hmm'
`100' is `bar'
`30' is `baz'

ソートされているようです。

さて、今回はFoundationDBのさわりとして、RubyからかあるくKVS風に触ってみました。SQLで操作とかトランザクションとかスループットとかも多いに気になるところですが、今回はここまでにしましょう。スループットとかはErlangで10,000プロセスくらいで一気に書いてみたらいいのかしらん……?


ところでガラパゴスではエンジニアを募集しています。ご興味をお持ちの方はぜひ弊社の採用ページをご覧ください。

www.glpgs.com

では、ご機嫌よう。

--

この記事は業務の一環として業務時間中に書きました

Sidekiqのプロセスをキューで分ける

ご機嫌よう、ガラパゴスのおとめです。

突然ですがRailsをお使いの皆さんは非同期処理にSidekiqを使ったりしていると思います。それで普通にデプロイするとSidekiqは1プロセスになりますね? 今回はかあるく短く、Sidekiqプロセスを複数にしたいなあ、というお話をしようと思います。

都合によりちょっと記事中のバージョンが古いですがご了承くださいね。

どうして複数プロセスにしたいの?

アプリケーションサーバーも非同期処理も全部一台で動かしているならSidekiqは1プロセスでもいいですが、多くの場合はサーバーを分けたりしているかと思います。

ところで、今時のサーバーならマルチコアですね? でも、1プロセスで動かしている限り、1コアしか使われません。当然ながら他の資源は無駄になります。

また、Rubyのマルチスレッドモデルでは、ブロッキングIOが発生しない限りコンテキストが切り替わりませんので、一つのワーカーで計算ばかり重い処理をしていると、他のワーカーが動かないといったことも起こります。

いやん。

もちろんコンテナで動かすとか資源を有効に活用する方法は他にもあるのですが、ここではとりあえず簡単にすぐにできる方法を試してみましょう。

複数のSidekiqを起動してみる

では、試しに複数起動しちゃってみましょう。必要な設定とかは書いてあるとして。

$ bundle exec sidekiq -C config/sidekiq.yml -L log/sidekiq1.log -d
$ bundle exec sidekiq -C config/sidekiq.yml -L log/sidekiq2.log -d

するとこのように、無事に複数起動するかと思います。

$ ps aux | grep sidekiq
otome  2383   0.0  0.0  4277992    908 s001  S+    9:09AM   0:00.00 grep sidekiq
otome  2377   0.0  1.2  4546588 204840   ??  S     9:09AM   0:09.43 sidekiq 4.0.2 sidekiq-test [0 of 10 busy]
otome  2109   0.0  1.8  4659228 296080   ??  S     9:09AM   0:13.17 sidekiq 4.0.2 sidekiq-test [0 of 10 busy]

もちろん、設定ファイルを分けることで、プロセスによって処理するキューを分けたりワーカー数を変更したりすることもできます。

例えば一方のプロセスで foo キューを処理して、

:pidfile: ./tmp/pids/sidekiq1.pid
:logfile: ./log/sidekiq1.log
:queues:
  - foo

別のプロセスで bar キューを処理するとします。

:pidfile: ./tmp/pids/sidekiq2.pid
:logfile: ./log/sidekiq2.log
:queues:
  - bar

あとはこれを引数に与えるだけですね。

どうやってデプロイするのん?

さて、では本番的な環境に適用しましょう。

大抵の場合はRailsアプリケーションのデプロイにはcapistranoを使われているかと思います。Sidekiqのデプロイにはcapistrano-sidekiqをお使いでしょう。

READMEを眺めてみると「なるほど???」という感じもしますが、例えば以下のようにすることで、複数のプロセスを異なる設定ファイルで起動することができます。

set :sidekiq_processes, 2
set :sidekiq_options_per_process, [
  "--logfile #{release_path}/log/sidekiq1.log --config #{release_path}/config/sidekiq1.yml",
  "--logfile #{release_path}/log/sidekiq2.log --config #{release_path}/config/sidekiq2.yml"
]

もちろんconfigに与える設定ファイルを同じにすれば、同じ設定ファイルで動きます。

早速デプロイしてみると、無事にSidekiqプロセスが複数になっているかと思います。


ところでガラパゴスではエンジニアを募集しています。ご興味をお持ちの方はぜひ弊社の採用ページをご覧ください。

www.glpgs.com

では、ご機嫌よう。

--

この記事は業務の一環として業務時間中に書きました

(完) テスコン(テスト設計コンテスト)2018 決勝戦いってきた

みなさまこんにちは!!テストチームとのの(@tonono2587)です。
前回前々回 に引き続き、完結編としてOPENクラスの振り返りをしていきます!!

gtech.hatenablog.com

gtech.hatenablog.com

OPENクラス 参加チーム

OPENクラスも5チームでの闘いでした。(発表順)

  1. タニタガワー6
  2. 紙印テスト倶楽部
  3. イイてすと
  4. ふわパン
  5. てすにゃんV3

個人的にはタニタガワー6のプレゼンききやすくて好きでした。
ふわパンさんのチーム名の由来聞きました?(チームメンバーの体型が)ふわふわ+パンダ って言ってましたよ?!めちゃくちゃかわいい!!!!!(好き!!)

結果

内容が入ってこなくてすみません。結果は以下です。

【優勝】てすにゃんV3 【準優勝】ふわパン

おめでとうございます!

ASTER-テスト設計コンテスト'18-OPENクラス 決勝戦

講評/総評でどんな感じだったのか振り返ります。

講評

タニタガワー6】

  • USAを提唱
  • 「かっこいい」と自分たちで言っていた
  • シンプルでわかりやすいと思います。
  • なぜ4つでいいのか、なぜそれがでてきたのか、を詰めていくとよいのでは

【紙印テスト倶楽部】

  • テストの取り組みは受け身になりがちだが、今回の発表は能動的にテストから仕掛けていく取り組みが内包されていてよかった
  • いままでの経験を積み重ねている
  • 最多出場で必ず*1決勝に残っている(すごい)

  • 継続する力がすごいし、しかも毎年新しいことを仕掛けている

  • アウトプットするし、たくさんの人に知らせている姿勢◯
  • そのフィードバックを次につなげる循環がよい◯

【イイてすと】

  • 特別枠だった、予選からレベルアップしていた
  • 業務フロー業務分析*2につかったりするものをテストにつかう
  • 見える化する」ことが大事
  • あれ自体が業務フローをあらわすものなので、それをテストに適応させていきたい
  • 質疑応答タイムで言っていた「テストに適用できると証明したい!」という熱い思いをはじめからだしたほうがよかった

【ふわパン】

  • 他チームが新しい技を出してきた中で、普通のテスト設計をしてきた
  • それがちゃんとできていた
  • こういうテストありだよな~と思った
  • オーソドックスにテストしていて、メンバーにこういう人がいたら安心できる内容だった
  • この基本は守って向上していってほしい
  • ただ、「言葉」(用語)が方言っぽくなっている (テスト技法→テストタイプ、テストポイント→テスト条件、など)
  • 非機能テストからやる→やっていることは王道だが表現が違った
  • 可視化して説明してほしい

【てすにゃんV3】
(すみません、てすにゃんの講評ありました?聴き逃してしまいました 汗) どんな内容だったかだけメモ載せときます

  • 製品のリリースを止めるバグを許容範囲までなくす
  • bugspots(よみ:バグスポッツ)を利用
  • 製品のリリースを止める事象およびバグをどう特定するか
  • フォルトツリーズを用いた事象の分解
  • テストで対処する/しない事象はどのように決めるか →被害金額とリスク値から決める
  • 対処するためにどんなテストをどのくらいやるか? →テストタイプのリスク低減表による許容範囲の調節

f:id:glpgsinc:20180227204505p:plain:w300 にゃ~

総評

  • テスコンがはじまってから2、3年はテスコンの次の活動がなかった。 いまは審査員になったり、次の活動に繋がったりしている
  • 卒業して、より広い活動、レベルの高い活動へ>次の世代が同じように追いかけていく→全体が右肩上がりしている

  • 審査員はフェアにみている →だれがつくったかは全く気にしないで成果物をみて、審査している

  • ひろくみて、いろんな関係をフラットにみて、だんだん落とし込む王道をいったのがふわパン

  • それは関係をモデリングして、落とし込んでいって…→これは難しいこと
  • 他4チームは何かほかの考え方に寄せている→こうすれば考えるのが楽になるのでは?
  • 考え方の違いなのでどっちがいいとかはない
  • (例えば円柱があったとして、)円をモデリング>長方形をモデリング>… 全部捉えようとしてしまったら扱いきれなくなってしまう
  • トレードオフですね
  • ほとんどのチームが何かに寄せて安心してしまったので点数が拮抗していた
  • 全部捉えようとしてしまったらほうは、扱いきれなくなってしまっていた感じ

  • 表せるものはなにで表せないものは何で、を理解した上でケースに落とし込む →その理解をどっち側からやるかが問題

  • 模範解答はない

  • 正解はない。100点の成果物はつくりようがない

  • 業務だと納期があり、深く深く考えるには限界がある

  • 一方テスコンは仕事の納期に比べれば考え抜く余裕がある
  • 考え抜いたものを見せてください!
  • テストとは何か考えたり

  • プレゼンがみんな似ているのでおもしろくない〜

  • 独自のプレゼンテーション がみたい!
  • 型ができて「型通りやると決勝いける」みたいになってきたらつまらないよね。

感想

  • 「USA」について、ユーザーストーリーマッピングがベースのテストということで、どんなテストをするのかわかりやすかった気がします。
  • 一方で、それで足りているかとか、安心かどうかを考えるにはプレゼン時間はあっという間すぎてついていけませんでした(´・_・`)話がわかるようになってきたらそこまで考えられるのかな。。
  • 紙印テスト倶楽部の、テストを考える前に仕様(テストベース)に対してフィードバックをする方法はすごくしっくりきました。
  • 「テストベースをテスト設計成果物へ変換する」ところで、いま知識が足りなかったりもやったりしているような気がする
  • bugspots、知らなかったのでぐぐりました

SHANON Engineer's Blog: Google のバグ予測アルゴリズムと bugspots の導入

  • コードに手を加えられているところほどあやしい、からそこを狙え、ということでしょうか?
  • ぐーぐる先生が言うなら信用できる!みたいなイメージをもちました
  • 正解がないぶん考えたなりに自信をもって「こうやって正解出しました!」と言えないと大人はうんと言わないですよね。がんばりどころのヒントになりそうです。

もやもや晴れた?

前々回で整理した、わたしのもやもやは。。

  • 考えた内容(設計)がうまく表現できない
  • 伝わるもっといい書き表し方があるはずだ
  • テスト分析してるけどなんか足りてないかもという不安感
  • テスト分析にはもっといい方法があるのでは?!

→聴講を通してヒントはあったように思います!

  • 全体を捉えるような視点で振り返るとよさそう
  • 何かに寄せて考えてみたり、全体から落とし込んでいったり、やり方がいろいろある
  • レベリング

昨年決勝戦にきたときは、正直ほとんど話についていけず、成果物の展示をみても 「字がいっぱい〜。。。」くらいにしか思えませんでした。

gtech.hatenablog.com

※ただモチベーションはものすごくあがった

今回も「字がいっぱい〜。。。」とは思いましたが(おいー)、
なんの話をしているかはわかるようになったなと思いました。

とくにU-30での発表内容やフィードバックは、自分に置き換えてみていくと実務に適用できそうなところがありました。 来年はもっと話のスピード感についていけるようになりたいです。

さいごに

参加者のみなさんお疲れさまでした!
このレポートをとおして観戦してくれたみなさまも、おつきあいありがとうございました。
テスト界ではテスコンのようないろんなイベントがありますので、どこかでまたお会いできたらうれしいです!とののでした。(^_^)/~






ガラパゴスからのお知らせ〜
ガラパゴスでは、ただいまサーバーサイドエンジニア、Androidアプリエンジニアを募集しております。
詳しくは公式HPをご覧ください。

SERVER ENGINEER | 株式会社ガラパゴス iPhone/iPad/Androidのスマートフォンアプリ開発

*1:必ずではなかったとご指摘いただいたので確認し訂正しました。2018/03/06

*2:教えていただいて修正しました。2018/03/06