LIVESENSE ENGINEER BLOG

リブセンスエンジニアの活動や注目していることを発信しています

RubyのRedis Client LibraryをCluster Modeに対応させた話

こんにちは、アルバイト事業部の春日です。アルバイト求人サイトである マッハバイト のサーバーサイドを担当しております。 Redis GemCluster Mode に対応させる Pull Request を出す機会に恵まれたため、本日は振り返りも兼ねてそれについてお話させていただければと思います。

背景

Ruby on Railsで実装しているマッハバイトでは、将来的なユーザー増加を見越して2015年03月頃にRedis ClusterをSession Storeとして使い始めました。 当時はまだRedis3.0が出たばかりだった記憶があり技術選定時に twemproxy なども検討されていました。 Reshardingなどもできる運用ツール もあってRedis本体がNativeでサポートしている、という理由でRedis Clusterを採用しました。

しかしRedis3.0で初めてCluster Modeが登場したというのもあり、Cluster Modeに対応した定番Gemがまだありませんでした。 RailsのSession Store機構が定番のGemセットでうまく扱えずにログイン周りなどを自前実装することになりました。

そこで定番とは言えないものの Redis本体の作者がつくったCluster Client Library を本番環境で使用することにしました。 Gem化されていないので vendor/* 配下に直接コピーして使ってました。それでも問題なく動作していたのですが、徐々に自前実装しているセッションロジックまわりのメンテがキツくなってきました。

その後、この Redis本体の作者がつくったライブラリをGem化する試み や別のGemが出てきたみたいですが、どれも活発に使用されている気配はありませんでした。 できれば我々はビジネスロジックに集中したいため、そうすると定番Gemセットを使うには Redis Gem に頼らざるを得ません。

Redis Gem のメンテナの方々は Redis本体 もメンテしている方が多く、本体のメンテが忙しくてClientソフトの方までなかなか手が回っていない印象を受けました。 Cluster Mode対応のissueは何個かあがっていて需要はあったみたいなので、チャンスと捉えてPull Requestを出すことにしました。

時系列

出来事
2017-09 Pull Request を出すも活動的なメンテナがいなくてしばらく放置される
2018-05 Sidekiqオーナーが出した救いの手issue によりメンテナが増える、このタイミングでRailsをメンテしているようなShopifyのRubyistたちが加わったのが大きい
2018-06 RailsもメンテしてるShopifyのRubyistの方に丁寧に的確にレビューしてもらう
2018-07 マージされる
2018-10 Ruby Prize 2018 に並ぶも他が強過ぎて普通に選考から外れる

最初は Redis本体の作者がつくったライブラリ のリファクタリング程度のものでしたが、レビューを通してテストコードを拡充していくとリファクタだけでは全然考慮が足りていなかったことに気付き、あわてて全面実装し直しました。 RailsもメンテしているShopifyのRubyistの方にはこの場を借りて感謝を申し上げます。本当にありがとうございます。頭が上がりません。

RedisのCluster Modeについて

Slot

Redis ClusterのShardnigはCommandのKeyから 算出 されるSlot値をもとに行われます。

f:id:livesense-blog:20181017134434p:plain

CLUSTER KEYSLOT コマンドを使うとKeyを指定してSlot値を得ることができます。

(以降の例はローカルに7000-7005ポートで1レプリカずつの計6インスタンスを立てているケースを想定) 下記の例だと key19189 のSlotを持つNodeに格納されることがわかります。

$ telnet localhost 7000
cluster keyslot key1
:9189

Slot値は0番から16383番までの16384個を取ります。Cluster構築時にSlot RangeをどのNodeに割り当てるかを明示的に指定します。 Cluster操作の運用ツールとして redis-trib.rb を使うとそこらへんの分割計算をしてくれます。 なお最新のRedisだと redis-trib.rbredis-cli に統合されました。Ruby以外でRedis Clusterを使用している環境では運用し易くなったと思います。

マッハバイトの本番環境ではレプリカ1つずつの計6台を運用しており、Master Nodeそれぞれに以下のSlotを割り当ててます。

  • Master1 0-5460
  • Master2 5461-10922
  • Master3 10923-16383

HashTag

Redisでは複数のKeyを指定できるCommandがあります。Cluster Modeだとそれに気を使う必要があります。Nodeを跨いだ複数Key指定はエラーが返ります。 下記の例だと key1key2 が異なるNodeに格納されていて CROSSSLOT エラーが返ってます。

$ telnet localhost 7000
mget key1 key2
-CROSSSLOT Keys in request don't hash to the same slot

これには複数Key指定コマンドの使用を諦めるか HashTag を使って意図的に同一ノードにKeyをまとめる必要があります。 下記の例だと {key}1 {key}2 は同一Nodeに格納されるようになります。MGET の結果が読みにくいですが [a b] の配列が返ってます。 余談ですが Redis Protocol はシンプルなので配列以外は読み易いです。

$ telnet localhost 7002
mset {key}1 a {key}2 b
+OK
mget {key}1 {key}2
*2
$1
a
$1
b

HashTagを使用すると中括弧内の文字列でSlot値を 算出 するようになります。 しかしこのHashTagを多用するとせっかくのShardingが偏るので注意が必要です。

Redirection

Redis ClusterのNodeはRequestをProxyしてくれません。指定したKeyが送信したNodeとは別のNodeに格納されている場合はリダイレクトを要求してきます。 SRE本 にもカスケード障害の章に以下の記述があります。

通常は、通信経路上に循環が生じることがありうるので、ユーザーのリクエスト処理の経路内でレイヤー内通信をするのは避けるようにした方が良いでしょう。 その代わりに、クライアントに通信をしてもらうようにしましょう。 例えば、フロントエンドがバックエンドに通信したものの、そのバックエンドの選択が適切ではなかった場合、そのバックエンドは適切なバックエンドへのプロキシとして振る舞うべきではありません。 その代わりに、問題のバックエンドがフロントエンドに対し、適切なバックエンドへリクエストのリトライを行うよう伝えさせてください。

下記の例だと key17001 番ポートで動いているNodeにあると教えてくれます。

$ telnet localhost 7000
get key1
-MOVED 9189 127.0.0.1:7001
quit
+OK

7001 番に繋ぎ直すと今度はリダイレクトを要求されなくなりました。(セットしていないため値は空)

$ telnet localhost 7001
get key1
$-1

Resharding

Cluster稼動中にshardingに偏りが目立ってきたり、新しいNodeを追加してさらに分散させたいときとかに Resharding ができます。 手動で CLUSTER コマンドを打ってもできますが、煩雑なので基本的には redis-trib.rb などの運用ツールを使います。

Resharding中は特殊なResponseが返る場合があります。Reshardingの流れは以下です。

  1. 移動先Nodeに対して CLUSTER SETSLOT コマンドで CLUSTER SETSLOT Slot値 IMPORTING 移動元NodeID を打って開始宣言する
  2. 移動元Nodeに対して CLUSTER SETSLOT コマンドで CLUSTER SETSLOT Slot値 MIGRATING 移動先NodeID を打って開始宣言する
  3. 移動元Nodeに対して CLUSTER GETKEYSINSLOT コマンドを打ってKeyリストを得る
  4. 移動元Nodeに対して MIGRATE コマンドを打ってKeyたちを移動させていく
  5. 任意のNodeに対して CLUSTER SETSLOT コマンドで CLUSTER SETSLOT Slot値 NODE 移動先NodeID を打って移動したSlotの所在を確定させる

この1, 2番の宣言から5番の確定までの間にRedisは -ASK というResponseを返す場合があります。RequestしたKeyが今どっちのNodeにあるか ASKING で尋ねる必要があるためです。

RedisのCluster Mode Clientの責務

Commandを正確に対象Nodeに送信する

Redis Cluster Clientは最悪Redirectionのみ対応できていれば機能はします。ですが無駄な通信は発生させない方が良いのでCommand送信先Nodeを正確に把握している必要があります。 基本的には以下の工程が必要になります。

  1. 送信するCommandからKeyを抽出する
  2. KeyからSlot値を算出する
  3. Slot値からNodeを特定する
  4. Scale Readしている場合は更新系コマンドはMaster Nodeに、参照系コマンドはSlave Nodeに送信する

Commandの細かな情報、Keyの位置や更新/参照系などは COMMAND コマンドが教えてくれます。 4番のScale Readは READONLY コマンドをSlave Nodeに打つと使えるようになります。

Redirection対応はあくまで上記のNode特定から漏れたときのセーフティネットと考えておいた方が良いかと思います。 また、Redirection対応に加えてResharding中のResponseの対応も必要です。 仕様ドキュメント にも以下の記述があります。

A client must be also able to handle -ASK redirections that are described later in this document, otherwise it is not a complete Redis Cluster client.

Commandごとの性質の違いを考慮する

RedisのCommandSET GET のようなものからPub/Sub、Luaスクリプトなど多岐にわたります。

単純にKeyを指定する系のCommandは普通にKeyからSlot値を得てNodeを特定して送信できます。

KEYS などのCommandはすべてのNodeに対して送信して結果をマージする必要があります。 しかしそもそも計算量の大きいCommandなので本番環境で使う機会はないでしょう。

Luaスクリプト は各Nodeに登録してあげないと不便です。単一Nodeに登録しても他のNodeでは使えません。

Pub/Sub コマンドだけは例外で、Redis ClusterではどのNodeに対して送信しても 伝搬 して動作してくれます。

Transaction対応

Transaction は2パターンの使い方があります。

  1. MULTI などのコマンドを個別に送信する
  2. Pipelining で一度に送る

Redis Clusterだと1番のやり方に問題が発生します。 MULTI を打つときにどのNodeに対して打てば良いのかわからないためです。 Redis ClusterのShardingはCommandのKeyに対して分散させるため、KeyのないCommandは送信先Nodeを特定できません。

よって2番の Pipelining を使ってTransactionをまとめて単一Nodeに送信することになります。

また2番でもTransaction内のCommandのKeyが複数Nodeに対するものであった場合に一貫性が保てません。 TransactionをNodeを跨いで担保することはできないため、ユーザーはTransaction内で単一Nodeにしかアクセスしないことを意識しないといけません。

Pipelining対応

Pipelining は悩ましい部分があります。 Transaction とは違い、複数Nodeに対するCommandが含まれていても、Clientソフト側でPipeliningを分割してあげて複数Nodeに送信してあげても良い気はします。 ですがたいていのClientソフトはTransactionでPipeliningを使用しているので、あんまり複雑にするよりはTransactionに合わせて単一Nodeのみに限定した方がシンプルになる気もします。 Redis Gem では後者のシンプルな方に倒しましたが議論の余地はあります。

Node変更対応

Clusterに対してNodeの追加やFailoverなどの変更が発生した場合にClientソフトは検知できないといけません。 CLUSTER NODES コマンドを使用すると最新のCluster情報を得ることができます。 Master/Slaveロールや割り当てられているSlot範囲などがわかります。

$ telnet localhost 7000
cluster nodes
$697
b22b58c1b9c711920a8e4e0d680ad19e842a54aa 127.0.0.1:7004 slave 27769953b7b22889a1d61c9aaf29d72b6931b0ff 0 1539232690326 5 connected
ebd83490643a0c129334dd47f6bfa761a0e72ef6 127.0.0.1:7002 master - 0 1539232690326 3 connected 10923-16383
50d8a34b0c9e10477587e9ed21e743c7852f05e4 127.0.0.1:7005 slave ebd83490643a0c129334dd47f6bfa761a0e72ef6 0 1539232691832 3 connected
5447d2b5ab8a0efff66d55a392099f142d30296c 127.0.0.1:7000 master - 0 1539232691330 1 connected 0-5460
27769953b7b22889a1d61c9aaf29d72b6931b0ff 127.0.0.1:7001 myself,master - 0 0 2 connected 5461-10922
b01855140ec22f9da217f3c379bcc4e0e33b6c78 127.0.0.1:7003 slave 5447d2b5ab8a0efff66d55a392099f142d30296c 0 1539232689826 4 connected

b22b58c1b9c711920a8e4e0d680ad19e842a54aa などの文字列はRedis Clusterが内部で管理しているNode IDです。 これとは別に 127.0.0.1:7000 などのIPとPORTの組み合わせ文字列で特定するケースもあるので、Node特定時にはコンテキストに応じて使い分けが必要です。

Redis Gemについて

Redis Gem はスター数も少なくはなく、Ruby界隈で主流のRedis Clientソフトです。 Ezra Zygmuntowicz さんが最初に実装したらしいです。

Cluster Modeの使い方

2018年10月現在、GitHubのエッジ版、または 4.1.0.beta1 のバージョンでCluster Modeを使用できます。

# Nodeごとの接続情報を配列でclusterオプションに渡します。
nodes = (7000..7005).map { |port| "redis://127.0.0.1:#{port}" }
redis = Redis.new(cluster: nodes)

# Nodeの接続情報は1つだけでも構いません。
# 内部で引数で指定されたNodeに対してCLUSTERコマンドを打ってNode情報を取り直しているからです。
redis = Redis.new(cluster: %w[redis://127.0.0.1:7000])

# Scale Readさせたい場合はreplicaオプションをtrueに指定します。
# デフォルトはfalseでMaster Nodeしか接続しません。
Redis.new(cluster: nodes, replica: true)

redis-rails Gemを使ってRailsアプリケーションでSession StoreやCache Storeとして使う場合は以下の設定で動きます。 なおRails5.2ではこのGemを使わなくてもActiveSupport側でCache Storeが使えるようになっているみたいです。 リリースノート

Rails.application.configure do
  # Redis Session Store (redis-rails Gem)
  nodes = (7000..7005).map { |port| "redis://localhost:#{port}/0/session" }
  config.session_store :redis_store, servers: { cluster: nodes }, expires_in: 1.month

  # Redis Cache Store (redis-rails Gem)
  nodes = (7000..7005).map { |port| "redis://localhost:#{port}/0" }
  config.cache_store = :redis_store, { cluster: nodes }

  # Redis Cache Store (ActiveSupport)
  nodes = (7000..7005).map { |port| "redis://localhost:#{port}/0" }
  config.cache_store = :redis_cache_store, { cluster: nodes }
end

Redis::Distributedについて

これはClient側でキー分散をサポートしている機能で こちら で言及されているやつです。

Clients supporting consistent hashing

Redis Cluster Modeとは一切関係がありません。こちらのRedisはノーマルモードで起動したものに対して使うみたいです。

なので Redis Gem は3つのモードをサポートしていることになります。

  1. 単一ノーマルRedisのClient
  2. Client側でサポートしている分散モードのClient Redis::Distributed
  3. Redis Cluster ModeのClient (今回私が実装したやつ)

Redis::Distributed は一部のCommandに対応していなかったり可用性も別に担保しないといけなかったりします。 一度削除されかけましたが周辺Gemがこれに依存している部分もあって反発に合い、Redis側にCluster Modeが誕生した現在でもまだ残っています。

構成

Redis クラスに公開インターフェースが揃ってます。ここにないCommandは method_missing に拾われます。 Redis クラスではCommandを配列として加工して後述の Client クラスに渡し、サーバーからのResponseをRuby用に最終加工したりしてます。 Redisからの生Responseは各種接続Driverが最低限のRuby用加工だけやってくれます。そこから先のBoolean化やHash化などのリッチデータ化の加工は Redis クラスでやってます。

接続周りの煩雑な処理は Client クラスに委譲されてます。 Cluster Modeでは Cluster クラスに委譲し Cluster クラスは内部で Client クラスに委譲しています。

Redis::Distributed クラスはその設計から外れていて独自に公開インターフェースを定義しています。 なので Redis クラスと Redis::Distributed の二重メンテが発生しています。

テスト

CIの設定ファイル を見るとRubyとRedisの各バージョンと各種接続DriverとのMatrixでテストされていることがわかります。

ローカルでテストする場合もCIと同じく make を使うと楽な気がします。私は最初は手元でDockerでコンテナを利用していましたが最終的には make を利用しました。

$ bundle install --path=.bundle
$ make start          # ノーマルの単一Redisが起動
$ make start_cluster  # Cluster Mode用のRedis6台が起動
$ make create_cluster # redis-trib.rb や redis-cli でClusterを組む
$ make test           # テストを通しで実行
$ make stop           # ノーマルの単一Redisの停止
$ make stop_cluster   # Cluster Mode用のRedis6台の停止

./tmp/* 配下に資源をダウンロードしてビルドして動かします。初回は redis-server 実行ファイルの生成に時間がかかりますが、以降はRedis本体側に更新がなければその工程はスキップされます。 テストを1ファイル単発で実行したいときは以下のように実行できます。

$ bundle exec ruby -w -Itest test/hogehoge_test.rb

テストツールは test-unit を使ってます。 minitest ではありません。

テストにおける共通処理やsetup/teardown系の処理は ヘルパー に記述されています。

Redisの基本データ型であるHash, List, Set, SortedSet, Stringなどのテストケースは Lint に定義されて共通化されています。 Single Mode Client Redis::Distributed Cluster Mode Client ではこれらを include してテストしてます。

モック はスレッドを立ててRedisプロトコルをしゃべらせて使ってます。 引数でコマンドとその生Responseを指定する形で使います。

def test_hogehoge
  redis_mock(save: ->(*_) { '+OK' }) do |redis|
    assert_equal 'OK', redis.save
  end
end

Redisのバージョンごとに異なるテストケースではバージョン指定ヘルパーを使って限定します。引数で指定したバージョン以降のRedisでないとテストが実行されなくなります。

def test_fugafuga
  target_version '3.2.0' do
    # test code
  end
end

反省 x お願い x これから

反省: 英語力の必要性

お恥ずかしながら私は致命的に英語ができません。今回のPull Requestでは英語ができないとスタートラインにすら立てないことを再認識させられました。 レビュアーの方にも私のカタコト英語にお付き合いいただき申し訳ない気持ちでいっぱいです。勉強します。

お願い: リアルワールドの高負荷環境での動作確認

現在マッハバイトでは Redis Gem のCluster Mode対応版である 4.1.0.beta1 を本番環境で使用しております。Scale ReadはせずにMaster Nodeのみを使用しております。

マッハバイトの本番環境は基本的にオンプレで、Redis Clusterもデータセンターで稼動しています。 Pull Requestでいただいたコメント ではCluster ModeをONにしたAWSのElastiCacheでも動作報告があがってます。

マッハバイトでは動作しても、より大規模で高負荷なサービスでこの 4.1.0.beta1 を使用したときに、ちゃんと長期的に動作し続けられるか見えない部分があります。 もし良かったらRubyで組まれてる他のサービスでも試験的に導入いただき、フィードバックをもらえたらうれしいです。

これから: TODO

  • マッハバイトのセッションまわりの独自実装を定番ライブラリを使うように修正(Must)
  • Redis Gem にてREADMEにCluster Modeについて追記(Should)
  • Redis Gem にてRedis5から使えるようになるらしい Streams の対応(Want)

合わせて読みたい

エンジニア学生支援プロジェクト "Code for Happiness" を開催しました

こんにちは、人事の羽山です。 リブセンスでは、今年からCode for Happinessという学生エンジニアの支援プロジェクトをはじめました。 9月28日を以って約2ヶ月にわたるプロジェクトが終了したので、その報告をさせていただきます。

f:id:livesense-blog:20181005102258p:plain

Code for Happinessとは?

エンジニアリングを通じて社会課題解決を目指す学生の開発を支援するプロジェクトです。支援対象の学生には、開発費として一人あたり50万円の支援金提供とリブセンス在籍エンジニアによる約2ヶ月の開発サポートを行いました。

幸せから生まれる幸せ を企業理念に掲げ あたりまえを発明しよう というビジョンへ向かうリブセンス。そこには、社会を豊かにする新しい価値を生み出し続けたい思いが込められています。もともとは、リブセンスも学生同士で起業した会社です。しかし、志はあるけど費用面や技術面などの問題で実現できていない学生もたくさんいます。彼らを支援したい思いで立ち上げたのが今回のプロジェクトです。

リブセンスとしても今年がはじめての取り組み。果たしてどんな展開を迎えるのか、運営側の私も緊張しながらプロジェクト初日を迎えました。

最終審査に臨んだのは3チーム!

Code for Happinessでは、書類審査通過者が約2ヶ月の開発に臨みます。中間審査・最終審査を経て通過者には50万円の開発費支援が行われます。今回は総勢47名 (23チーム) からの応募がありました。最大6名を支援する予定で書類選考を行い、5名 (4チーム) の応募が採択されました。

私達がしたいのはビジネスコンテストでなく、志がある学生への開発支援です。提案の優劣はつけません。どの応募も独自の創意工夫があり、技術的にチャレンジしていて、審査員も頭を悩ませました。その中でも、世に出たときの社会的価値と開発の実現可能性を考慮し、最終審査に残ったのが下記3つの提案です。

プロダクト: vote

  • 起案者
    • 辰巳憲太郎さん (一橋大学4年)
  • キャッチコピー
    • 政治に対する意見発信をより身近に
  • 概要
    • 政治に関する意見発信は日本ではタブーとされており、リアルな会話においてもSNSに関してもなかなか議論しにくいという現状がある。このような問題を解決するため、Voteというサービスを開発。機能は三つあり、1. リアルタイム世論調査 2. 政治ニュースの閲覧機能、意見交換機能 3. 政治専門SNSを使用できる。各機能は匿名で利用でき、より手軽の政治的な意見発信を行うことができる。

プロダクト: HiTrip

  • 起案者
    • 小貫将太さん (中央大学4年)
  • キャッチコピー
    • 何を "誰とするか" でひとり旅はもっと面白くなる
  • 概要
    • ひとり旅をする人は数多くいる一方、旅先でのコミュニケーションがなく孤独に感じている人も多いという課題があることに注目。それを解決するためにひとり旅の日本人旅行者が、旅先の地域に住む人が提供する地域体験に全員がひとりで予約できるサービスを開発。地域の体験に参加でき、地域に住む人や他のひとり旅行者と交流できる。

プロダクト: Connect

  • 起案者
    • 室田雅貴さん (新潟大学大学院修士1年)
    • 小林航大さん (新潟大学大学院修士1年)
  • キャッチコピー
    • 定番化したおでかけに新しいワクワクを
  • 概要
    • 地元の楽しみ方は地元の人が一番良くわかっている。でも観光ガイドブックではそれを知ることができない。ならば、地元の人が案内すれば良い。そんな発想から生まれたサービスが「Connect」です。自分たちが訪れたスポットを地図上に点として投稿。それを続けることで観光コースが出来上がります。投稿者の体験に基づいたコースなので、観光ガイドブックとは違う発見に出会えます。

最終審査の結果は...

学生より各チーム20分の発表を行った後、審査員の能登 (VP of Engineering) より審査結果の発表です。

f:id:livesense-blog:20181005102313j:plain

結果は、全員最終審査通過!学生の皆さん、改めておめでとうございます!

学生インタビュー

最後に、感想を学生にインタビューしました。みんないいこと言うものだから、運営側の私も目頭が熱くなります。涙を隠しながら話を聴かせてもらいました。

小貫将太さん (中央大学4年)

f:id:livesense-blog:20181005103826j:plain 応募のきっかけは、私自身起業をしているのですがまだ自社のプロダクトがなく、自分たちのプロダクトを持ちたいと思ったためです。今回のプログラムでは、リブセンスから技術と開発費の援助をいただけるとのことだったので、これはチャンスと思い応募してみました。 プロジェクトは山あり谷ありでしたね (苦笑) 実は、応募時に提案したサービスと、最終的に出来上がったサービスが完全に別物なんです。開始1ヶ月はずっとメンターとプランの壁打ちでした。ほとんど開発していません (笑) コアバリューを定義し直したり、案出し100本ノックをしたり…悩み続けていましたが、その結果思い切ってプランを変更。 今回提案した「HiTrip」の開発を行いました。自分のやりたいことにたどり着けたのだから、必ずリリースします。楽しみにしていてください! そして、一緒にサービスを大きくしてくれる仲間も募集中です!

辰巳憲太郎さん (一橋大学4年)

f:id:livesense-blog:20181005103814j:plain Twitterでフォローしてた桂さん (リブセンス桂大介) のTweetを見てCode for happinessを知りました。以前よりアプリをリリースたことはあったのですが、ちょうど新しいものを作りたいと思ったタイミングだったので応募しました。 メンターからは新しい知識をたくさん教えてもらいました。企業が実際にどうアプリを実装しているか、運用しているかなどのノウハウは働いている人に聴かないとわかりません。そういったインターネットで検索しても出てこない情報は目から鱗でした。今回開発した「Vote」は日本ではタブーとされがちな政治の領域に踏み込んでいます。アプリの性質上、リリース後アプリが荒れる可能性あると正直思ってます。それでも、世の中がどう動くのか検証してみたい思いが強いです。 リリースまであとひと踏ん張り頑張ります!

室田雅貴さん・小林航大さん (新潟大学)

f:id:livesense-blog:20181005103759j:plain 今回のプロジェクトを一言で言うならば「青春」でしたね。特に最後の数週間は二人で研究室に篭り一日中開発してました。スタートアップの立ち上げってきっとこんな感じなんだろうなと思ってました (笑) 実は以前から新潟を良くするサービスを作りたいと思ってたんです。でもなかなか行動できずにいました。だからCode for happinessを知った時には背中を押された気分でした。正直、書類審査を通ると思っていなかったので通過の報せをもらったときは驚きましたが、それで覚悟が決まりました。 開発を始めるとたくさんの気づきがありました。一番衝撃だったのは「自分たちよりもユーザーの欲しいものを優先したくなる」感覚です。今回はリリースする前提なので、ユーザーが欲しいものを作る必要があります。そうなると、どんどん自分でなくユーザーに目が向いていくんです。この夏の青春で終わらぬよう、これからも努力していきたいです。そして、今回が人生初のリリースです。たくさんの人に使われるとを考えると緊張しますが、たくさんの人に使ってもらえるならばそれは幸せなことです。ユーザーからのフィードバックを得ながらどんどん良いものにしていきたいと思います!

まとめ

リブセンスとして初の取り組みということもあり、運営側も企画から運営まで試行錯誤の繰り返しでした。 でも、最後に学生から「一歩踏み出すことができた」「必ずプロダクトをリリースする」等前向きな言葉を聴けて、開催して本当によかったと実感しています。 これからもリブセンスは世の中を豊かにする あたらしいあたりまえ の発明に取り組んでいきます。少しでも興味あれば、コチラ Livesense Engineering Contact からお気軽にお問い合わせください。

f:id:livesense-blog:20181005103600j:plain 学生とメンター、審査員の村上 (リブセンス代表取締役社長)・能登 (VP of Engineering)・桂 (リブセンス共同創業者) で記念写真

画像配信システムにCDNの導入を試みた話

こんにちは。9月よりインターンとして参加しているインフラグループの幸田です。
現在リブセンスでは、高速化の取り組みを進めており、その一環として今回は画像配信システムへのCDN導入検証を行いました。

この記事では導入検証を通して見つけた、最低限確認しておきたい キャッシュヒット率 に関わる設定を2つ紹介します。

検証の背景とか

ステージング環境での検証 というフェーズで、インターン課題として取り組みました。
最低限キャッシュを無視する設定(PASS設定)しかされておらず、まさに「とりあえず通してある」という感じです。

ここから本番環境へ導入を進めるための導入検証をはじめました。

前提とか設定とか

前提として、今回導入検証を行うのは画像の配信を専門に行う 画像配信システム です。
CDNには Fastly を使用しました。
(以下Fastlyに合わせて画像配信システムのことを Origin と表現します)

ステージング環境は社内からしかアクセスできないので、そのままだとキャッシュヒット率の計測がうまく行えません。
そのため今回検証するステージングのOriginには、本番トラフィックの1/3をミラーリングし、ある程度トラフィックを確保した状態で、動作確認や検証を行いました。
この時点でのキャッシュヒット率は平均で30%~35%程でした。

とりあえずやってみよう

「キャッシュさせて高速にコンテンツを配信する」という観点で見た時、キャッシュヒット率が低くCDNとしての役割を果たせていないと思ったので「 思い当たる設定を見てみる 」ことにしました。

まずはTTLの設定を見てみる

キャッシュの話になった時、初めに思い浮かぶ設定値といえばTTL(Time to live)ではないでしょうか。
TTLは「どのくらいの期間キャッシュとして保持するか」という設定です。

Origin側の設定ファイルを確認しましたが指定はなく、更に前提でも書いたようにFastlyで明示的な設定も施していませんでした。

TTL指定しなかったらどうなる?

Fastlyではデフォルト値としてTTLが 120s に設定されています。
OriginやFastlyで特に指定がない場合はこの数値が適用されます。

つまり2分間だけキャッシュとして保持され、期限が切れるとOriginから取得して再度2分間キャッシュするという動きになります。
そのためキャッシュヒット率低下に繋がります。

TTLを設定する

「明示的にTTLを設定しなかったために 120s が適用され、キャッシュされる時間が短かった」というのが今回の原因なので、 明示的にTTLの値を設定 してみましょう。

TTLの設定方法はいくつかありますが、今回はOriginで Surrogate-Control というヘッダを付与して設定しました。
ヘッダに関する詳しい内容はこちらを参照してください。

nginxでの設定例です。

+    add_header Surrogate-Control "max-age=604800";

Surrogate-Control は今回で言うとFastlyなど 間に入るProxyサーバにのみ有効なTTL値を設定するためのヘッダ です。

通常 Cache-Control で設定したTTLはブラウザなどにも適用されますが、 Surrogate-Control は今回の場合だと、Fastlyだけで取り扱われ、その後取り除かれます。
そのためブラウザからこのヘッダは確認できません。

今回の Surrogate-Control の値は 604800s1 にしてみました。

TTLの設定値について

今回は「検証のために、ある程度長くしてみよう」という考えから 604800s を指定しましたが、本当にこの設定値が適切なのでしょうか。

個人的には正解がないような気がしていて、扱うコンテンツによっても変わってくるものだと思います。
なのでこのあたりの設定値は、コンテンツの種類や更新頻度を総合的に判断した上で設定する必要があります。

例えば、

  • あまり更新されることがないから、(仮に、少しの間古い情報が返されたとしても)大きな問題がない場合
  • そこそこ高頻度で更新されるので、数日間保持されると困る場合

など。
「すぐに更新してくれないと困るものなのか?」や「逆にちょっとくらい遅れても困らないものなのか?」という点に着目するとより適切な設定ができるかと思います。

極端な話をすると「何ヶ月も更新されることがないのであれば、何ヶ月も保持していい」ので。

キャッシュの更新どうする?

またキャッシュの更新をTTLだけに任せると「TTLが過ぎるまではOriginでコンテンツが更新されても、キャッシュされた古いコンテンツを返すのか?」という話も出てきます。

これについては、 CacheBusting と呼ばれる手法を用いることで解決することができます。
GETパラメータで更新日時などを付け加えて別のURLにすることによって、再取得させる方法です。

それ以外にもFastlyには 強力なPurge機能 が備わっています。Purge機能とはキャッシュを削除する機能です。
Originでコンテンツを更新した時にこのAPIを叩くような実装をすると、すぐ(ミリ秒単位)にFastly上からキャッシュを削除することができます。
CacheBusting の場合だとTTLが過ぎるまではサーバ上に残ることになるので、少しだけセンシティブな内容を扱う時はPurgeするやり方がオススメです。

ん?ブラウザ変えたらHITしなくなるな?

キャッシュのHIT,MISSの洗い出しをしようと思い、主にGoogleChromeのDevToolsを眺めていました。
普段はFirefoxを使用しているのですが、DevToolsが優秀なのでこういう検証をする時にはChromeも使っています。

その過程で「Firefoxで何度も表示させていたページを、Chromeで確認するとMISSになる」という現象から、User-Agent(以下UA)を取り扱うVaryヘッダに目をつけました。

Varyヘッダを取り扱うとどうなるか

そもそもVaryヘッダは「同一のURLでもヘッダの内容が違うから、別のコンテンツとして扱ったよ。キャッシュとかするならそこらへんよろしくね」という命令にあたります。
よくある例だと、UAのデバイスの情報をもとにコンテンツの出し分けを行っている時、CDNやL7LBに別物として認識させるようなケースでしょうか。

Fastlyでは2特に指定をしない限り、Varyヘッダを取り扱います。
つまりUAなどが含まれていた場合、 UA毎にキャッシュを生成します
UAはクライアントの様々な情報を格納しているため種類が多く、キャッシュヒット率に影響します。

今回の場合だとOriginでUAが付与されていたため、まさに「UA毎にキャッシュが生成されている」という状態でした。

じゃあVaryヘッダ消そう

この問題に対する対処法はいくつかあります。

  • FastlyでVaryヘッダを削除してキャッシュする
  • OriginでVaryヘッダを適切に設定する
  • FastlyでUAを正規化する

など。

今回は1つ目の、 FastlyでVaryヘッダを削除してキャッシュする という方法を採用しました。

前提でも話したように、今回対象となるのは画像配信システムであり画像以外のコンテンツを扱っていません。
またUAを利用してのコンテンツの出し分けも行っていないため 「 Varyヘッダを扱う必要がない 」 という理由から、削除する方法を取りました。
VaryヘッダにはUA以外にも Accept-Encoding なども含まれていますが、今回の場合は不要なので削除しました。

それ以外にも「FastlyのダッシュボードからGUIで設定可能であり、素早く試せる」というのも理由の1つです。

設定

Fastlyの設定画面からGUIで設定することができます。

1.対象のダッシュボード画面を開きます。
2.[CONFIGURE]を開いて、CONFIGURATION > Clone activeをクリックします。これで現在の設定がCloneされます。
3.サイドメニューより[Content]を開き、CREATE HEADERから画像のように設定します。
f:id:livesense-blog:20180914173330p:plain

効果を確認

時系列で話すと、Varyヘッダの削除→TTLの設定という順番で検証を行いました。
なので、Varyヘッダの設定を入れたのが左の赤ラインで、TTLの設定を入れたのが右の赤ラインです。
当初平均で30%程だったヒット率が今だと平均で80%近くまで上がってきています。

  • Varyヘッダの設定単体で見ると、約20%UP
  • TTLの設定単体で見ると、約25%UP

といった感じです。 f:id:livesense-blog:20180914173345p:plain

おわりに

この記事では最低限チェックしたいポイントを上げましたが、他にもヒット率を上げるための方法はいくつもあると思います。
また今回は画像配信だけを行うシステムを対象にしたのであまり複雑な設定をしなくても済みましたが、他のコンテンツも扱う場合だとUAが必要になったりなど色々複雑になってきます。
特に 個人情報などセンシティブな内容が絡んでくる場合は、設定を慎重に行う必要があります。

FastlyではVCLと呼ばれる言語を利用して複雑な処理を行うこともできるので、工夫次第でもっと最適な設定ができそうですね。

おまけ:感想的な何か

2週間という短い期間でしたが、内容の濃いインターンでした。
「なんかFastly流行ってるしカッコいいからこれがいい」という理由で、インターン課題を選定しましたがCDNに対する理解がより一層深まりました。
また技術的な部分はもちろん、ドキュメントを作成する時のコツなどそれ以外のこともたくさん学べました。

インターン時は「コーヒーの伝道師」と呼ばれ、社員の方に慕われたりなどすごく楽しかったです(笑)

最終日の焼肉も美味しかったです!関わってくださった社員の皆様ありがとうございました!


  1. 604800s = 1週間

  2. デフォルトのVaryヘッダの取り扱い方については、各CDNによって異なるので注意が必要です。

GopherCon 2018に行ってきました!

イエシルでサーバーサイドエンジニアをしている@mom0tomoです。
コロラド州デンバーで行われたGopherCon 2018に、会社から支援金を受けて行ってきました。

海外カンファレンスに参加するのは初めてだったので、新鮮なことばかりで毎日がとても刺激的でした。 今回は中でも特に印象に残った出来事をご紹介します。

なぜGopherConなのか?

わたしはふだんRuby on Railsを使っていますが、リブセンスでは一部のシステムでGoが使われています。

また、わたしはプライベートでWomen Who Go Tokyoというコミュニティの運営スタッフとしてイベントを主催しており、国際的なカンファレンスに参加して世界のGopherと会うことで、自分自身の技術に対するモチベーションをあげること、またそこで受けた刺激を社内外に伝えることを目的として参加しました。

f:id:mom0tomo:20180913053302j:plain
Women Who Goの仲間と

カンファレンスの日程

2018年のGopherConは4日間にわたって開催されました。

1日目はプレイベントとして、様々なワークショップが開かれました。
ワークショップのチケットは別に購入する必要があるため、ワークショップには参加しないけれども会場内をぶらぶらするという人も見られました。

わたしはBuffaloというRails likeなフレームワークを使ったWeb Developmentのワークショップに参加しました。
朝から1日かけて一通りの開発ができるようになるまで、開発者自ら講師になっていただきながら、初心者でもわかるように丁寧に教えていただきました。

他にも機械学習やパフォーマンス改善など、同時開催なのでひとつしか参加できないのが惜しいほど多種多様なワークショップが開催されていました。

f:id:mom0tomo:20180913052606j:plain
会場外観

2日目と3日目が本編で、大小のルームでセッションやトークが行われました。
また、2日目の夜には公式のパーティが野外で盛大に行われました。「Gopher Band」というバンドが登場し、迫力あるロックの生演奏を前にみんなでお酒を飲んだりご飯を食べたり、夜もふけるまで楽しく過ごしました。

f:id:mom0tomo:20180911221343p:plain
Gopher Band

最終日はコミュニティデーということで、OSSへのコントリビュートの仕方や実際に機器を使ったIoT開発のワークショップ、GoogleのGo開発チームの議論に参加できる時間などが取られていました。

最終日を待たずに帰ってしまう方もいるようで、コミュニティデーは本編よりも参加者は少なめでしたが、少人数だからこそのメリットを生かし、参加者同士やOSS開発者、コミュニティのリーダーの方との交流をじっくり取ることができて、充実感のある内容でした。

f:id:mom0tomo:20180911214649p:plain
コミュニティデー

わたしはOSSにコントリビュートするワークショップに参加し、athensというプロジェクトを用いてコントリビュートの基本的な方法を学びました。

ワークショップでははじめに、OSSにコントリビュートする上での心構え(気張らずに、みんなのためにコントリビュートしよう)や、初めてのコントリビュートまでの流れやオススメポイントなどをお話しいただきました。OSSへの熱い想いのこもったトークはわくわくするもので、その後すぐに同じテーブルの参加者とわいわい楽しく開発をはじめました。

華々しいオープニング・クロージングトーク

2日目の本編は、TEDさながらの迫力あるトークで幕を上げました。

f:id:mom0tomo:20180911214709p:plain
オープニング

トーク中はリアルタイムで正確な文章起こしがディスプレイに流れており、会場はみな驚きました。

Goを使った何らかの技術を使っているのか、はたまた人間が文字起こしをしているのか?と話題になっていましたが、どうやらプロの筆記者の方が数名その場でタイピングしていたようです。

いずれにせよ、オープニングおよびクロージングトークは非英語ネイティブでも容易に内容が理解できて楽しめる一つのコンテンツになっていました。

LTを含む全てのトークはyoutubeで視聴することができます。
Gopher Academy - YouTube

コミュニケーション、ネットワーキングの時間

日本で自身が参加したことのあるカンファレンスや技術イベントと比べて特に違いが目立ったのは、参加者の方々が対面でのコミュニケーションに注力していることでした。

いままでわたしが国内で参加した技術イベントでは、Twitterのタイムラインを追うとイベントの流れがわかるというほど、Twitterでのコミュニケーションが盛んでした。
しかし、GopherConは参加者の人数が多い割にハッシュタグを追ってもあまり情報が流れて来ません。

不思議に思って仲良くなったアメリカからの参加者の方に聞いて見たところ、普段会えない人と対面でコミュニケーションをとり、ネットワークをつなぐことで今後のコミュニケーションを円滑にしたり仕事に繋げることが目的としていると教えてもらい、違いに納得しました。

ネットワーキングの時間は朝食、ランチ、パーティなどふんだんに用意されていて、参加者の皆さんも気さくな方が多いのでテーブルで話が弾みます。 またコミュニケーションの時間にはセッションの感想等を話し合ったり、人によっては直接スピーカーに話しかけに行ったり、対面での会話や議論が多数交わされていました。

参加していない人も楽しめるTwitter実況は便利だと思う一方、対面でコミュニケーションの輪を広げて行くスタイルも参加する醍醐味を感じられて良いと思いました。

もちろん参加者全員がコミュニケーションが得意というわけではなく、大勢の知らない人と話すのは苦手だという人もいたり、自分なりのトーク技術を公開している人もいました。

わたしも初対面の人と話すのは得意ではありませんが、参加者はオープンに話題を振ってくれる気さくな人ばかりだったので、居心地よく過ごすことができました。

また公式のパーティに加え、現地のGopherによるmeet upやWomen Who Goディナーなど、知り合いをつくって交流するためのイベントが複数開かれていました。

印象的だったセッション

全てのセッションとトークが魅力的でしたが、ここでは特に気づきの大きかったものとして、アクセシビリティについてのセッションをご紹介します。

このセッションでは、目の不自由な方がエディタのコード読み上げ機能を使ってプログラミングをする例を挙げ、実際の読み上げ音声を使いながらアクセシブルなコードとは何かを説明していただきました。

一例を挙げれば、Goでは変数名を短くする、また型名の後ろに変数名を書くという特徴があります。

短い変数名が先に来て型名が後に来ることにより、エディタ等のコード読み上げ機能を使うプログラマにとって、素早く変数名を聞き取りすぐに意味を捉えることができます。


ロジカルに書くこと。
発音できるように書くこと。
首尾一貫して書くこと。


どれもコードを書く上で意識すべきと言われている基本的な原則ですが、アクセシビリティと関連づけて考えられたことはあまりないのではないでしょうか。

アクセシビリティに配慮して書かれたコードは、みんなにとって良いコードになる。

この言葉がひときわ輝く、すばらしいセッションでした。

下記にセッションの内容がアップされています。
ぜひ皆さんもご覧ください。

Writing Accessible Go

Go2に向けてのドラフトの話

2日目の午前のセッションが終わったと同時に、突如ビデオメッセージが流れ始めました。

話し手はあのRuss Coxさん!内容はGo2のドラフト構想についての発表で、会場は興奮の渦に包まれました。

f:id:mom0tomo:20180913052845p:plain
Russ Cox氏

詳しくは下記のページからアクセスできます。 https://go.googlesource.com/proposal/+/master/design/go2draft.md

また、日本語で意見を述べることが可能なフォームもあるので、興味のある方はのぞいてみてはいかがでしょうか。

おわりに

リブセンスでは半期に1名海外カンファレンスのための渡航費等を支援しており、誰でも立候補することができます。 もちろん, 海外カンファレンスには登壇者として招待されて行くのが憧れですが、すべてのエンジニアにチャンスが与えられるのは意義深いことです。

今回のGopherCon参加では概算で40万円ほどかかりましたが、その費用のほとんどを会社に負担してもらいました。
4日間のカンファレンス参加チケットに宿代等を合わせると小さくない金額になるので、支援してくれた会社に感謝しています。

今回の記事を読んでいただき、海外カンファレンスに行きたいと思った方、自分ならこんなものを持ち帰ってくるというアイディアのある方は、 ぜひリブセンスにお越しください。

リブセンスでは一緒に働きたい!という方をお待ちしています。

Tech Award 2018を開催しました

こんにちは、就活会議でエンジニアをしている大政です。 リブセンスでは、昨年からTech Awardという技術表彰をはじめました。

Tech Awardとは

技術的に優れた取り組みであったり、事業のKPIに直接的にはつながりにくいレガシー改善について、直近1年間の業務として行った取り組みを表彰するイベントです。 Edge (先進的)とLegacy (レガシー改善) という2部門を設けて、プロジェクトごとにエントリーしてもらい、当日プレゼン発表をするというものです。 プレゼン発表はノウハウの共有・質疑応答を目的としたもので、詳細な内容はエントリー時に社内Wikiにドキュメントを記載していただき、プレゼンの上手さではなく、取り組みの内容で審査をしています。

f:id:taise:20180827143426j:plain
Tech Award 2018 の メインビジュアル

審査員のみなさん

社外からも素晴らしいエンジニアの方を招致して審査をしました。

f:id:taise:20180829140908j:plain
左から藤 吾郎さん(Bit Journey, Inc.) 、能登 信晴さん (Livesense Engineer Leader)、田中 勇輔さん (Akatsuki Inc.)

f:id:taise:20180829140938j:plain
谷村 琢也さん (Livesense 執行役員)、中野 悦史さん (Livesense インフラストラクチャーグループリーダー)

プログラム

Edge部門で3エントリー、Legacy部門で5エントリーありました。 どのエントリーも創意工夫であったり、技術的なチャレンジに溢れるものでした。そのうちのいくつかは、後日こちらのブログでもご紹介できると思います。

Edge部門

タイトル 概要
AB テスト : 多腕バンディット基盤 "Brain Optimizer” ABテスト / 多腕バンディットを社内の複数のサービスで実施出来る基盤の実装 / 構築
メルマガ配信基盤 KiKi キューワーカー型の大規模メルマガ配信基盤を作成し、10 年来の PHP フレームワーク上のバッチで動いていたメールマガジン群を移行
Heroku Private Spaces移行 HerokuのCommon Runtime環境(米国リージョンにある)で運用中のサービスを、Heroku Private Spaces(AWSの東京リージョン)に移行

Legacy部門

タイトル 概要
人は1年でAWSの環境をモダンに改善できるのか 設定内容や構築ドキュメントが残っていないAWS設定や運用サーバ自身の設定を「可視化」及び「コード管理」をして「変更のしやすさ」、「設定の適用」を容易にする
転職会議 同時登録フルリニューアル セキュリティサポートの切れた会員登録の基盤のアーキテクチャリニューアル
【転職会議】契約管理業務のシステム化 バックオフィスの方々が手動で運用・管理していた、転職会議BUSINESSの契約から請求までの一連のフローをシステム化
転職ドラフト:問い合わせ効率化 問い合わせフォームによくある単語を入力すると解決方法が表示される仕組み
転職会議 新商品:Business PR 開発(Cosmeticsプロジェクト) レガシーを避けながらAPIサーバーを作って新機能追加

プレゼン発表

プレゼン発表当日は、エンジニア・ディレクターを含めて50名以上がオーディエンスとして参加し、プレゼン発表は笑いあり感嘆ありで、リブセンスらしい大変あたたかい雰囲気で行われました。

Edge部門にエントリーされたプロジェクトは、まだ誰も踏み抜いていない技術的な問題に取り組んでノウハウが蓄積されていたり、スケーリングの問題を分散システムの構築で真っ向から解決して運用までしっかりのせていたりと、聴き応えのあるプレゼンばかりでした。

Legacy部門にエントリーされたプロジェクトは、避けることができないレガシーなコード/インフラとの戦いであったり、リブセンスの事業環境に依存した課題をエンジニアリングで解決したものが多く、表に出てきにくい工夫が詰まっていて非常に興味深いプレゼンばかりでした。

また、藤さん・田中さんから、本質的な鋭い質問をたくさんいただきました。発表者だけでなく、オーディエンスのエンジニアも大変刺激になったと思います。

f:id:taise:20180829141326j:plain

Tech Award 2018 大賞

昨年と今年のTech Awardは、Edge部門とLegacy部門の2部門で、それぞれ大賞を決めています。 両部門を合わせた総合1位のような賞を作っていないのは、技術的に先進的な取り組みも、レガシー改善も、今のリブセンスにはとても重要なもので、優劣つけられないと考えているためです。 なお、大賞を受賞すると少なくない額のAmazonギフト券が贈呈されます。

Edge部門: メルマガ配信基盤 KiKi

受賞者

KiKi 開発チーム

  • 岡前 直由
  • 山内 雅斗

受賞理由

  • 分散処理、並行処理、スケーラブルなアーキテクチャをちゃんと設計して作っている
  • 止まった時のリカバリや運用のことまで見据えて作っている

f:id:taise:20180829141240j:plain

Legacy部門: 人は1年でAWSの環境をモダンに改善できるのか

受賞者

  • 藤村 宗彦
  • 山浦 清透

受賞理由

  • AWS の改善に追従する仕組みを作っている、レガシーになりにくい仕組みになっている
  • 運用ルール決めるのが難しいが、それもやりきっている
  • コードで管理するのが当たり前となっている

f:id:taise:20180829141412j:plain

まとめ

リブセンスは、様々な事業領域で「新しいあたりまえを発明」して、ユーザーに価値を届けるべく日々試行錯誤をしています。 そしてそれには、いま以上に高い技術力が必要だと考えており、今回ご紹介したTech Awardを始めとした様々な施策が社内で行われています。

今年で2回目を迎えたTech Awardは、昨年から進化をして開催することができました。
果たして来年はどんな技術的に優れた事例が大賞を取るのか、いまから楽しみですね。
もしかしたら、この文章を読んでくださったあなたが手にしているかもしれません。

リブセンスでは優秀なエンジニアを募集しております。
ご応募お待ちしております。

募集情報 | 株式会社リブセンス | 採用情報

f:id:taise:20180829141735j:plain

回転寿司が会社にやってきた

はじめまして。 転職ナビでエンジニアをしている、negitorosanと申します。
事務職として 2015年6月リブセンスに入社しましたが、2016年1月からエンジニアに転向しました。

5月末、リブセンスのエンジニアを集めて『Engineer Drink UP』を行いました。
今回は、『Engineer Drink Up』を開催するまでのエピソードをご紹介します。

f:id:livesense-blog:20180615184546j:plain

Engineer Drink UPとは?

四半期ごとに開催される、リブセンスのエンジニアのための懇親会です。
エンジニアがあつまってお酒を飲みながら、LTをしたり、聞いたりして盛り上がり、普段なかなか交流のない別チームのエンジニア同士の横のつながりを強くすることを目的としています。
そして、毎回新鮮さを追求するために、下記の方針で開催しています。

  • 事業部毎の持ち回り制
  • 事業部の個性を発揮する

運営メンバーで話し合ったこと

まずは目標として、下記を設定しました。

  • 参加率の改善
  • 記憶に残る楽しい懇親会にする
  • LTの実施

参加率の改善

今までの懇親会では、エンジニア80名中30〜50名弱と、50%ほどの参加率でした。
どうして参加率が向上しないのかを話し合ったところ、下記のような問題点が見えてきました。

  1. 業務後に拘束されるのが嫌...
  2. オフィスから移動するのが嫌...
  3. 家庭があるため、夜は早めに帰らないといけない...
  4. 行かない人も多いのだから、自分も参加しなくてもいいだろうという気持ち...

2.に関しては大人数を収容できるセミナールームがオフィス内にあるため、大きな問題にならない見込みが立ちました。
そうなると、1.と3.を解決するにはどうしたらよいか。

私達が導き出した答えは・・・

業務時間に開催すればよい

業務時間内であれば、仕事の一環!
早く帰らないといけない人も参加できる!
あの人が行くなら自分も行こうかなと心揺れる人も増えるはず!
※ 弊社エンジニアは裁量労働制です。

記憶に残る楽しい懇親会にする

楽しいだけではなく、自分たちらしさ も出さなければいけません。
他の事業部と内容がカブってしまわないように注意が必要だったため、少し難航しました...
色々な案がでましたが、なかでもとびきりインパクトのあるものを選びました。

結論からいうと、会社内でお寿司を回しました。
自分たちでレーンを作りましたといえたら素敵ですが、出張回転寿司といったものがあるので、発注して当日設置してもらいました。

f:id:livesense-blog:20180615184724j:plain

今回利用したのは、サキガケサービスさんの「出張回転寿司(くるくる)」です。
https://www.sakigake-s.co.jp/sushi

実施時間は業務時間内の17:00〜19:00、場所はリブセンスのセミナールームで行いました。

結果

f:id:livesense-blog:20180615184833j:plain

70人弱のエンジニアが参加してくれました!!
回転寿司も好評だったようで、みなさん写真を撮ったりして楽しんでいたようです。
LTは、弊社の海外カンファレンス支援制度 を利用して Rails Conf 2018に参加した内山の体験談 や、今年度入社した新卒エンジニアからの熱い意気込みなど、様々なLTがありました。

ちなみに、 Engineer Drink Up 開催後に実施したアンケートの結果はこちらです。

f:id:livesense-blog:20180615184855p:plain f:id:livesense-blog:20180615184907p:plain f:id:livesense-blog:20180615184919p:plain

概ね、みなさんに楽しんでいただくことができました!!よかった!

懇親会を運営して得たもの

いままで話したことがなかった人と話す良いきっかけとなり、懇親会を開くことの大変さを知ることができました。
そして、この経験は業務にも活かしていくべきだなと感じました。

  • 問題点をみつけ
  • 改善策を練り
  • 準備を行い
  • 実行し
  • 振り返る

まさにPDCAですね。
参加メンバーが発言しやすい環境づくりを行い、準備し、実行する。
言葉にしてしまえばとても単純なことですが、その難しさと楽しさを再確認することができました!!

f:id:livesense-blog:20180619111155g:plain:w500

おまけ

出張回転寿司を頼む際の注意点

f:id:livesense-blog:20180619111219j:plain

1. 場所

回転寿司台を設置する関係、どうしても場所(テーブル 45cm × 180cmくらいのものを4~5台)と、職人さんの握り場所(1.8m四方位)が必要となります。
※さらにレーンなどを運んだ機材を置いておく場所も必要です。

2. 水場

調理器具などを洗う場所が必要になりますので、近くに水場があることも確認してください。

3. ネタ

各ネタの注文数には制限(最低参加人数の半分程度)があり、ネタの種類を多くし、それぞれの数を少なくする際は注意する必要があります。

DNS over HTTPSを使ってDNSレコードを外形監視

こんにちは、インフラグループの水野です。

みなさん、DNSのレコードの監視を行っていますか? DNSレコードの変更ミス等を検知することはもちろん、自分たちの運営しているサービスの名前解決がユーザ側でどのように見えているのかというのを確認することは大切です。

しかしながら、DNSレコードを外形監視してくれる監視ツールは数が少なく中々コレといったものがありません。 外部からの監視をしたいがためにパブリッククラウドに監視専用のインスタンスを建てるのももったいないです。

弊社ではメインの監視ツールとして Mackerel を利用していますが、MackerelにはURL外形監視はありますが、DNS外形監視はありません。 別途 pingdom のDNS外形監視を利用していましたが、pingdomではIPアドレスとのマッチしかできません。 IPアドレスもひとつしか登録できないため、ELBのようにIPアドレスが定期的に変わるCNAMEレコードなどを監視する際にはあまり相性がよくないという課題を抱えていました。

今回はDNS over HTTPSを使ってこの課題を解決した取り組みをご紹介したいと思います。

f:id:nashiox:20180518113217p:plain

DNS over HTTPS

DNS over HTTPS とは IETF1が標準化を進めているHTTPSを用いてDNSの通信を行う技術です。

従来のDNSの通信は主にUDPを用いて平文でやり取りされます。 この特徴はセキュリティ的にもプライバシー的にも問題視されており、その対策として誕生したのがDNS over HTTPSです。 既にGoogle Public DNSや先日話題となったCloudflareが提供を始めたパブリックDNSでもこの機能が提供されています。

従来のDNSのプロトコルで外形監視を行おうと思うと専用の機能が必要となりますが、HTTPのプロトコルを利用したURL外形監視であれば多くの監視ツールでサポートされています。 今回はこのDNS over HTTPSとMackerelのURL外形監視の機能を利用してDNSレコードの外形監視を実現します。

まずはDNS over HTTPSの動作を確認

今回はGoogle Public DNSCloudflareのパブリックDNS(1.1.1.1) 2つのDNS over HTTPSの機能を試してみたいと思います。 標準化が進んでるだけあってどちらもほとんど同じ使い勝手で使うことができます。

Google Public DNS

Google Public DNSのDNS over HTTPSではAPI版のURL(https://dns.google.com/resolve)、GUI版のURL(https://dns.google.com/query)が用意されています。 今回はAPI版を利用します。

サポートされているパラメータはいくつかありますが、name にFQDNを指定することでレコードを引くことができます。

$ curl -s 'https://dns.google.com/resolve?name=made.livesense.co.jp' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 195,
      "data": "hatenablog.com."
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 31,
      "data": "13.230.115.161"
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 31,
      "data": "13.115.18.61"
    }
  ]
}

上記のようにレコードを引くことができます。 Answer 部分が応答になっており、 type がレコードタイプ(1がAレコード、5がCNAMEレコード)、 data がレコードの値になります。

パラメータで type を指定すると指定タイプのレコードを引くこともできます。

$ curl -s 'https://dns.google.com/resolve?name=made.livesense.co.jp&type=CNAME' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 298,
      "data": "hatenablog.com."
    }
  ]
}

CloudflareのパブリックDNS(1.1.1.1)

CloudflareのパブリックDNSのDNS over HTTPS(https://cloudflare-dns.com/dns-query)ではDNS WireformatとJSONフォーマットがAPIで用意されています。 今回はJSONフォーマットを利用します。

パラメータはGoogle Public DNS同様、 nametype 、更にMIME Typeを指定する ct がサポートされています。

$ curl -s 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=made.livesense.co.jp' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 1
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 300,
      "data": "hatenablog.com."
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 24,
      "data": "13.115.18.61"
    },
    {
      "name": "hatenablog.com.",
      "type": 1,
      "TTL": 24,
      "data": "13.230.115.161"
    }
  ]
}

出力はGoogle Public DNSとほとんど同じです。 標準化って素晴らしいですね。

レコードタイプの指定も同様にできます。

$ curl -s 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&name=made.livesense.co.jp&type=CNAME' | jq .
{
  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5
    }
  ],
  "Answer": [
    {
      "name": "made.livesense.co.jp.",
      "type": 5,
      "TTL": 246,
      "data": "hatenablog.com."
    }
  ]
}

MackerelでDNS外形監視

ここまで来れば勘のいい人は大体お気づきだとは思いますが、MackerelのURL外形監視にDNS over HTTPSのURLを指定し、レスポンスボディのチェックでDNSレコードの外形監視をやってしまおうという魂胆です。

監視ルールを追加から外形監視を設定して新規監視ルールを作成します。 監視対象のURLに先ほど試した Google Public DNS または Cloudflare DNS のURLをパラメータを設定して入力します。

f:id:nashiox:20180517205103p:plain

レスポンスボディのチェックに監視したいレコードの内容を入れます。

f:id:nashiox:20180517205519p:plain

非常に簡単ですね。

後は実際に動作を確認するだけです。 レスポンスボディのチェックと実際に引ける内容が異なるときちんと通知されました。

f:id:nashiox:20180517211016p:plain

おわりに

DNS外形監視は今までこれというものが中々見つかりませんでしたが、今回のDNS over HTTPSを使った外形監視は結構使い勝手が良いんじゃないかと思っています。

DNS over HTTPSはまだドラフト段階ですが、2018年中には標準化を完了させる目標になっているそうです。 HTTPで利用できると言うのは他にも色々活用方法がありそうなので今後も色々試していきたいと思います。


  1. Internet Engineering Task Force (https://www.ietf.org/)

ビジョン合宿はやはり良かった

はじめまして。
昨年の11月にリブセンスにジョインして、今は転職会議のエンジニアをしたり、その他イロイロやっている しらかわ と申します。

先日 (といっても先月ですが) 、わたしの所属する組織では、One-DAYビジョン合宿というものが行われました。
そのときの様子と、なぜ合宿までしてビジョンを追求するのか。という話をしようと思います。

f:id:livesense-blog:20180427153342j:plain

なぜやるのか

この合宿を実施する上で、4つの理由がある。すべてはそこから始まりました。
開催にあたってのリーダーの言葉を借ります。

  1. 誰かがプロダクトを作るのではない。自分たちが作るんだ。
  2. ひとつ屋根の下、1日しゃべってお互いの理解を深めよう。
  3. 事業領域理解・自社理解を深めよう。
  4. 転職会議の進むべき方向性を決めるための素材を集めよう。

どんな準備が必要か

1. みんなが知っていることをそろえる

2時間くらい "合宿事前セミナー" というものを実施しました。
転職会議というプロダクトは人材業界と切り離して考えることはできません。
わたしたちが携わるプロダクトについて業界のプロに本格的な話をしてもらうことで、より理解や深まり、課題を掘り下げやすくなったと思います。

2. ひとりでじっくり考えてくる

シートを埋めました。宿題です。
項目はこんな感じでした。

  • なぜ存在するのか
  • ミッションはなにか
    • 誰に対して
    • どんな価値を
    • どのように提供するか
  • どうありたいか

この "どうありたいか" がビジョンになります。
これを、転職会議に訪れてくれるユーザと、転職会議に求人情報を載せてくれているクライアントに対して、それぞれ考えてみました。

3. 時間割をきめる

数名が "プレ合宿" と称して、合宿のリハーサルを行い、当日の時間割を考えました。
これがあったおかげで、当日の流れが大変スムーズになったと思います。

どんなことをしたのか

f:id:livesense-blog:20180427155029j:plain

阿佐ヶ谷の古民家!を丸一日借り切っての合宿となりました。
6〜7名くらいのグループを複数作り、お互いの宿題を見せ合いながら議論し、グループで一つの方向まで導きました。

f:id:livesense-blog:20180427153437j:plain

そして最後にグループ別に発表をして、1日を終えました。

もたらされたもの

まず、とにかく楽しい。楽しいというのはそれだけでも正義ですよね。
そして、普段多くを語らないようなメンバが本当は何を大切に思ってこのプロダクトに携わっているのか、お互いに気づくことができたと思います。自分では到底思いつかないようなアイデアもたくさん生まれ、何よりも視座が高まりました。

さらに、思いを持って仕事をしているモノ同士、大きな一体感を感じることができました。
これって会社の会議室ではない非日常な空間だからこそ、得られるものだったのではないでしょうか。

そして目的は達成されたでしょうか。

  1. 自分たちがプロダクトを作るんだ!という気持ちがより高まった!
  2. ひとつ屋根の下、1日話し合うことで、普段一緒に仕事をしていない仲間の考え方を知ることができた!
  3. セミナーを受けて、さらに自分で考える事で、そしてみんなでじっくり話し合うことで、事業領域理解・自社理解が深まった!
  4. 転職会議の進むべき方向性を決めるための素材がたくさん集まった!

なぜビジョンが大切か

ビジョンがあると、迷ったときの拠り所になるのではないでしょうか。
わたしたちは生まれも育ちも年齢も何もかも異なります。そして、迷ったり間違ったりする生き物です。
そんなバラバラでフワフワなわたしたちが一つのプロダクトを産み、育てていくのですから、やっぱりビジョンは大切なんだなぁ...と思います。

f:id:livesense-blog:20180427153229j:plain

またビジョン合宿やりたい!
ʕ•ᴥ•ʔ<やろうやろう!

付録

ビジョン合宿のあと、みんなと一緒にバスに乗って帰りました。
「バスっていいなあ。」と強く思ったので、社内でLTをしました。
こういう気持ちも、この合宿がもたらしたものの一つかもしれないです。

speakerdeck.com

リブセンスの海外カンファレンス渡航支援制度でRailsConf2018に参加しました

こんにちは。マッハバイトでエンジニア/マネージャーをしている内山です。

この度リブセンスでは「海外カンファレンス渡航支援制度」が始まりました。 当制度を利用して4/17(火)~4/19(木)にアメリカで行われたRailsConf2018に参加することができたので、それについて書きたいと思います。

海外カンファレンス渡航支援制度とは?

その名の通り、海外にて開催されるカンファレンスに、オーディエンスとして参加するにあたっての交通費や滞在費等を会社が支給してくれる制度です。
希望者は行きたい海外カンファレンスを宣言し、半年に1度、1名を対象に支援が行われます。 初回となる今回は僕のRailsConf行きを支援してもらうことになりました。

RailsConfとは?

これまたその名の通り、Ruby on Railsの国際カンファレンスで、年に1度開催されています。

railsconf.com

開催場所は毎年アメリカ国内を転々としているようで、去年はアリゾナ州フェニックスで、今年はペンシルベニア州ピッツバーグでの開催となりました。

来年はミネソタ州ミネアポリスで行われることが発表されています。

また、例年オープニングKeynoteをRails創始者であるDHH氏が務め、クロージングKeynoteをRubyとRailsのコアコミッターであるAaron Patterson氏が務めるというのが慣習のようです。

日本でもRubyの国際カンファレンスとしてRubyKaigiがありますが、Railsについてのセッションが行われることは稀です。
最近は日本でもRails Developers MeetupというRailsの知見が共有されるイベントが開催されていますが、やはりRailsコアコミッター自ら最新動向を話してくれる機会はなかなかないように思い、RailsConfに一度参加したいと思うようになりました。
(特にDHHはあんまり日本に来ないんですよね...)

ピッツバーグはどんな街?

アメリカ北東部に位置する人口30万人ほどの街です。 日本との時差は-13時間で、ニューヨークやワシントンD.C.と同じタイムゾーンに位置します。

南北を流れる2つの川にかかる橋や、川の合流地点を高台から眺められるインクライン(ケーブルカー)などで知られており、今回のRailsConfの各種デザインにもそれらがあしらわれていました。

f:id:livesense-blog:20180426020552j:plain
RailsConfのノベルティ

今回カンファレンスが行われたのは北側の川に面したDavid Lawrence Convention Centerです。 国際展示場や幕張メッセを小さくしたような施設と想像してもらえるといいのかもしれません。

ピッツバーグはアメリカでも「住みやすい街No.1」に選ばれたこともあるらしく、治安がとても良く、その点では会期中快適に過ごすことができました。 ただ一方で、関東暮らしが長い僕にとっては、なかなか厳しい4月の天候となりました。

f:id:livesense-blog:20180426014649j:plain
雪の降りしきるピッツバーグ

やはりそれは、世界中から集った多くのRubyistにとっても同じだったようで、オーガナイザーからの冒頭挨拶では「会場から上着が買える場所までの道順」をスライドに映し出して笑いを誘っていました。

セッションについて

RubyKaigiのセッションが「正直、難しくて理解できないとこもたくさんあったけど、なんか楽しかった!」となることが少なくない(個人的な感想です)一方で、どちらかと言えば、RailsConfのセッションはより多くの人が理解しやすいようになっているものが多かったように思います。

冒頭、オーガナイザーの「RailsConfに初めて来た人?」という問いに、自分を含む大半の人が手を上げていたので、それらの人への配慮もあるのかもしれません。
僕はリスニングスキルに長けているとは言い難いので、その点では、内容面が難しすぎないというのはありがたかったと思います。

f:id:livesense-blog:20180426035342j:plain
メインのホール

また、いわゆるTechTalkだけでなく、開発をめぐる"エモい"話などが多いのも特徴でしょうか。 TechTalkの傾向としては、テスト関連の話題、RailsアプリケーションにおけるJavaScript開発のTips、Kubernetesを始めとしたコンテナ技術の事例...などが目立ったように思います。

印象的だったセッションをいくつか取り上げます。
※これらのセッションの様子は一ヶ月以内にYoutubeで公開されるとのことです。興味を持たれた方は是非チェックしてみてください!

Turbo Boosting Real-world Applications - Akira Matsuda

  • 日本からもRubyとRailsのCommitterである松田さんが発表をされていました。
  • DBへのクエリ発行やPartialのレンダリングを、子スレッドを利用して行うことでRailsを高速化するというアプローチについて紹介されていました
  • スライド: Turbo Boosting Real-world Applications // Speaker Deck

Keynote: The Future of Rails 6: Scalable by Default - Eileen M. Uchitelle

  • GitHubのエンジニアであり、RailsコアチームでもあるEileenによる2日目のKeynoteです
  • Rails6で追加される並列テストや、複数DBのサポートについての話がありました
  • そのうえで「Scaling should make us happy」といった言葉とともに、スケーリングに応えるRailsであろうとする姿勢を力強く話されていました。
  • スライド: RailsConf 2018 | The Future of Rails 6: Scalable by Default // Speaker Deck

Inside Active Storage: a code review of Rails' new framework - Claudio Baccigalupo

  • Railsのissue対応を行っているClaudioからは、Rails5.2で追加されたActiveStorageについてのトークがありました。
  • ActiveStorageの使い方を踏まえた上でのコードの解説がとてもわかりやすく、勉強になりました
  • スライド: Active Storage // Speaker Deck

その他、ClaudioがRails公式サイトのブログにまとめ記事をあげています。併せてご確認ください!

weblog.rubyonrails.org

参加してみて

海外カンファレンス初参加となりましたが、慣れない英語を集中して聞き続けるというのはやはりドッと疲れるなぁ...というのが、恥ずかしながらも正直な感想です...。 事実、会期3日間のうち2日間は、カンファレンスが終わるとフラフラとホテルに直行し、夕食も取らずに寝てしまいました。

f:id:livesense-blog:20180426034703j:plain
元気があったカンファレンス前日に撮った夜景

最終日は、RailsConfに毎年来られている日本の方と夕食をご一緒する機会がありました。 全てのセッションを聞きつつもスピーカーとさほどコミュニケーションを取らず、夕飯以降の機会でも他の参加者らと交流を取っていない僕のことを、その方は冗談めかして「もったいない」と笑っていました。

確かに、Youtubeで全てのセッションが公開されることを考えれば、セッションにかじりついているだけでなく、その場での交流や情報交換までできてこそ、カンファレンスに参加した甲斐があったと言えるのかもしれません。 ...とは言っても、スピーカーの方らに拙い英語で話しかけることに気後れを感じてしてしまうのも事実です。 カンファレンスの準備として語学学習だけでなく、誰と話したいか、どんなことを話したいかといったことを予め考えておくのも重要だったのかもしれないなぁと今では思っています。

とは言え、もちろん現地でしか得られない経験もできました。 「How We Made Our App So Fast it Went Viral in Japan」というトークをしたdev.toのファウンダーの方に「I'm from Japan」と伝えて笑ってもらったり、自分がWebエンジニアを目指すにあたっての大きな拠り所となったRails Tutorialの作者に感謝を伝えたりすることもできました。 ランチタイムに他の参加者の方らと、日本とアメリカ各州の住宅費用やエンジニア年収について談笑したことも心に残っています。

本当はスポンサーによるエキシビジョンブースの様子なども書きたいのですが、長くなってきたのでこれくらいで...。

最後に

f:id:livesense-blog:20180426012356j:plain
帰りの空港にて

海外カンファレンスに参加すること自体も貴重な経験でしたが、今回「会社の金で行くぞ」という適度なプレッシャーが自分にとって英語学習のきっかけになったことも事実です。 日本にもRubyKaigiを始めとした国際カンファレンスがありますし、せっかくですから自分のペースでもう少し学習を続けたいと思っています。
来月は仙台でのRubyKaigiですね!楽しみです。

最後になりますが、リブセンスではエンジニアを募集中です!
海外カンファレンスに行ってみたいエンジニアの方からのご応募もお待ちしております!!

4Kモニターを仕事で使い始めたらやっぱり最高だった

こんにちは、マッハバイトエンジニアの黒川です。 今日は、最近会社で買ってもらって仕事で使っている4Kモニターが最高だという話をします。 エンジニアブログというよりは商品レポートなので、お気軽に読んでいただければ幸いです。

入社時点での設備

9月に入社した時点で私には、タッチバーつきスペックマシマシのMacBook Proが支給されました(デフォルトがそれなだけで、他のが良ければもちろん任意のマシンも申請可能でした)。 またモニターはオフィスにたくさん置いてあり、好きなだけ持っていって使って良いという状態でした。

しかしそこにはちょっとした問題点がありました。モニターのサイズが少し小さくて、解像度が低かったのです。 最強のMacBook Proがあるのに、USB-C変換アダプターをぶら下げてHDの解像度のモニターで仕事をするのは、せっかくマシンに投資してもらっているのにもったいないなと思っていました。

良いモニターがほしい!

もし良いモニターがあれば、最強のMacをさらに活かし良いものを作れるはずだということで、チームリーダーに相談してみました。するとリーダーがすぐに総務に相談してくれました。 その後はチーム内で他にも4Kモニターがほしい人がいないかアンケートを取ったうえで、無事購入してもらえました。

要望を言える空気、そして前向きに検討してもらえて叶える方向で動いてもらえる空気感の弊社は最高だなと思いました。 実際仕事場にモニターが来たらさらに最高でした。

どんな感じに最高なのよ

ここからは、仕事場に新しいMacBook Proと4Kモニターがあるとどう最高なのかを説明していきます。 ちなみに買ってもらったのはLGの27UD88-Wです。

まず何より、デカい

私は今までモニターを2枚並べて使っていましたが、2枚を横に並べると横幅が大きくなりすぎて、ひと目で全体を把握できませんでした。 またその関係上、よくマウスポインターがモニター上のどこにあるかわからなくなっていました。 これらの問題を、新しいモニターはそのデカさで補ってくれます。

f:id:blackawa:20171114171906j:plain

(左: 新しいモニター / 右: オフィスによく置いてあるモニター) 新しいモニターは、オフィスに置いてあるものに比べて一回りほど大きいです。 おかげで今は、1枚の大きなモニターに情報をまとめて表示できています。

文字が潰れない

今まで使っていたモニターはサイズが小さかったので、Mac側で文字サイズを小さくしてたくさんの情報を表示できるようにしていました。 しかしそうすると新たな別の問題が発生します。それは「文字が潰れる」ということです。 まずオフィスに置いてあるモニターを、手元のiPhone SEで写真に撮ってみました。

f:id:blackawa:20171114172100j:plain

画像も粗いし、「新妻」の「妻」の字は潰れてしまっています。 文字が潰れてしまう状態で大量の文字を読むと、だんだん目が疲れてきます。

次に、新しいモニターを見てみます。

f:id:blackawa:20171114172103j:plain

ひと目で分かるレベルで画像も文字もきれいに表示できています。 カメラ越しでもこの差!実際にはもっと見やすいです。 今もこの記事を新しいモニターで書いていますが、爽快な書き心地を体験できます。 いわんや、これがソースコードなら。

なめらかな角度調節・高さ調節

オフィスに置いてあるモニターの中には、高さの調節ができるものとできないものが混在しています。 高さが調節できないと目線が常に下になるので肩や首が疲れやすくなります。 また、姿勢も悪くなってしまいます。私は身長が190cm近くあるので、余計負担が大きかったです。 新しいモニターの要件にはもちろん高さ調節機能があります。

f:id:blackawa:20171114172445g:plain

もちろんモニターの角度も片手で滑らかに変えられます。

f:id:blackawa:20171114172448g:plain

これで、体格に合った高さと角度で業務に取り掛かることができます。

さらばケーブル・アダプター地獄

最後は少しTIPS感のある良さですが、これもこれでとても良いので紹介させてください。

Mac Book Pro 2016から、外部インターフェースがUSB Type-C限定になりました。 今まで通りのHDMIやUSBケーブル、Thunderboltケーブルを使うためには、専用のアダプターが必要でした。 このアダプターだけで1万円近くかかるという、便利になったのかなっていないのかよくわからない状態でした。

しかし、新しいモニターはUSB-Cがいかに優れモノかを見せてくれます。

f:id:blackawa:20171114172609j:plain

なんとモニターとMacをUSB-Cケーブルで接続するだけで、 - 画面表示できる - 充電できる - ディプレイのUSBポートに挿したキーボードを使える

のです。 下の写真のように、モニターにUSBケーブルを接続するとあたかもMacに挿しているのと同じように使えます。

f:id:blackawa:20171114172714j:plain

これで、離席する時にはMacに挿してある1本のケーブルを抜けば良いだけです。 席に戻ってきたら再び挿せばすぐに画面が表示されて充電が始まり、外付けキーボードのHHKBで作業ができます。 おかげでテーブルのまわりのケーブルがこんなにシンプルになりました。

f:id:blackawa:20171114172755j:plain

これで離席があってもストレスなく作業を再開できそうです。

まとめ

ここまで、4Kモニターとそれを買ってくれる弊社最高という話をしてきました。 ぜひ皆様のチームでも良いマシンと良い機材を導入してみてください。 全力で集中して長い時間使うオフィスの機材が良くなるのは最高の体験です。