Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lightweight REST API Server by Go, and performa...

Lightweight REST API Server by Go, and performance compalison with implementations of other languages.

Lightweight REST API Server by Go, and performance compalison with Go, Perl and Ruby at GoCon 2013 autumn.

Shinji Tanaka

October 16, 2013
Tweet

More Decks by Shinji Tanaka

Other Decks in Technology

Transcript

  1. Lightweight REST API Server by Go Shinji TANAKA @stanaka /

    id:stanaka CTO at Hatena Co, Ltd. Thursday, October 17, 13
  2. @stanaka / id:stanaka • Shinji TANAKA • CTO at Hatena

    Co., Ltd. • Go .. novice • LTSV .. Labeled Tab-Separated Values Thursday, October 17, 13
  3. Motivation • Deal well with widely-shared DBs • like User

    DB / Session DB User DB Thursday, October 17, 13
  4. Typical solution • Common library / Shared module User DB

    Hatena::User Hatena::User Thursday, October 17, 13
  5. Problems of Common Library • Dependency to specific ORM •

    hard for applications to use other ORM • Hard to update libraries for all application use them • Inconsistent versions for each application Thursday, October 17, 13
  6. Solution: Loose coupling • Twitter case • Decomposing Twitter: Adventures

    in Service-Oriented Architecture ( http://www.infoq.com/presentations/twitter-soa ) • Make them as independent services Thursday, October 17, 13
  7. Communication between Services • Thrift .. NO! • REST API

    .. YES! • Simple, Easy to extend • Stable client for mostly ALL languages • IDL is annoying • Poor performance at Perl-binding Thursday, October 17, 13
  8. Lightweight REST API Server by Go • Body • JSON

    • MessagePack • MySQL • usual SQL query • innodb memcached plugin .. Avoid overhead to parse SQLs. Thursday, October 17, 13
  9. Go implementation • Go 1.1.2 • net/http • github.com/ugorji/go/codec (messagepack

    library) • encoding/json • github.com/go-sql-driver/mysql • github.com/bradfitz/gomemcache/memcache Thursday, October 17, 13
  10. Architecture Client host Target host REST API server MySQL Benchmark

    tool REST API SQL / memcached Thursday, October 17, 13
  11. rest_server.go #1 package  main import  (   "database/sql"   "encoding/json"

      "github.com/bradfitz/gomemcache/memcache"   _  "github.com/go-­‐sql-­‐driver/mysql"   "github.com/ugorji/go/codec"   "net/http" ... ) ... func  main()  {   db,  err  =  sql.Open("mysql",  "root@/test") ...   http.HandleFunc("/",  messagepack_handler) ...   err  =  http.ListenAndServe(*addr,  nil)   if  err  !=  nil  {     log.Fatal("ListenAndServe:",  err)   } } Thursday, October 17, 13
  12. rest_server.go #2 func  fetch_mysql()  *map[string]interface{}  { ...   var  user

     User   re  :=  make(map[string]interface{})   err  =  db.QueryRow("SELECT  name,mail  FROM  user  WHERE  id=?",  id)                      .Scan(&user.name,  &user.mail) ...   re["name"]  =  &user.name   re["mail"]  =  &user.mail   return  &re } ... func  messagepack_handler(w  http.ResponseWriter,  r  *http.Request)  {   w.Header().Set("Content-­‐Type",  "application/x-­‐msgpack")   res  :=  fetch_mysql()   enc  :=  codec.NewEncoder(w,  &mh)   err  =  enc.Encode(res) } ... Thursday, October 17, 13
  13. Perl implementation • Perl 5.18.1 • Starman + If-else Routing

    (4 worker processes) • Data::MessagePack • JSON::XS • DBI + DBD::mysql • Cache::Memcached::Fast Thursday, October 17, 13
  14. Ruby implementation • Ruby 2.0.0-p247 • puma + sinatra (16

    worker threads) • msgpack • oj (json library) • mysql2 • dalli (memcached library) Thursday, October 17, 13
  15. MySQL • MySQL 5.6.13 • usual SQL query • innodb

    memcached plugin Thursday, October 17, 13
  16. Schema CREATE  TABLE  `user`  (    `id`  varchar(32)  NOT  NULL,

       `name`  varchar(256)  NOT  NULL,    `mail`  varchar(1024)  NOT  NULL,    `c3`  int(11)  DEFAULT  NULL,    `c4`  bigint(20)  unsigned  DEFAULT  NULL,    `c5`  int(11)  DEFAULT  NULL,    PRIMARY  KEY  (`id`) )  ENGINE=InnoDB  DEFAULT  CHARSET=utf8 Thursday, October 17, 13
  17. Environment • Amazon EC2 m1.large (both client/target) • 2 CPU

    / Intel(R) Xeon(R) CPU E5507 @ 2.27GHz • 7.5 GB memory • RTT(ICMP) client-target 0.411 msec (average) • debian 6.0.6 • 2.6.32-5-xen-amd64 Thursday, October 17, 13
  18. Benchmark Load • 100% read • Mostly same rate as

    services in production. • Data size • 10,000 records • All data is on memory (no read/write I/O) • CPU-intensive benchmark Thursday, October 17, 13
  19. Results 10,000 requests 10 concurrency direct memcached (innodb) direct mysql

    go msgpack + memcached perl msgpack + memcached perl json + memcached perl msgpack + mysql perl json + mysql ruby msgpack + memcached ruby json + memcached go msgpack + mysql go json + memcached go json + mysql ruby msgpack + mysql ruby json + mysql 0 2,000 4,000 6,000 8,000 10,000 12,000 243.55 246.1 254.7 259.15 255.29 262.32 1413.04 2187.29 2201.99 2888.71 2946.53 4001.27 6545.38 10720.1 req/sec Thursday, October 17, 13
  20. Results 10,000 requests serial direct memcached (innodb) direct mysql go

    msgpack + memcached perl msgpack + memcached perl json + memcached perl msgpack + mysql perl json + mysql ruby msgpack + memcached ruby json + memcached go msgpack + mysql go json + memcached go json + mysql ruby msgpack + mysql ruby json + mysql 0 500 1,000 1,500 2,000 120.79 123.48 132.04 134.05 136.14 620.03 621.69 760.12 767.41 856.81 861.68 1018.45 1287.74 1722.93 req/sec Thursday, October 17, 13
  21. Results 10,000 requests serial direct memcached (innodb) direct mysql go

    msgpack + memcached perl msgpack + memcached perl json + memcached perl msgpack + mysql perl json + mysql ruby json + memcached ruby msgpack + memcached go msgpack + mysql go json + memcached go json + mysql ruby msgpack + mysql ruby json + mysql 0 2 5 7 9 8.279 8.099 7.573 7.46 7.345 1.609 1.613 1.316 1.303 1.171 1.161 0.982 0.777 0.58 msec/req Thursday, October 17, 13
  22. Observations • Go + memcached plugin + messagepack = Fastest!!

    • except direct mysql/memcached • Go has good performance and small footprint • mysql library needs to be improvement • Perl mysql library does good performance • innodb memcached plugin works well Thursday, October 17, 13
  23. Q & A We’re Hiring at both KYOTO and TOKYO!

    https://github.com/stanaka/go-rest-api-server Thursday, October 17, 13