delirious thoughts

by Kentaro Kuribayashi

gRPCでgdbmにネットワークインタフェイスを持たせる

先日、HTTP/2とProtocol BuffersをベースにしたRPCフレームワークgRPCがリリースされた。

Microservicesがなんちゃらいわれる昨今だが、その実現のためには、設計面におけるベストプラクティスはもとより、実装面においても課題がある。すなわち、サービス間でどのようにオーバーヘッドが少なく、帯域を浪費しない通信を実現するかということ。そんな折Googleが、上記のリンク先にある通り「うちらめっちゃMicroservicesだし」ってんで、まさに「これだ!」という技術スタックでいい感じのものを出してくれた。

gdbmにRPCしてみる

とりあえず試してみたいので、簡単にできそうな例として、gdbmにネットワークインタフェイスをもたせてRPCしてみる、ってのをやってみた。

kentaro/grpc-gdbm · GitHub

インタフェイスを定義する

Thriftとかああいうのを触ったことがあるひとにはお馴染みのIDL(Interface Definition Language)があって、gRPCの場合はProtocol Buffersを用いて、こんな感じで書く。以下は、gdbmに対して、Insert, Replace, FetchというRPCを定義している。Protocol Buffersを使うぐらいなのでデータ量-awareな感じだろうから、ほんとは以下のRequestの定義をもっと厳密にわけた方がいいと思うけど、例なので深く考えない。

syntax = "proto3";

package gdbm;

service Gdbm {
        rpc Insert (Request) returns (Entry) {}
        rpc Replace (Request) returns (Entry) {}
        rpc Fetch (Request) returns (Entry) {}
}

message Request {
        string key = 1;
        string value = 2;
}

message Entry {
        string key = 1;
        string value = 2;
}

んでもって、この定義からRPCへのクライアントとサーバのコードを生成する。

$ protoc -I ./protos ./protos/gdbm.proto --go_out=plugins=grpc:gdbm

生成された内容は以下の通り:

サーバとクライアントを書く

あとはそれを使ってなんか適当に書いていくだけ。IDLで定義したInsert, Replace, Fetchを実装したstructを、上記で生成されたpb.RegisterGdbmServer()にわたしてやると、RPCをいい感じに受け付けるようになる(生成されたコードに、そういうinterfaceが定義されている)。

サーバ:

package main

import (
    "flag"
    "fmt"
    "log"
    "net"

    "github.com/cfdrake/go-gdbm"
    pb "github.com/kentaro/grpc-gdbm/gdbm"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
)

var port int
var file string

func init() {
    flag.IntVar(&port, "port", 50051, "port number")
    flag.StringVar(&file, "file", "grpc.gdbm", "gdbm file name")
    flag.Parse()
}

type server struct {
    Db *gdbm.Database
}

func (s *server) Insert(ctx context.Context, in *pb.Request) (*pb.Entry, error) {
    err := s.Db.Insert(in.Key, in.Value)
    return &pb.Entry{Key: in.Key, Value: in.Value}, err
}

func (s *server) Replace(ctx context.Context, in *pb.Request) (*pb.Entry, error) {
    err := s.Db.Replace(in.Key, in.Value)
    return &pb.Entry{Key: in.Key, Value: in.Value}, err
}

func (s *server) Fetch(ctx context.Context, in *pb.Request) (*pb.Entry, error) {
    value, err := s.Db.Fetch(in.Key)
    return &pb.Entry{Key: in.Key, Value: value}, err
}

func main() {
    lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    db, err := gdbm.Open(file, "c")
    if err != nil {
        log.Panicf("couldn't open db: %s", err)
    }
    defer db.Close()

    s := grpc.NewServer()
    pb.RegisterGdbmServer(s, &server{Db: db})
    s.Serve(lis)
}

クライアントは特に述べるまでもない感じ。この例の場合に普通に使うなら、生成されたコードを使っていい感じのAPIを持つライブラリを作って、それを使うことになるだろう。

package main

import (
    "flag"
    "fmt"
    pb "github.com/kentaro/grpc-gdbm/gdbm"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
    "log"
)

var port int
var key string
var value string

func init() {
    flag.IntVar(&port, "port", 50051, "port number")
    flag.StringVar(&key, "key", "key", "key name")
    flag.StringVar(&value, "value", "value", "value for key")
    flag.Parse()
}

func main() {
    conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", port))

    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    c := pb.NewGdbmClient(conn)

    r, err := c.Replace(context.Background(), &pb.Request{Key: key, Value: value})
    if err != nil {
        log.Fatalf("gdbm error: %v", err)
    }

    r, err = c.Fetch(context.Background(), &pb.Request{Key: key})
    log.Printf("value for %s: %s", key, r.Value)
}

RPCしてみる

そしたら、あとはサーバとクライアントを使ってRPCできる。

サーバを起動する:

$ go run server/main.go

-key, -valueの引数で指定した値を入れたり出したりするだけのクライアント:

$ go run client/main.go -key foo -value bar
2015/03/03 01:11:12 value for foo: bar

簡単ですね。

使いどころ

この例で示したような、6〜7年前とかにThriftとか使っていた頃のようなユースケースにもあてはまるんだろうけど、いまだとまさにMicroservices用とかStreamingとかに使う感じになるんだろう。というか、そうでないとHTTP/2なうれしさがあんまり見いだせないだろうし。

ともあれ、当時だといろいろとしんどかった記憶があるけれども、いまだと例でも利用したGoもあるしHTTP/2もあるし、いろいろ環境は整っているなという感じがする。

2015年1月に読んだ本をブクログでふりかえる

今月は13冊。あれ、こんなものか。あんまり読んでなかったな。

もうちょっとちゃんと分野を決めて本を読みたいと思いつつ、相変わらず雑多な感じ。でも、イスラム国とかでてくるとなんだろうなそれと思って知りたくなったりするのだし(『イスラーム国の衝撃』『メディアとテロリズム』)、自炊を再開したので飲食関連も読みたくなるし(「dancyu」の日本酒特集など)、仕事関連で気になっている本を読んだりもして(『Lean Analytics』など)、いろいろしかたない。

kentaroの本棚 - 2015年02月 (13作品)
技術経営論
丹羽清
読了日:02月28日
評価4

powered by booklog

Slack用のIkachanを作った

最近、社内のチャットツールをSlackに移行しつつある。ペパボではIkachanをヘヴィに使っているので、移行に際してはそこをどうSlackに移行するかが問題となった。というわけで、Ikachanと同じインタフェイスでSlackにメッセージを送れる簡単なツールを作成した。

Ikachanを使っているひとには特に説明の必要もない感じ。詳しくはREADMEを見てほしい。go getしたら、

$ SLACK_API_TOKEN="YOUR SLACK API TOKEN" takosan [-host string] [-port int] [-name string]

以下のように起動して、あとは

$ curl -d "channel=#channel&message=test message" localhost:4979/privmsg

とかするだけ。簡単ですね。エラーハンドリングが雑だけど、メッセージを投げる側はエラーメッセージ見てなんかするみたいなことないだろうから、実際上は問題ないと思う。ログはいてるので、そっちを見てね、という感じ。

どうぞご利用ください。

大きな構想を持つこと

DeNAのZIGOROuさんによる技術選択とアーキテクトの役割というスライドを拝見して、大いに感じるところがあったので、少し書く。といっても、技術的な話というよりは、もうちょっと違うレイヤの話(技術選択についても思うところはあるのだけど、それはそれについて述べたスライド*1を参照していただきたい)。

経験曲線効果

経験曲線効果という言葉がある。元は、ボストン・コンサルティング・グループ(BCG)のコンサルタントによって提唱されたものだ*2。このような図*3を見たことがあるだろう。

f:id:antipop:20150220002603g:plain

Wikipedia*4には以下のように説明されている。

経験曲線効果(けいけんきょくせんこうか、experience curve effect)とは、経験と効率との間の関係を示す経験則である。単に経験効果とも呼ばれる。一般に個人や組織が特定の課題について経験を蓄積するにつれて、より効率的にその課題をこなせるようになることを指す。また累積生産量の増加に伴って、製品数量ごとの間接費を含めた総コストが予測可能な一定の割合で低下していくことを指す。

経験曲線効果の起こる条件

ここで重要なのは、上記の引用に反して、単に経験を積みさえすれば、すなわち、生産量の累積さえ増えれば必ずそのような望ましい効果が現れるわけではない、ということだ。なんとなく経験を積み上げるだけでは、それなりに習熟して効率化されることは起こりえても、経験曲線効果が示すほどの改善は見られないだろうことは、実感からも確かだろうと思う。

では、経験曲線効果による望ましさを得るには、なにが必要なのだろうか。経営学者の高橋伸夫は、その著書群のあちこちでその条件を述べている*5

生産量が増えることを期待して生産技術を変えること、すなわち機械器具を設備して量産態勢をとること、あるいは大量生産に合った製品デザインを採用することが、コスト低減の大前提だとライトは指摘していたのである。プロトタイプにはプロトタイプの制作の仕方があり、10台作るのなら10台作る作り方がある。100台には100台なりの、そして1万台生産するのであれば1万台を効率的に生産する量産方法と製品デザインがある。ものづくりの現場には、前提となるスケール観があってしかるべきなのだ。

いかに現場の奮闘努力があったとしても、結果的に累積1万台を作りました……では、学習曲線は実現しないのである。最初から、いつまでに月産1000台を作る量産態勢を整えるという見通しがあればこそ、それなりのやり方を現場は考えるのあり、その結果として、累積1万台のときまでにはコスト・ダウンが実現されている――という性格のものなのである。

少し脱線するが、ピーター・ティールが『ゼロ・トゥ・ワン』*6でリーン・スタートアップを批判していたのは、上記引用の文脈で読みかえればそれはそれでステージの違いに過ぎないともいえるし、スケール観の大切さを別のやり方で表現しているともいえる。

アーキテクトの条件

そうした経験曲線効果が起こる条件を用意する「スケール観」を持つ者を、高橋は「スケール観を持った予言者」と記している。冒頭に紹介したスライドでZIGOROuさんの述べるアーキテクトとは、まさにそのような存在であるべきだろう。そうした「スケール観」があったからこそ、DeNAの圧倒的な成長が可能になったのだろうと思う。

そういう意味において参考になる文献としては、100倍で考える | Preferred Research*7がある。これなどはまさに、経験曲線効果を起こすためのスケール観を醸成する最たるものである。それで私は、最近、口癖のように10倍とか100倍とかいっているわけだ。経験曲線効果は、まさにインターネットサービスにおいても、その正しさを誇っているように見える。

組織能力を圧倒的に成長させるためにも、大きな「スケール観」が必要だ。もちろん、単なる構想倒れでは意味がないことは明白であるにしても、まず最初にスケール観に基づく大きな構想が必要なのは、これまでの論から確かであるといえると思う。私はそうした存在になりたいと思う。

殻―脱じり貧の経営

殻―脱じり貧の経営

ゼロ・トゥ・ワン―君はゼロから何を生み出せるか

*1:林健太郎 "On Technological Selection"、https://speakerdeck.com/kentaro/on-technological-selection

*2:言葉としてはその通りだが、現象としてそれが報告されたのはカーティス・ライト社の主任技師兼部長のライトによる論文とされる。高橋伸夫『殻―脱じり貧の経営』(ミネルヴァ書房、2013年、p.177)参照のこと。

*3:Wikipedia "Experience curve effects" http://en.wikipedia.org/wiki/File:Experience_curve.gif

*4:Wikipedia経験曲線効果http://ja.wikipedia.org/wiki/%E7%B5%8C%E9%A8%93%E6%9B%B2%E7%B7%9A%E5%8A%B9%E6%9E%9C

*5:高橋伸夫『殻―脱じり貧の経営』ミネルヴァ書房、2013年、pp.178-179

*6:ピーター・ティール + ブレイク・マスターズ著、関美和訳『ゼロ・トゥ・ワン―君はゼロから何を生み出せるか』NHK出版、2014年

*7:岡野原大輔「100倍で考える」、"Preferred Research"、http://research.preferred.jp/2014/10/100x/

エンジニア専門職のグレードについて詳細な役割定義は必要か?

様々な人々から、エンジニアに関する制度についてインタビューされる機会が増えてきた。その中で考えが整理されてきたパーツもあるので、せっかくなのでまとめておこうと思う。


ペバボのエンジニア職位制度のアップデートについてなどで書いている通り、ペパボはエンジニア専門職制度を制定し運用している。その前提として、専門職制度がどのような位置付けかというと、簡単に示すと以下の図の通りである。

f:id:antipop:20150219210310p:plain

この構造自体は特になんの変哲もない、わりと一般的な制度だといえるが、我々はこの中にひとひねり加えている。以下に説明する。

前提知識

ただし、その前に人事制度における前提的知識について述べておかないとならない。

社員格付け

昨今は「フラットな組織」「ネットワーク型組織」などというものも出てきているが、それはそれとして、一般に企業組織は、その構成員をなんらかの方法を用いて格付けしている。すぐに思い浮かぶのは、部長とか係長とかいった役職だろう。

ただし、格付けの方法はそれだけではない。日本企業においては、伝統的に以下のふたつが並列する制度が広く用いられてきた

  • 役職制度: 前述の部長や係長といった役職による格付け
  • 職能資格制度: 職務遂行能力による格付け

このふたつが並列しているということは、職能資格上のランクと役職的な「偉さ」がともすれば一致しないことになるわけだが、終身雇用制度下の組織においてはそれなりに便利だったので、広く用いられてきたわけだ*1

昨今の新興企業では、そのような制度を採用しているところは少ないだろう。その両者をミックスしたような、役割等級制度を採用している企業が多いと思われる。その特徴は、役職制度と職能資格制度の並立のような複雑な制度を廃し、

  • グレードに応じた役割を一意に定義していること
  • 賃金体系をその役割に応じて一本化していること

ということが挙げられる。

昇進と昇格

昇進と昇格とは、どちらも似たような字面であるため、区別がつきづらいが、その意味は人事制度上はずいぶん異なったものだ。その理解のためには、上記した社員格付け制度について知っていなければならない。すなわち、

  • 昇進: 役職制度において上位へあがること
  • 昇格: 職能資格制度において上位へあがること

を意味する。その違いは、昇進・昇格させる権限を持つ者が、どのような動詞でもってそれを行うかの違いとしても説明されるし、その行為がどのような期待を暗示するかの違いとしても説明される。すなわち、

  • 昇進: 命じられる。「入学」方式
  • 昇格: 任じられる。「卒業」方式

昇進というのは、身近の例で思い浮かべて欲しいのだが、たとえば課長になるよう「命じられる」ものだし、その者が(能力はあるだろうにせよ)最初から課長としてバンバン成果を出すことを期待するというよりは、これからがんばってねという期待を示すものだ。

一方で昇格というのは、一定以上の職務遂行能力を持っていることにより「任じられる」ものだし、その者は昇格したその日からその格付における職務能力を発揮することを期待される。これは、能力というものの性質上、当然のことだろう。つまり、下位の資格を「卒業」して上位にあがるという期待が示されている。

ペパボの社員格付制度

ペパボでは、上記の図で示した通り、役割等級制度に近い制度を採用している。ただし、最初に書いた通り、そこにひとひねり加えている。

他の制度同様、役割等級制度においても、「等級」や「グレード」などと呼ばれる階級のそれぞれについて、一般に、明確な定義が行われる。もしそうでなければ、制度を運用する側もその制度の下で働く者たちも、何を期待するべき/されているかがわからないため、制度がなりたたない。

明確かつ納得感の高い期待をみんなが共有し、内面化し、自己の成長のためのツールとして利用できるようにし、ひいては事業成長に寄与することが、人事制度の目的である。

そこで、役割定義というものが誤解の余地のないよう平易な言葉で、できるだけ具体的に記述され、等級表のようなものが各社で作成されているわけだ。ペパボにももちろんそれはあるし、メンテナンスされ続けている。

専門職の役割記述

上記は一般論としてはその通りであることは明白だし、実際にペパボでも、そのように運用している。ただし、エンジニア専門職についても完全に同じようなことでよいかというと、我々はそうは考えていない。どういうことか?

繰り返しになるが、一般に、等級が示す役割に期待されることを明確に記述することが社員格付け制度においては重要とされているが、エンジニア専門職(あるいは専門職一般かもしれないが)について我々はそれを必ずしも必要であるとは考えない。エンジニア専門職についての定義をまったくしてないというわけではないが、ほぼ以下のふたつのリソース以上のことはない。

  1. 上記したペバボのエンジニア職位制度のアップデートについてにある内容
  2. エンジニアの働き方 | キャリア採用 | 採用情報 | GMOペパボ株式会社に記載の内容

その他には、1)のエントリにある通り、昇格評価プロセスが全社員にすべて公開されているので、これまで積み上がった昇格可否判断の歴史もある。そこには、昇格可否判断の根拠についても詳細にドキュメントされているので、それなりに多量の文面となっている。

そういう意味においては、成文法主義に対する判例法主義のような制度であるともいえる。

エンジニア専門職とは

組織の規模・発展段階によって適した制度はいろいろあるが、我々のような新しい市場を切り開いていくタイプの、現に規模が小さく、将来に対してはまだまだアーリーステージにある企業にとっては(そうでなくてもだろうが)、制度は実態に即したものでなければならない。では、エンジニア専門職の実態とはなんだろうか?

エンジニア/エンジニアリングのビッグピクチャ」で述べた通り、我々のみならずインターネット企業に勤務するエンジニアは絶え間ない成長を求められているし、実際、いやでもそうでなければ生き残れないだろう。ひいては、それらエンジニアたちによって「組織能力を圧倒的に成長させること」ができなければ、企業は生き残ることができない。

ただ、だからといって我々エンジニアは、そんなことを考えて成長し続けるべくがんばっているばかりではない。いまも昔も、エンジニアの成長にとって一番重要なのは、

  • 未知の問題をなんとかして解決したいという情熱
  • 憧れの存在になんとかして近づきたいという憧憬

であるだろう。そうでなければ、昼も夜も、平日も休日も、何年間も技術を追い求めて倦まないないなどということがあり得るだろうか。そんなわけで、企業的な理屈とは別に、エンジニアには成長へのモチベーションが強く存在するし、また、そうしたモチベーションを喚起できるエンジニアこそが成長できるわけだ。鶏卵問題ではあるが、その均衡を打ち破れなければ、そこで終わりだ。

そのようなモチベーションにより圧倒的な成長を成し遂げるエンジニアたちにとって、詳細な役割記述は必ずしも有用ではない。もちろん、何もないでは単なる怠慢の謗りは免れないが、それだけでは充分ではないのだ。では何が必要か。それは、たとえばよくいわれるような「アプレンティスシップ = 徒弟制」のような、モチベーションを適切に醸成するような仕組みだろう。

そのような考えに基いて我々は、たとえば新人教育を行っているし、それは以下のスライドに示した通りだが、それは何も新人に限ったことではない。

そうであってみれば、役職として「入学」方式で期待をする管理職について「成文法主義」的に役割記述を明確化することとは対照的に、職能として「卒業」方式で能力が認められるエンジニア専門職について「判例法主義」的アプローチを採ることの理由は明確だ。

強いモチベーションと、その結果としての能力を扱う以上は、それを詳細に記述することにあまり意味はない。それよりも、上位の者が彼/彼女らの圧倒的な強度を示すことで、他のエンジニアたちの模範・憧憬の的となり、モチベーションを醸成することの方が重要だ。

すなわち、「◯◯の役割定義は?」という問いへの回答は「××さんのような者であることだ」ということになる。それが、標題の疑問に対する回答である。

注意点

この制度が、必ずしもすべて順風満帆にいっているかどうかといえば、そうとはいえないのは明白だ。たとえば、以下の様な感想・意見・不安が語られたりもする(まあ、それがこうしてネット上のブログにアウトプットされるという自由さはまた、我々のある面における成功を示していると誇らしいわけだが)。

また、エンジニアがモチベーションにより圧倒的に成長する存在であるということは、人事部門が制定した役割記述のようなものではなく、その上位に立つエンジニアたちが大きく成長し、圧倒的な成果をあげることで、モチベーションを喚起する存在であり続けなければならない、それはそれで過酷な制度でもあるということだ。それは、やってみれば容易にわかるが、なかなかのプレッシャーではある。どんな組織にも可能とは思われない。

また、ペパボのようにエンジニアが70人そこらの会社なら今はそれで回るが、ではそれが10倍、100倍になった時にどうするか?というのは、これから考えていかなければならないことではある。

参考文献

マネジメント・テキスト 人事管理入門<第2版>

マネジメント・テキスト 人事管理入門<第2版>

能力主義人事の設計と運用トータルシステムの進め方

能力主義人事の設計と運用トータルシステムの進め方

アプレンティスシップ・パターン ―徒弟制度に学ぶ熟練技術者の技と心得 (THEORY/IN/PRACTICE)

アプレンティスシップ・パターン ―徒弟制度に学ぶ熟練技術者の技と心得 (THEORY/IN/PRACTICE)

企業内人材育成入門

企業内人材育成入門

*1:このあたりについて説明を長ったらしく書くのは本旨から外れるので、イメージだけ理解しておけばよい。詳細について知りたい場合は、参考文献にあたられたい。

市野吉記@zakka土の記憶

安南手のうつわに心惹かれるものが多い(先日買ったものもそう)のだけど、ネットであれこれ見ていたら、市野吉記さんという作家を知った。作風については、以下のページが詳しい。

安南手特有のゆったりした雰囲気に、やや錆がかった風情をまぶしたその作品は、ひとつふたつ手元においといて気ままに使いたくなる感じ。zakka土の記憶で通販しているのを見つけたので、ちょうどラインナップに物足りなさを感じていた、7寸大の浅鉢を購入したのであった。いいでしょ、これ。素敵。

市野吉記 安南手浅鉢

さっそく、今晩の食事で使ってみた。期待通りの使い勝手の良さ。この大きさのものだと、額賀章夫さんの7寸浅鉢を頻繁に使っていたのだけど、良い選択肢が増えて、より充実した〜。

塩豚炒めた

私の著作物についてのAmazon上の著者ページ

だいぶ前に作っていたのですが、少し動きがあったので、このタイミングでちょっと出しておきます(謎の書影が気になりますね)。

こんな感じです。よろしくどうぞ。

f:id:antipop:20150216223000p:plain

GMOペパボ株式会社・技術責任者。市役所職員、株式会社はてな勤務を経て、現職。Perl Monger兼本読みとして、フロントエンドからインフラ、ハッカー倫理から経営までをあちこち揺れ動く、文化系ソフトウェアエンジニア。ネット上では「あんちぽくん」として知られる。