three ruby usages

56
Three Ruby usages Powered by Rabbit 2.1.4 Three Ruby usages Kouhei Sutou ClearCode Inc. RubyKaigi 2014 2014/09/20

Upload: kouhei-sutou

Post on 15-Jun-2015

250 views

Category:

Technology


2 download

DESCRIPTION

This talk describes three Ruby usages: * Implementing high-level interface by Ruby. * Using Ruby as a glue language. * Embedding Ruby into a C program for flexibility. All of them have pros and cons. They are trade-off. If a case can ignore cons, we will have pros for the case. Most of Rubyists implement their Ruby applications only by Ruby. This talk shows another options to use Ruby as your convenient tool. If you know another options and trade-offs of them, you will implement your Ruby applications more effectively. This talk uses Droonga, a distributed full-text search engine, as a sample application to describe these Ruby usages. Droonga uses these three Ruby usages.

TRANSCRIPT

Page 1: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Three Ruby usages

Kouhei SutouClearCode Inc.

RubyKaigi 20142014/09/20

Page 2: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Silver sponsor

Page 3: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Goal

You know three Ruby usagesHigh-level interface✓

Glue✓

Embed✓

You can remember them later✓

Page 4: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Targets

High-level interfacePure Rubyists✓

GlueRubyists who can write C/C++✓

EmbedRubyists who also write C/C++✓

Page 5: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Case study

Implement distributed full-text search engine in Ruby

Abbreviation: DFTSE = Distributed Full-Text Search Engine

Page 6: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

DFTSE?

Full-TextSearchEngine

DistrubutedFull-TextSearchEngine

1: Full-text search

2: Distributesub requests

3: Mergeresponses

Page 7: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Why do we use DFTSE?

I'm developing Droonga

(A DFTSE implementation in Ruby)

😃

Page 8: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

High-level interface

Three Ruby usages

High-level interface

Target: Pure Rubyists✓

Glue✓

Embed✓

Page 9: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

High-level interface

Provideslower layer feature tohigher layer

With simpler/convenience API✓

Page 10: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

High-level interface

Higher layer users

High-levelinterface

Feature

Application/Library

by Yukihiro Matsumoto

Page 11: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Example

Developers

Vagrantfile

Builddevelopmentenvironment

Vagrant

by Yuk i h i r o M a t s u m o t o

Developers

Object based API

Access data in RDBMS

Active Record

by Yuk i h i r o M a t s u m o t o

Vagrant Active Record

Page 12: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Droonga: High-level IF

DFTSE components

Full-text search engine✓

Messaging system✓

Cluster management✓

Process management✓

Page 13: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Messaging system

FTSE

DTFSE1: Full-text search

2: Distributesub requests

3: Mergeresponses

Messagingsystem

Workerprocess

Page 14: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Messaging system

Providesdistributed search featurePlan how to search✓

Distribute requests✓

Merge responses✓

Users don't know details✓

Page 15: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Characteristic

Plan how to searchMay speed up/down over 100 times✓

Distribute requestsNetwork bound operation✓

Merge responsesCPU and network bound operation✓

Page 16: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Point

Algorithm is importantNeed to find new/existing better algorithm

"Rapid prototype and measure" feedback loop is helpful

Ruby is good at rapid dev.✓

Page 17: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Glue

Three Ruby usages

High-level interface✓

Glue

Target:Rubyists who can write C/C++

Embed✓

Page 18: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Glue

Feature

Exporta feature

Glue

Ruby

OtherLanguage

Combinefeatures

Page 19: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Example

Feature

Active Record

Glue

libmysqlclient.so

mysql2 gem

Access to MySQL VM Provision

Vagrant

(VirtualBox) (Chef)

Page 20: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Why do we glue?

Reuse existing features✓

Page 21: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

How to glue

Use external libraryImplement bindings (mysql2 gem)✓

Use external commandSpawn command (Vagrant)✓

Use external serviceImplement client✓

Page 22: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Glue in Droonga

Rroonga: Groonga bindingsGroonga: FTSE C library (and server)✓

Cool.io: libev bindingslibev: Event loop C library(Based on I/O multiplexing and non-blocking I/O)

Serf: Clustering tool (in Droonga)✓

Page 23: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Rroonga in Droonga

FTSE

DTFSE1: Full-text search

2: Distributesub requests

3: Mergeresponses

Messagingsystem

Workerprocess

Page 24: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

FTSE in Droonga

Must be fast!✓

CPU bound processing✓

Page 25: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

For fast Rroonga

Do heavy processing in C

Nice to have Ruby-ish API✓

Less memory allocationCache internal buffer✓

MultiprocessingGroonga supports multiprocessing✓

Page 26: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search

Groonga::Database.open(ARGV[0])entries = Groonga["Entries"]

entries.select do |record| record.description =~ "Ruby"end

Page 27: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search - Pure Ruby (ref)

Groonga::Database.open(ARGV[0])entries = Groonga["Entries"]

entries.find_all do |record| # This block is evaluated for each record /Ruby/ =~ record.descriptionend

Page 28: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search impl.

# (2) Evaluate expression in Centries.select do |record| # (1) Build expression in Ruby # This block is evaluated only once record.description =~ "Ruby"end

Page 29: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search impl. - Fig.

Ruby

C

entries.select do |record| record.description =~ "Ruby"end

Expression

Build Searchrequest

Result set

Evaluate expressionby Groonga project

by Groonga project

Page 30: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search - Benchmark

Ruby (It's already showed)✓

C✓

Page 31: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search - C

grn_obj *expr;grn_obj *variable;const gchar *filter = "description @ \"Ruby\"";grn_obj *result;

GRN_EXPR_CREATE_FOR_QUERY(&ctx, table, expr, variable);grn_expr_parse(&ctx, expr, filter, strlen(filter), NULL, GRN_OP_MATCH, GRN_OP_AND, GRN_EXPR_SYNTAX_SCRIPT);result = grn_table_select(&ctx, table, expr, NULL, GRN_OP_OR);grn_obj_unlink(&ctx, expr);grn_obj_unlink(&ctx, result);

Page 32: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Search - Benchmark

Ruby impl. is fast enough 😃Impl. Elapsed time

C 0.6msRuby 0.8ms

(Full-text search with "Ruby" against 72632 records)

Page 33: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Embed

Three Ruby usages

High-level interface✓

Glue✓

Embed

Target:Rubyists who also write C/C++

Page 34: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Embed

C/C++ applicationC/C++ library

Implementsome featuresin Ruby

by Yukihiro Matsumoto

C/C++ applicationC/C++ library

Plugin APIConifugration

by Yukihiro Matsumoto

InterfaceInternal engine

Page 35: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Examples

Implementquery optimizerin Ruby

by Yukihiro Matsumoto VIM

vim-ruby by Yukihiro Matsumoto

InterfaceInternal engine

Page 36: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Embed in Droonga

...mrubyby The Groonga Project

by The Groonga Project

by The Groonga Project

by Yukihiro Matsumoto

by Yukihiro Matsumoto

by Yukihiro Matsumoto

Page 37: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

CRuby vs. mruby

CRubyFull featured!✓

Signal handler isn't needed 😞✓

mrubyMulti-interpreters in a process!✓

You may miss some features 😞✓

Page 38: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

mruby in Groonga

Query optimizer✓

Command interface (plan)Interface and also high-level interface!✓

Plugin API (plan)Interface!✓

Page 39: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Query optimizer

Query

QueryOptimizer

OptimizeOptimized

query

Evaluator

Full-text search

by Yukihiro Matsumoto

Result set

Page 40: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Query optimizer

Plan how to searchIt's a bother 😞✓

Light operation than FTS✓

Depends on data(Choose effective index, use table scan and so on)

Page 41: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Example

rank < 200 && rank > 100

Page 42: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Simple impl.

rank 1 2 100 200 10000...

rank > 100

rank < 200

&&

101 199

rank < 200 && rank > 100

... ... ...

101 199...

Page 43: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Simple impl.

Slow againstmany out of range data

Page 44: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Optimized impl.

rank 1 2 100 200 10000...

100 < rank < 200

101 199

rank < 200 && rank > 100

... ... ...

101 199...

Page 45: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Is embedding reasonable?

Measure

Page 46: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Measure

mruby overhead✓

Speed-up by optimization✓

Page 47: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Overhead

Small overhead: Reasonable😃# conds mruby Elapsed

1 ○ 0.24ms1 × 0.16ms4 ○ 0.45ms4 × 0.19ms

Page 48: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Speed-up

Fast for many data:Reasonable😃# records mruby no mruby

1000 0.29ms 0.31ms10000 0.31ms 2.3ms100000 0.26ms 21.1ms1000000 0.26ms 210.2ms

Page 49: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Note

Embedding needs many worksWrite bindings, import mruby your build system and ...

How to test your mruby part?And how to debug?✓

Page 50: Three Ruby usages

Conclusion

Page 51: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Conclusion 1

Describe three Ruby usagesHigh-level interface✓

Glue✓

Embed✓

Page 52: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Conclusion 2

High-level interfaceTarget: Pure Rubyists✓

Provides lower layer feature to higher layer w/ usable interface

Ruby's flexibility is useful✓

Page 53: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Conclusion 3

GlueTarget:Rubyists who can write C/C++

Why: Reuse existing feature✓

To be fast, do the process in C✓

Page 54: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Conclusion 4

EmbedTarget:Rubyists who also write C/C++

Why:Avoid bother programming by Ruby

Page 55: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Conclusion 5

EmbedIs it reasonable for your case?✓

You need many works✓

Very powerfulif your case is reasonable😃

Page 56: Three Ruby usages

Three Ruby usages Powered by Rabbit 2.1.4

Announcement

ClearCode Inc.A silver sponsor✓

Is recruiting✓

Will do readable code workshop✓

The next Groonga conferenceIt's held at 11/29✓