SlideShare a Scribd company logo
1 of 70
Download to read offline
Hiroshi Nakamura
Software Engineer
Treasure Data, K.K.
『Embulk』に見るモダンJavaの実践的テクニック

∼並列分散処理システムの実装手法∼
1
#ccc_cd4 / #embulk
#ccc_cd4 / #embulk
Today’s talk
Embulkとは
> バルクデータ転送の難しさ
> Embulkのアプローチ
> アーキテクチャ概要
Java実装技術
> Java 7ネイティブ
> Guiceによるコンポーネント間の接続
> ServiceLoaderによる拡張
> Jacksonによるモデルクラス、Immutable
> Nettyバッファアロケータ、Unsafe
2
#ccc_cd4 / #embulk
Embulkとは? - http://embulk.org/
> オープンソースのバルクデータ転送ツール
> “A” から “B” へレコードを転送
> プラグイン機構
> 多様な “A” と “B” の組み合わせ
> データ連携を容易に
> システム構築の頭痛の種の一つ
Storage, RDBMS,
NoSQL, Cloud Service, …
broken records,

error recovery, maintenance,

performance, …
3
#ccc_cd4 / #embulk
Embulk committers
Hiroshi Nakamura
@nahi
Muga Nishizawa
@muga_nishizawa
Sadayuki Furuhashi
@frsyuki
4
#ccc_cd4 / #embulk
バルクデータ転送の難しさ
> 入力データの正規化
> エラー処理
> メンテナンス
> 性能
#ccc_cd4 / #embulk
入力データ正規化の難しさ
データエンコーディングのバリエーション
> null、時刻、浮動小数点
> 改行、エスケープ、レコード/カラム区切り
> 文字コード、圧縮有無
→ 試行によるデータ正規化
#ccc_cd4 / #embulk
エラー処理の難しさ
例外値の扱い
ネットワークエラーからの復旧
ディスクフルからの復旧
重複データ転送の回避
→ データバリデーション、リトライ、リジューム
#ccc_cd4 / #embulk
メンテナンスの難しさ
継続的な動作の確保
データ転送要件変更への対応
→ ドキュメント、汎用化、OSS化
#ccc_cd4 / #embulk
性能の問題
転送データ量は通常増えていく
対象レコードも増えたりする
→ 並列・分散処理
#ccc_cd4 / #embulk
バルクデータ転送の例
指定された 10GB CSV file をPostgreSQLにロード
> 1. コマンド叩いてみる → 失敗
> 2. データを正規化するスクリプトを作成
”20150127T190500Z”→“2015-01-27 19:05:00 UTC”に
“null”→“N”に変換
元データを見ながら気付く限り…
> 3. 再度チャレンジ → 取り込まれたが元データと合わない
“Inf”→“Infinity”に変換
> 4. ひたすら繰り返す
> 5. うっかりレコードが重複して取り込まれた…
#ccc_cd4 / #embulk
バルクデータ転送の例
指定された 10GB CSV file をPostgreSQLにロード
> 6. スクリプトが完成
> 7. cronに登録して毎日バルクデータロードするよう登録
> 8. ある日別の原因でエラーに…
不正なUTF-8 byte sequenceをU+FFFDに変換
#ccc_cd4 / #embulk
バルクデータ転送の例
過去の日次 10GB CSV file を 730個 取り込む(2年分)
> 1. たいていのスクリプトは遅い
> 最適化してる暇がない
> 1ファイル1時間、エラー発生しなかったとして1ヶ月
> 2. 並列データロードするようスクリプト変更
> 3. ある日ディスクフル/ネットワークエラーで失敗
> どこまで読み込まれた?
> 4. 障害後に再開し易いよう、データロード単位を調整
> 5. 安全な再開機能をスクリプトに追加
#ccc_cd4 / #embulk
システム構築の頭痛の種
様々な転送データ、データストレージ
> CSV, TSV, JSON, XML, MessagePack, SequenceFile,
RCFile
> S3, Salesforce.com, Google Cloud Storage,
BigQuery, Elasticsearch
> MySQL, PostgreSQL, Oracle, MS SQL Server,
Amazon Redshift, Redis, MongoDB
#ccc_cd4 / #embulk
HDFS
MySQL
Amazon S3
CSV Files
SequenceFile
Salesforce.com
Elasticsearch
Cassandra
Hive
Redis
Broken
script :(
Sometimes
fails :(
No one
can fix :(
14
#ccc_cd4 / #embulk
HDFS
MySQL
Amazon S3
CSV Files
SequenceFile
Salesforce.com
Elasticsearch
Cassandra
Hive
Redis
Broken
script :(
Sometimes
fails :(
No one
can fix :(
N x M

scripts!
> Poor error handling
> No retrying / resuming
> Low performance
> Often no maitainers
15
#ccc_cd4 / #embulk
Embulkのアプローチ
> プラグインアーキテクチャ
> 入力データ正規化支援: guess, preview
> 並列・分散実行
> 繰り返し実行
> トランザクション制御
16
#ccc_cd4 / #embulk
HDFS
MySQL
Amazon S3
CSV Files
SequenceFile
Salesforce.com
Elasticsearch
Cassandra
Hive
Redis
Broken
script :(
Sometimes
fails :(
No one
can fix :(
17
#ccc_cd4 / #embulk
HDFS
MySQL
Amazon S3
CSV Files
SequenceFile
Salesforce.com
Elasticsearch
Cassandra
Hive
Redis
Reliable
framework :-)
18
#ccc_cd4 / #embulk
HDFS
MySQL
Amazon S3
CSV Files
SequenceFile
Salesforce.com
Elasticsearch
Cassandra
Hive
Redis
PluginsPlugins
Reusable
plugins
19
#ccc_cd4 / #embulk
プラグインアーキテクチャ
拡張ポイントが再利用可能なコンポーネントを定義
従っている限りフレームワークの恩恵を受けられる
> 並列処理、繰り返し実行、エラー処理、リカバリ
20
#ccc_cd4 / #embulk
Embulkプラグインの例
RubyGemsとして配布 - http://www.embulk.org/plugins/
> DB
> Oracle, MySQL, PostgreSQL, Amazon Redshift
> 検索エンジン
> Elasticsearch
> クラウドサービス
> Salesforce.com
> Amazon S3
> Google Cloud Storage, Google BigQuery
> ファイルフォーマット
> CSV, TSV, JSON, XML
> pcap packet capture files
> gzip, bzip2, zip, tar, cpio
21
#ccc_cd4 / #embulk
デモ
> guessとpreview
> 並列・分散実行
> 繰り返し実行
> トランザクション処理
> プラグインのサンプル
22
#ccc_cd4 / #embulk
Embulkアーキテクチャ概要
#ccc_cd4 / #embulk
InputPlugin OutputPlugin
Executor plugin
Filter plugin
Filter plugin
Filter plugins
records
Threads,
MapReduce
records
convert, …
input, … output.
24
records
config
#ccc_cd4 / #embulk
InputPlugin
FileInput plugin
OutputPlugin
Decoder plugin
Parser plugin
HDFS, S3,

Riak CS, …
gzip, bzip2,

aes, …
CSV, JSON,

pcap, …
buffer
buffer
Filter plugin
Filter plugin
Filter plugins
records
records
Executor plugin
25
records
config
#ccc_cd4 / #embulk
InputPlugin
FileInput plugin
OutputPlugin
FileOutput plugin
Encoder plugin
Formatter plugin
Decoder plugin
Parser plugin
HDFS, S3,

Riak CS, …
gzip, bzip2,

aes, …
CSV, JSON,

pcap, …
buffer
buffer
buffer
buffer
Filter plugin
Filter plugin
Filter plugins
recordsrecords
Executor plugin
26
records
config
#ccc_cd4 / #embulk
Embulkアーキテクチャ概要
4種のプラグインとそれを組み上げるフレームワーク
1. Executor: 実行
2. Input: バルクデータのレコード群を取り込み
FileInput, Decoder, Parser: ファイル操作
3. Filter: レコードに対するデータ操作
4. Output: バルクデータのレコード群を出力
FileOutput, Encoder, Formatter: ファイル操作
#ccc_cd4 / #embulk
InputPlugin OutputPlugin
Executor plugin
Filter plugin
Filter plugin
Filter plugins
28
records records
records
config diff
#ccc_cd4 / #embulk
InputPlugin OutputPlugin
Executor plugin
Filter plugin
Filter plugin
Filter plugins
29
task
schema
report
task
schema
report
records records
task
schema
records
resume state
config
#ccc_cd4 / #embulk
Embulkの実装技術
> Java 7ネイティブ
> Guiceによるコンポーネント間の接続
> ServiceLoaderによる拡張
> Jacksonによるモデルクラス
> Immutableなモデルクラス
> Nettyバッファアロケータ
> sun.misc.Unsafeによるバッファコピー回避
30
#ccc_cd4 / #embulk
Java 7ネイティブ
try-with-resources
ファイル操作:Files & Paths API
※Date and TimeはJRubyの実装を利用
try (SetCurrentThreadName dontCare =
new SetCurrentThreadName(“transaction”))
{
return doRun(config);
}
Path basePath = Paths.get(“.”).normalize();
Path file = basePath.resolve(“relative.csv”);
#ccc_cd4 / #embulk
Guiceによるコンポーネント間の接続
32
public class EmbulkService
{
protected final Injector injector;
public EmbulkService(ConfigSource systemConfig)
{
ImmutableList.Builder<Module> modules = ImmutableList.builder();
modules.add(new SystemConfigModule(systemConfig));
modules.add(new ExecModule());
modules.add(new ExtensionServiceLoaderModule(systemConfig));
modules.add(new BuiltinPluginSourceModule());
modules.add(new JRubyScriptingModule(systemConfig));
injector = Guice.createInjector(modules.build());
}
public Injector getInjector()
{
return injector;
}
}
#ccc_cd4 / #embulk
Guiceによるコンポーネント間の接続
33
public class EmbulkService
{
protected final Injector injector;
public EmbulkService(ConfigSource systemConfig)
{
ImmutableList.Builder<Module> modules = ImmutableList.builder();
modules.add(new SystemConfigModule(systemConfig));
modules.add(new ExecModule());
modules.add(new ExtensionServiceLoaderModule(systemConfig));
modules.add(new BuiltinPluginSourceModule());
modules.add(new JRubyScriptingModule(systemConfig));
injector = Guice.createInjector(modules.build());
}
public Injector getInjector()
{
return injector;
}
}
public class ExecModule implements Module
{
@Override
public void configure(Binder binder)
{
...
binder.bind(LocalThreadExecutor.class).in(Scopes.SINGLETON);
registerPluginTo(binder, ExecutorPlugin.class, "local", LocalExecutorPlugin.class);
#ccc_cd4 / #embulk
Guiceによるコンポーネント間の接続
34
public class EmbulkService
{
protected final Injector injector;
public EmbulkService(ConfigSource systemConfig)
{
ImmutableList.Builder<Module> modules = ImmutableList.builder();
modules.add(new SystemConfigModule(systemConfig));
modules.add(new ExecModule());
modules.add(new ExtensionServiceLoaderModule(systemConfig));
modules.add(new BuiltinPluginSourceModule());
modules.add(new JRubyScriptingModule(systemConfig));
injector = Guice.createInjector(modules.build());
}
public Injector getInjector()
{
return injector;
}
}
public class ExecModule implements Module
{
@Override
public void configure(Binder binder)
{
...
binder.bind(LocalThreadExecutor.class).in(Scopes.SINGLETON);
registerPluginTo(binder, ExecutorPlugin.class, "local", LocalExecutorPlugin.class);
public class LocalExecutorPlugin implements ExecutorPlugin
{
private final ExecutorService executor;
@Inject
public LocalExecutorPlugin(LocalThreadExecutor executor)
{
this.executor = executor.getExecutorService();
...



(InjectedPluginSource)

public T newPlugin(Injector injector)
{
return (T) new FileInputRunner((FileInputPlugin) injector.getInstance(impl));
#ccc_cd4 / #embulk
Guiceによるコンポーネント間の接続
XMLでなくすべてJavaで書く系のDI
Annotationによる宣言的なDI、

injectorによる動的なDIの組み合わせ
> 動的なモジュール差し替えがし易い
#ccc_cd4 / #embulk
ServiceLoaderによる拡張
public class ExtensionServiceLoaderModule implements Module
{
private final ConfigSource systemConfig;
public ExtensionServiceLoaderModule(ConfigSource systemConfig)
{
this.systemConfig = systemConfig;
}
@Override
public void configure(Binder binder)
{
ServiceLoader<Extension> serviceLoader =
ServiceLoader.load(Extension.class, classLoader);
for (Extension extension : serviceLoader) {
for (Module module : extension.getModules(systemConfig)) {
module.configure(binder);
}
}
}
}
#ccc_cd4 / #embulk
ServiceLoaderによる拡張
jarをclasspathに入れるだけでモジュール追加/差し替え
簡単でClassLoaderいじるよりは安全
標準Plugin群の登録に利用
※Pluginの読み込みはClassLoader
#ccc_cd4 / #embulk
Jacksonによるモデルクラス(task)
public class CsvParserPlugin
implements ParserPlugin
{
public interface PluginTask
extends Task, LineDecoder.DecoderTask, TimestampParser.ParserTask
{
@Config("columns")
public SchemaConfig getSchemaConfig();
@Config("header_line")
@ConfigDefault("null")
public Optional<Boolean> getHeaderLine();
@Config("skip_header_lines")
@ConfigDefault("0")
public int getSkipHeaderLines();
public void setSkipHeaderLines(int n);
@Config("delimiter")
@ConfigDefault("","")
public char getDelimiterChar();
#ccc_cd4 / #embulk
InputPlugin OutputPlugin
Executor plugin
Filter plugin
Filter plugin
Filter plugins
39
task
schema
report
task
schema
report
records records
task
schema
records
config
config diff
resume state
#ccc_cd4 / #embulk
Jacksonによるモデルクラス(schema)
public class ColumnConfig
{
private final String name;
private final Type type;
@JsonCreator
public ColumnConfig(
@JsonProperty("name") String name,
@JsonProperty("type") Type type)
{
this.name = name;
this.type = type;
}
@JsonProperty("name")
public String getName() { return name; }
@JsonProperty("type")
public Type getType() { return type; }
}
#ccc_cd4 / #embulk
Jacksonによるモデルクラス
デ/シリアライズが重要
> 並列・分散実行のため
> Ruby <-> Javaのやりとりのため
IDL生成でなくすべてJavaで書く系のモデル
#ccc_cd4 / #embulk
Immutableなモデルクラス
ソースコード中のfinalなメンバー変数の割合
> Presto:83%(4714変数)
> Embulk:72%(255変数)
> Cassandra:59%(2348変数)
> Elasticsearch:51%(6871変数)
> Nashorn (OpenJDK 8):43%(852変数)
> JRuby:40%(3154変数)
> Hadoop:31%(9280変数)
> Hive:23%(4600変数)
#ccc_cd4 / #embulk
Nettyバッファアロケータ
レコード群のためのメモリをすべて自前管理
> OutOfMemoryが起きる前に検出
> GCコスト削減
複数のバルクロードセッションを

サーバプロセス内で同時実行可能に
#ccc_cd4 / #embulk
Nettyバッファアロケータ
レコード群のためのメモリをすべて自前管理
> OutOfMemoryが起きる前に検出
> GCコスト削減
複数のバルクロードセッションを

サーバプロセス内で同時実行可能に
public Buffer allocate(int minimumCapacity)
{
int size = MINIMUM_BUFFER_SIZE;
while (size < minimumCapacity) {
size *= 2;
}
return new NettyByteBufBuffer(nettyBuffer.buffer(size));
}
#ccc_cd4 / #embulk
Unsafe
airlift/slice - sun.misc.Unsafe APIのwrapper
> バイト列の直接操作(デ/シリアライズ)
> コピー削減
参考: http://frsyuki.hatenablog.com/entry/
2014/03/12/155231
#ccc_cd4 / #embulk
Unsafe
airlift/slice - sun.misc.Unsafe APIのwrapper
> バイト列の直接操作(デ/シリアライズ)
> コピー削減
参考: http://frsyuki.hatenablog.com/entry/
2014/03/12/155231
public void addRecord()
{
// record header
bufferSlice.setInt(position, nextVariableLengthDataOffset);
bufferSlice.setBytes(position + 4, nullBitSet);
count++;
this.position += nextVariableLengthDataOffset;
this.nextVariableLengthDataOffset = fixedRecordSize;
Arrays.fill(nullBitSet, (byte) 0);
// flush if next record will not fit in this buffer
if (buffer.capacity() < position +

nextVariableLengthDataOffset + stringReferenceSize) {
flush();
}
}
47
ユーザー
転送
管理コンソール
から実行
トレジャー
クラウドストレージ
Embulk
Worker
管理コンソール
からアクセス
S3のインポートから,エクスポー
トまでを完全自動化
#ccc_cd4 / #embulk
Contributing to the Embulk project
> Pull-requests & issues on Github
> Posting blogs
> “使ってみた”
> “コードを読んでみた”
> “ここがイケてる / イケてない”
> Talking on Twitter with a word “embulk"
> Writing & releasing plugins
> Windows support
> Integration to other software
> ETL tools, Fluentd, Hadoop, Presto, …
48
1. Distributed Systems Engineer
2. Integration Engineer
3. Software Engineer, MPP DBMS
4. Sales Engineer
5. Technical Support Engineer
(日本,東京,丸の内)

https://jobs.lever.co/treasure-data
We’re hiring!
ANALYTICS INFRASTRUCTURE. SIMPLIFIED IN THE CLOUD.
50
#ccc_cd4 / #embulk
FluentdとEmbulk
52
This?
53
Or this?
M x N → M + N
Nagios
MongoDB
Hadoop
Alerting
Amazon S3
Analysis
Archiving
MySQL
Apache
Frontend
Access logs
syslogd
App logs
System logs
Backend
Databases
buffer/filter/route
#ccc_cd4 / #embulk
FluentdとEmbulk
ストリーミングデータコレクター

vs バルクデータローダー
ストリーミングデータか、転送単位がはっきり
しているバルクデータか
任意データ vs データバリデーション・正規化
即時 vs トランザクション性
#ccc_cd4 / #embulk
Embulkの実行
インストール
guess
preview
繰り返し実行
56
# install
$ wget https://bintray.com/artifact/download/
embulk/maven/embulk-0.2.0.jar -o embulk.jar
$ chmod 755 embulk.jar
Installing embulk
Bintray

releases
Embulk is released on Bintray
wget embulk.jar
# install
$ wget https://bintray.com/artifact/download/
embulk/maven/embulk-0.2.0.jar -o embulk.jar
$ chmod 755 embulk.jar

# guess
$ vi partial-config.yml
$ ./embulk guess partial-config.yml

-o config.yml
Guess format & schema in:
type: file
paths: [data/examples/]
out:

type: example
in:
type: file
paths: [data/examples/]
decoders:
- {type: gzip}
parser:
charset: UTF-8
newline: CRLF
type: csv
delimiter: ','
quote: '"'
header_line: true
columns:
- name: time

type: timestamp

format: '%Y-%m-%d %H:%M:%S'
- name: account

type: long
- name: purchase

type: timestamp

format: '%Y%m%d'
- name: comment

type: string
out:

type: example
guess
by guess plugins
# install
$ wget https://bintray.com/artifact/download/
embulk/maven/embulk-0.2.0.jar -o embulk.jar
$ chmod 755 embulk.jar

# guess
$ vi partial-config.yml
$ ./embulk guess partial-config.yml

-o config.yml

# preview
$ ./embulk preview config.yml
$ vi config.yml # if necessary
+--------------------------------------+---------------+--------------------+
| time:timestamp | uid:long | word:string |
+--------------------------------------+---------------+--------------------+
| 2015-01-27 19:23:49 UTC | 32,864 | embulk |
| 2015-01-27 19:01:23 UTC | 14,824 | jruby |
| 2015-01-28 02:20:02 UTC | 27,559 | plugin |
| 2015-01-29 11:54:36 UTC | 11,270 | fluentd |
+--------------------------------------+---------------+--------------------+
Preview & fix config
# install
$ wget https://bintray.com/artifact/download/
embulk/maven/embulk-0.2.0.jar -o embulk.jar
$ chmod 755 embulk.jar

# guess
$ vi partial-config.yml
$ ./embulk guess partial-config.yml

-o config.yml

# preview
$ ./embulk preview config.yml
$ vi config.yml # if necessary
# run
$ ./embulk run config.yml -o config.yml
in:
type: file
paths: [data/examples/]
decoders:
- {type: gzip}
parser:
charset: UTF-8
newline: CRLF
type: csv
delimiter: ','
quote: '"'
header_line: true
columns:
- name: time

type: timestamp

format: '%Y-%m-%d %H:%M:%S'
- name: account

type: long
- name: purchase

type: timestamp

format: '%Y%m%d'
- name: comment

type: string
last_paths: [data/examples/sample_001.csv.gz]
out:

type: example
Deterministic run
in:
type: file
paths: [data/examples/]
decoders:
- {type: gzip}
parser:
charset: UTF-8
newline: CRLF
type: csv
delimiter: ','
quote: '"'
header_line: true
columns:
- name: time

type: timestamp

format: '%Y-%m-%d %H:%M:%S'
- name: account

type: long
- name: purchase

type: timestamp

format: '%Y%m%d'
- name: comment

type: string
last_paths: [data/examples/sample_002.csv.gz]
out:

type: example
Repeat
# install
$ wget https://bintray.com/artifact/download/
embulk/maven/embulk-0.2.0.jar -o embulk.jar
$ chmod 755 embulk.jar

# guess
$ vi partial-config.yml
$ ./embulk guess partial-config.yml

-o config.yml

# preview
$ ./embulk preview config.yml
$ vi config.yml # if necessary
# run
$ ./embulk run config.yml -o config.yml
# repeat
$ ./embulk run config.yml -o config.yml
$ ./embulk run config.yml -o config.yml
#ccc_cd4 / #embulk
Writing Embulk plugins
62
InputPlugin
module Embulk
class InputExample < InputPlugin
Plugin.register_input('example', self)
def self.transaction(config, &control)
# read config
task = {
'message' =>
config.param('message', :string, default: nil)
}
threads = config.param('threads', :int, default:
2)
columns = [
Column.new(0, 'col0', :long),
Column.new(1, 'col1', :double),
Column.new(2, 'col2', :string),
]
# BEGIN here
commit_reports = yield(task, columns, threads)
# COMMIT here
puts "Example input finished"
return {}
end
def run(task, schema, index, page_builder)
puts "Example input thread #{@index}…"
10.times do |i|
@page_builder.add([i, 10.0, "example"])
end
@page_builder.finish
commit_report = { }
return commit_report
end
end
end
OutputPlugin
module Embulk
class OutputExample < OutputPlugin
Plugin.register_output('example', self)
def self.transaction(
config, schema,
processor_count, &control)
# read config
task = {
'message' =>
config.param('message', :string, default: "record")
}
puts "Example output started."
commit_reports = yield(task)
puts "Example output finished. Commit
reports = #{commit_reports.to_json}"
return {}
end
def initialize(task, schema, index)
puts "Example output thread #{index}..."
super
@message = task.prop('message', :string)
@records = 0
end
def add(page)
page.each do |record|
hash = Hash[schema.names.zip(record)]
puts "#{@message}: #{hash.to_json}"
@records += 1
end
end
def finish
end
def abort
end
def commit
commit_report = {
"records" => @records
}
return commit_report
end
end
end
GuessPlugin
# guess_gzip.rb
module Embulk
class GzipGuess < GuessPlugin
Plugin.register_guess('gzip', self)
GZIP_HEADER = "x1f
x8b".force_encoding('ASCII-8BIT').freeze
def guess(config, sample_buffer)
if sample_buffer[0,2] == GZIP_HEADER
return {"decoders" => [{"type" => "gzip"}]}
end
return {}
end
end
end
# guess_
module Embulk
class GuessNewline < TextGuessPlugin
Plugin.register_guess('newline', self)
def guess_text(config, sample_text)
cr_count = sample_text.count("r")
lf_count = sample_text.count("n")
crlf_count = sample_text.scan(/rn/).length
if crlf_count > cr_count / 2 && crlf_count >
lf_count / 2
return {"parser" => {"newline" => "CRLF"}}
elsif cr_count > lf_count / 2
return {"parser" => {"newline" => "CR"}}
else
return {"parser" => {"newline" => "LF"}}
end
end
end
end
#ccc_cd4 / #embulk
Releasing to RubyGems
Examples
> embulk-plugin-postgres-json.gem
> https://github.com/frsyuki/embulk-plugin-postgres-json
> embulk-plugin-redis.gem
> https://github.com/komamitsu/embulk-plugin-redis
> embulk-plugin-input-sfdc-event-log-files.gem
> https://github.com/nahi/embulk-plugin-input-sfdc-event-
log-files
#ccc_cd4 / #embulk
plugin bundle
> embulk bundle <dir>
> Gemfile
Attention!
Presto Presto Presto Presto
Presto Presto Presto Presto
Presto Presto Presto Presto
Presto Presto Presto Presto
Presto Presto Presto Presto
68
Attention!
Hive Hive Hive Hive
Hive Hive Hive Hive
Hive Hive Hive Hive
Hive Hive Hive Hive
69
Hive Hive Hive Hive
Hive Hive HiveHive
PrestoPrestogres
hba.conf
PostgreSQL
70

More Related Content

What's hot

クラウドでも非機能要求グレードは必要だよね
クラウドでも非機能要求グレードは必要だよねクラウドでも非機能要求グレードは必要だよね
クラウドでも非機能要求グレードは必要だよねYoshioSawada
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
AWS Batch Fargate対応は何をもたらすか
AWS Batch Fargate対応は何をもたらすかAWS Batch Fargate対応は何をもたらすか
AWS Batch Fargate対応は何をもたらすかShun Fukazawa
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!mosa siru
 
脱 Excel設計書
脱 Excel設計書脱 Excel設計書
脱 Excel設計書rai
 
私にとってのテスト
私にとってのテスト私にとってのテスト
私にとってのテストTakuto Wada
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAkihiro Kuwano
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
MySQLからPostgreSQLへのマイグレーションのハマリ所
MySQLからPostgreSQLへのマイグレーションのハマリ所MySQLからPostgreSQLへのマイグレーションのハマリ所
MySQLからPostgreSQLへのマイグレーションのハマリ所Makoto Kaga
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはJun-ichi Sakamoto
 
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきことこれからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと土岐 孝平
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)NTT DATA Technology & Innovation
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンKentaro Yoshida
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 

What's hot (20)

クラウドでも非機能要求グレードは必要だよね
クラウドでも非機能要求グレードは必要だよねクラウドでも非機能要求グレードは必要だよね
クラウドでも非機能要求グレードは必要だよね
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
AWS Batch Fargate対応は何をもたらすか
AWS Batch Fargate対応は何をもたらすかAWS Batch Fargate対応は何をもたらすか
AWS Batch Fargate対応は何をもたらすか
 
Google Cloud で実践する SRE
Google Cloud で実践する SRE  Google Cloud で実践する SRE
Google Cloud で実践する SRE
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
脱 Excel設計書
脱 Excel設計書脱 Excel設計書
脱 Excel設計書
 
私にとってのテスト
私にとってのテスト私にとってのテスト
私にとってのテスト
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
AWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティスAWSのログ管理ベストプラクティス
AWSのログ管理ベストプラクティス
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
MySQLからPostgreSQLへのマイグレーションのハマリ所
MySQLからPostgreSQLへのマイグレーションのハマリ所MySQLからPostgreSQLへのマイグレーションのハマリ所
MySQLからPostgreSQLへのマイグレーションのハマリ所
 
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とはがんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
がんばらなくても C# で Single Page Web アプリケーションが書けてしまう「Blazor」とは
 
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。 【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
【BS4】時は来たれり。今こそ .NET 6 へ移行する時。
 
Guide To AGPL
Guide To AGPLGuide To AGPL
Guide To AGPL
 
これからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきことこれからSpringを使う開発者が知っておくべきこと
これからSpringを使う開発者が知っておくべきこと
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 

Viewers also liked

Embulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderEmbulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderSadayuki Furuhashi
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11Sadayuki Furuhashi
 
Embulk - 進化するバルクデータローダ
Embulk - 進化するバルクデータローダEmbulk - 進化するバルクデータローダ
Embulk - 進化するバルクデータローダSadayuki Furuhashi
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方Hiroshi Nakamura
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingDebasish Ghosh
 
Next Generation Big Data Platform at Netflix 2014
Next Generation Big Data Platform at Netflix 2014Next Generation Big Data Platform at Netflix 2014
Next Generation Big Data Platform at Netflix 2014Eva Tse
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDebasish Ghosh
 
Transportasi melburne
Transportasi melburneTransportasi melburne
Transportasi melburneIsmail Hasan
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2mganeko
 
Java 20年史 (JJUG CCC 2015 春 基調講演)
Java 20年史 (JJUG CCC 2015 春 基調講演)Java 20年史 (JJUG CCC 2015 春 基調講演)
Java 20年史 (JJUG CCC 2015 春 基調講演)Kazuyuki Kawamura
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaVladimir Kostyukov
 
初心を思いだしてみよう
初心を思いだしてみよう初心を思いだしてみよう
初心を思いだしてみようSayaka Nakano
 
EdogawaLib(20130728)
EdogawaLib(20130728)EdogawaLib(20130728)
EdogawaLib(20130728)真 岡本
 
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.scalaconfjp
 
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)Fukushima University
 
社会人プログラマが覚えておきたい 抽象化と具体化の事例
社会人プログラマが覚えておきたい 抽象化と具体化の事例社会人プログラマが覚えておきたい 抽象化と具体化の事例
社会人プログラマが覚えておきたい 抽象化と具体化の事例Akira Kozakai
 

Viewers also liked (20)

Embulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loaderEmbulk, an open-source plugin-based parallel bulk data loader
Embulk, an open-source plugin-based parallel bulk data loader
 
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
分散ワークフローエンジン『Digdag』の実装 at Tokyo RubyKaigi #11
 
Embulk - 進化するバルクデータローダ
Embulk - 進化するバルクデータローダEmbulk - 進化するバルクデータローダ
Embulk - 進化するバルクデータローダ
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modeling
 
Next Generation Big Data Platform at Netflix 2014
Next Generation Big Data Platform at Netflix 2014Next Generation Big Data Platform at Netflix 2014
Next Generation Big Data Platform at Netflix 2014
 
Grails 2.0 Update
Grails 2.0 UpdateGrails 2.0 Update
Grails 2.0 Update
 
Beyond Scala Lens
Beyond Scala LensBeyond Scala Lens
Beyond Scala Lens
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approach
 
Transportasi melburne
Transportasi melburneTransportasi melburne
Transportasi melburne
 
Spring3.1概要x di
Spring3.1概要x diSpring3.1概要x di
Spring3.1概要x di
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2
 
Java 20年史 (JJUG CCC 2015 春 基調講演)
Java 20年史 (JJUG CCC 2015 春 基調講演)Java 20年史 (JJUG CCC 2015 春 基調講演)
Java 20年史 (JJUG CCC 2015 春 基調講演)
 
Purely Functional Data Structures in Scala
Purely Functional Data Structures in ScalaPurely Functional Data Structures in Scala
Purely Functional Data Structures in Scala
 
初心を思いだしてみよう
初心を思いだしてみよう初心を思いだしてみよう
初心を思いだしてみよう
 
EdogawaLib(20130728)
EdogawaLib(20130728)EdogawaLib(20130728)
EdogawaLib(20130728)
 
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.ビズリーチ x ScalaMatsuri  by BIZREACH, Inc.
ビズリーチ x ScalaMatsuri by BIZREACH, Inc.
 
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)
副詞的修飾関係の論点と課題(Meaning-knowledge Problem on Japanese Adverbial Relations.)
 
社会人プログラマが覚えておきたい 抽象化と具体化の事例
社会人プログラマが覚えておきたい 抽象化と具体化の事例社会人プログラマが覚えておきたい 抽象化と具体化の事例
社会人プログラマが覚えておきたい 抽象化と具体化の事例
 
プロダクトデザインとしてのライティング
プロダクトデザインとしてのライティングプロダクトデザインとしてのライティング
プロダクトデザインとしてのライティング
 

Similar to Embulk 20150411

ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌A AOKI
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますfukuoka.ex
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」fukuoka.ex
 
2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコムTomoyaTakegoshi
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugY Watanabe
 
社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)Iwana Chan
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたHideaki Aoyagi
 
20091030cakephphandson 01
20091030cakephphandson 0120091030cakephphandson 01
20091030cakephphandson 01Yusuke Ando
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.jsTanUkkii
 
これから始めるAzure Kubernetes Service入門
これから始めるAzure Kubernetes Service入門これから始めるAzure Kubernetes Service入門
これから始めるAzure Kubernetes Service入門Yuto Takei
 
New Features in C# 10/11
New Features in C# 10/11New Features in C# 10/11
New Features in C# 10/11Akira Inoue
 
The Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionThe Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionYoshifumi Kawai
 
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWINHow to Make Own Framework built on OWIN
How to Make Own Framework built on OWINYoshifumi Kawai
 
Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Daiyu Hatakeyama
 
20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-publicAmazon Web Services Japan
 
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlikPresalesJapan
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)Daisuke Ikeda
 
DCK Server プロトタイプ
DCK Server プロトタイプDCK Server プロトタイプ
DCK Server プロトタイプEtsuji Nakai
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Masahito Zembutsu
 

Similar to Embulk 20150411 (20)

ASP.NET vNextの全貌
ASP.NET vNextの全貌ASP.NET vNextの全貌
ASP.NET vNextの全貌
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
 
2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム2019年度 CaaS ワークショップ @ NTTコム
2019年度 CaaS ワークショップ @ NTTコム
 
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsugSpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
 
社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)
 
AKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみたAKS と ACI を組み合わせて使ってみた
AKS と ACI を組み合わせて使ってみた
 
20091030cakephphandson 01
20091030cakephphandson 0120091030cakephphandson 01
20091030cakephphandson 01
 
Isomorphic web development with scala and scala.js
Isomorphic web development  with scala and scala.jsIsomorphic web development  with scala and scala.js
Isomorphic web development with scala and scala.js
 
これから始めるAzure Kubernetes Service入門
これから始めるAzure Kubernetes Service入門これから始めるAzure Kubernetes Service入門
これから始めるAzure Kubernetes Service入門
 
New Features in C# 10/11
New Features in C# 10/11New Features in C# 10/11
New Features in C# 10/11
 
The Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnionThe Usage and Patterns of MagicOnion
The Usage and Patterns of MagicOnion
 
How to Make Own Framework built on OWIN
How to Make Own Framework built on OWINHow to Make Own Framework built on OWIN
How to Make Own Framework built on OWIN
 
Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版Azure Machine Learning Services 概要 - 2019年2月版
Azure Machine Learning Services 概要 - 2019年2月版
 
20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public20120528 aws meister-reloaded-awssd-kforjava-public
20120528 aws meister-reloaded-awssd-kforjava-public
 
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装までQlik TechFest C-5  Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
Qlik TechFest C-5 Qlikエンジンのサーバーサイド拡張(SSE)の 基礎から実装まで
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
 
DCK Server プロトタイプ
DCK Server プロトタイプDCK Server プロトタイプ
DCK Server プロトタイプ
 
Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話Docker ComposeでMastodonが必要なものを梱包する話
Docker ComposeでMastodonが必要なものを梱包する話
 

More from Hiroshi Nakamura

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSHiroshi Nakamura
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in rubyHiroshi Nakamura
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasHiroshi Nakamura
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyHiroshi Nakamura
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyHiroshi Nakamura
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)Hiroshi Nakamura
 

More from Hiroshi Nakamura (9)

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSS
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in ruby
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvas
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)
 
現実世界のJRuby
現実世界のJRuby現実世界のJRuby
現実世界のJRuby
 
HSM超入門講座
HSM超入門講座HSM超入門講座
HSM超入門講座
 

Recently uploaded

LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (10)

LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 

Embulk 20150411

  • 1. Hiroshi Nakamura Software Engineer Treasure Data, K.K. 『Embulk』に見るモダンJavaの実践的テクニック
 ∼並列分散処理システムの実装手法∼ 1 #ccc_cd4 / #embulk
  • 2. #ccc_cd4 / #embulk Today’s talk Embulkとは > バルクデータ転送の難しさ > Embulkのアプローチ > アーキテクチャ概要 Java実装技術 > Java 7ネイティブ > Guiceによるコンポーネント間の接続 > ServiceLoaderによる拡張 > Jacksonによるモデルクラス、Immutable > Nettyバッファアロケータ、Unsafe 2
  • 3. #ccc_cd4 / #embulk Embulkとは? - http://embulk.org/ > オープンソースのバルクデータ転送ツール > “A” から “B” へレコードを転送 > プラグイン機構 > 多様な “A” と “B” の組み合わせ > データ連携を容易に > システム構築の頭痛の種の一つ Storage, RDBMS, NoSQL, Cloud Service, … broken records,
 error recovery, maintenance,
 performance, … 3
  • 4. #ccc_cd4 / #embulk Embulk committers Hiroshi Nakamura @nahi Muga Nishizawa @muga_nishizawa Sadayuki Furuhashi @frsyuki 4
  • 5. #ccc_cd4 / #embulk バルクデータ転送の難しさ > 入力データの正規化 > エラー処理 > メンテナンス > 性能
  • 6. #ccc_cd4 / #embulk 入力データ正規化の難しさ データエンコーディングのバリエーション > null、時刻、浮動小数点 > 改行、エスケープ、レコード/カラム区切り > 文字コード、圧縮有無 → 試行によるデータ正規化
  • 10. #ccc_cd4 / #embulk バルクデータ転送の例 指定された 10GB CSV file をPostgreSQLにロード > 1. コマンド叩いてみる → 失敗 > 2. データを正規化するスクリプトを作成 ”20150127T190500Z”→“2015-01-27 19:05:00 UTC”に “null”→“N”に変換 元データを見ながら気付く限り… > 3. 再度チャレンジ → 取り込まれたが元データと合わない “Inf”→“Infinity”に変換 > 4. ひたすら繰り返す > 5. うっかりレコードが重複して取り込まれた…
  • 11. #ccc_cd4 / #embulk バルクデータ転送の例 指定された 10GB CSV file をPostgreSQLにロード > 6. スクリプトが完成 > 7. cronに登録して毎日バルクデータロードするよう登録 > 8. ある日別の原因でエラーに… 不正なUTF-8 byte sequenceをU+FFFDに変換
  • 12. #ccc_cd4 / #embulk バルクデータ転送の例 過去の日次 10GB CSV file を 730個 取り込む(2年分) > 1. たいていのスクリプトは遅い > 最適化してる暇がない > 1ファイル1時間、エラー発生しなかったとして1ヶ月 > 2. 並列データロードするようスクリプト変更 > 3. ある日ディスクフル/ネットワークエラーで失敗 > どこまで読み込まれた? > 4. 障害後に再開し易いよう、データロード単位を調整 > 5. 安全な再開機能をスクリプトに追加
  • 13. #ccc_cd4 / #embulk システム構築の頭痛の種 様々な転送データ、データストレージ > CSV, TSV, JSON, XML, MessagePack, SequenceFile, RCFile > S3, Salesforce.com, Google Cloud Storage, BigQuery, Elasticsearch > MySQL, PostgreSQL, Oracle, MS SQL Server, Amazon Redshift, Redis, MongoDB
  • 14. #ccc_cd4 / #embulk HDFS MySQL Amazon S3 CSV Files SequenceFile Salesforce.com Elasticsearch Cassandra Hive Redis Broken script :( Sometimes fails :( No one can fix :( 14
  • 15. #ccc_cd4 / #embulk HDFS MySQL Amazon S3 CSV Files SequenceFile Salesforce.com Elasticsearch Cassandra Hive Redis Broken script :( Sometimes fails :( No one can fix :( N x M
 scripts! > Poor error handling > No retrying / resuming > Low performance > Often no maitainers 15
  • 16. #ccc_cd4 / #embulk Embulkのアプローチ > プラグインアーキテクチャ > 入力データ正規化支援: guess, preview > 並列・分散実行 > 繰り返し実行 > トランザクション制御 16
  • 17. #ccc_cd4 / #embulk HDFS MySQL Amazon S3 CSV Files SequenceFile Salesforce.com Elasticsearch Cassandra Hive Redis Broken script :( Sometimes fails :( No one can fix :( 17
  • 18. #ccc_cd4 / #embulk HDFS MySQL Amazon S3 CSV Files SequenceFile Salesforce.com Elasticsearch Cassandra Hive Redis Reliable framework :-) 18
  • 19. #ccc_cd4 / #embulk HDFS MySQL Amazon S3 CSV Files SequenceFile Salesforce.com Elasticsearch Cassandra Hive Redis PluginsPlugins Reusable plugins 19
  • 21. #ccc_cd4 / #embulk Embulkプラグインの例 RubyGemsとして配布 - http://www.embulk.org/plugins/ > DB > Oracle, MySQL, PostgreSQL, Amazon Redshift > 検索エンジン > Elasticsearch > クラウドサービス > Salesforce.com > Amazon S3 > Google Cloud Storage, Google BigQuery > ファイルフォーマット > CSV, TSV, JSON, XML > pcap packet capture files > gzip, bzip2, zip, tar, cpio 21
  • 22. #ccc_cd4 / #embulk デモ > guessとpreview > 並列・分散実行 > 繰り返し実行 > トランザクション処理 > プラグインのサンプル 22
  • 24. #ccc_cd4 / #embulk InputPlugin OutputPlugin Executor plugin Filter plugin Filter plugin Filter plugins records Threads, MapReduce records convert, … input, … output. 24 records config
  • 25. #ccc_cd4 / #embulk InputPlugin FileInput plugin OutputPlugin Decoder plugin Parser plugin HDFS, S3,
 Riak CS, … gzip, bzip2,
 aes, … CSV, JSON,
 pcap, … buffer buffer Filter plugin Filter plugin Filter plugins records records Executor plugin 25 records config
  • 26. #ccc_cd4 / #embulk InputPlugin FileInput plugin OutputPlugin FileOutput plugin Encoder plugin Formatter plugin Decoder plugin Parser plugin HDFS, S3,
 Riak CS, … gzip, bzip2,
 aes, … CSV, JSON,
 pcap, … buffer buffer buffer buffer Filter plugin Filter plugin Filter plugins recordsrecords Executor plugin 26 records config
  • 27. #ccc_cd4 / #embulk Embulkアーキテクチャ概要 4種のプラグインとそれを組み上げるフレームワーク 1. Executor: 実行 2. Input: バルクデータのレコード群を取り込み FileInput, Decoder, Parser: ファイル操作 3. Filter: レコードに対するデータ操作 4. Output: バルクデータのレコード群を出力 FileOutput, Encoder, Formatter: ファイル操作
  • 28. #ccc_cd4 / #embulk InputPlugin OutputPlugin Executor plugin Filter plugin Filter plugin Filter plugins 28 records records records config diff
  • 29. #ccc_cd4 / #embulk InputPlugin OutputPlugin Executor plugin Filter plugin Filter plugin Filter plugins 29 task schema report task schema report records records task schema records resume state config
  • 30. #ccc_cd4 / #embulk Embulkの実装技術 > Java 7ネイティブ > Guiceによるコンポーネント間の接続 > ServiceLoaderによる拡張 > Jacksonによるモデルクラス > Immutableなモデルクラス > Nettyバッファアロケータ > sun.misc.Unsafeによるバッファコピー回避 30
  • 31. #ccc_cd4 / #embulk Java 7ネイティブ try-with-resources ファイル操作:Files & Paths API ※Date and TimeはJRubyの実装を利用 try (SetCurrentThreadName dontCare = new SetCurrentThreadName(“transaction”)) { return doRun(config); } Path basePath = Paths.get(“.”).normalize(); Path file = basePath.resolve(“relative.csv”);
  • 32. #ccc_cd4 / #embulk Guiceによるコンポーネント間の接続 32 public class EmbulkService { protected final Injector injector; public EmbulkService(ConfigSource systemConfig) { ImmutableList.Builder<Module> modules = ImmutableList.builder(); modules.add(new SystemConfigModule(systemConfig)); modules.add(new ExecModule()); modules.add(new ExtensionServiceLoaderModule(systemConfig)); modules.add(new BuiltinPluginSourceModule()); modules.add(new JRubyScriptingModule(systemConfig)); injector = Guice.createInjector(modules.build()); } public Injector getInjector() { return injector; } }
  • 33. #ccc_cd4 / #embulk Guiceによるコンポーネント間の接続 33 public class EmbulkService { protected final Injector injector; public EmbulkService(ConfigSource systemConfig) { ImmutableList.Builder<Module> modules = ImmutableList.builder(); modules.add(new SystemConfigModule(systemConfig)); modules.add(new ExecModule()); modules.add(new ExtensionServiceLoaderModule(systemConfig)); modules.add(new BuiltinPluginSourceModule()); modules.add(new JRubyScriptingModule(systemConfig)); injector = Guice.createInjector(modules.build()); } public Injector getInjector() { return injector; } } public class ExecModule implements Module { @Override public void configure(Binder binder) { ... binder.bind(LocalThreadExecutor.class).in(Scopes.SINGLETON); registerPluginTo(binder, ExecutorPlugin.class, "local", LocalExecutorPlugin.class);
  • 34. #ccc_cd4 / #embulk Guiceによるコンポーネント間の接続 34 public class EmbulkService { protected final Injector injector; public EmbulkService(ConfigSource systemConfig) { ImmutableList.Builder<Module> modules = ImmutableList.builder(); modules.add(new SystemConfigModule(systemConfig)); modules.add(new ExecModule()); modules.add(new ExtensionServiceLoaderModule(systemConfig)); modules.add(new BuiltinPluginSourceModule()); modules.add(new JRubyScriptingModule(systemConfig)); injector = Guice.createInjector(modules.build()); } public Injector getInjector() { return injector; } } public class ExecModule implements Module { @Override public void configure(Binder binder) { ... binder.bind(LocalThreadExecutor.class).in(Scopes.SINGLETON); registerPluginTo(binder, ExecutorPlugin.class, "local", LocalExecutorPlugin.class); public class LocalExecutorPlugin implements ExecutorPlugin { private final ExecutorService executor; @Inject public LocalExecutorPlugin(LocalThreadExecutor executor) { this.executor = executor.getExecutorService(); ...
 
 (InjectedPluginSource)
 public T newPlugin(Injector injector) { return (T) new FileInputRunner((FileInputPlugin) injector.getInstance(impl));
  • 36. #ccc_cd4 / #embulk ServiceLoaderによる拡張 public class ExtensionServiceLoaderModule implements Module { private final ConfigSource systemConfig; public ExtensionServiceLoaderModule(ConfigSource systemConfig) { this.systemConfig = systemConfig; } @Override public void configure(Binder binder) { ServiceLoader<Extension> serviceLoader = ServiceLoader.load(Extension.class, classLoader); for (Extension extension : serviceLoader) { for (Module module : extension.getModules(systemConfig)) { module.configure(binder); } } } }
  • 38. #ccc_cd4 / #embulk Jacksonによるモデルクラス(task) public class CsvParserPlugin implements ParserPlugin { public interface PluginTask extends Task, LineDecoder.DecoderTask, TimestampParser.ParserTask { @Config("columns") public SchemaConfig getSchemaConfig(); @Config("header_line") @ConfigDefault("null") public Optional<Boolean> getHeaderLine(); @Config("skip_header_lines") @ConfigDefault("0") public int getSkipHeaderLines(); public void setSkipHeaderLines(int n); @Config("delimiter") @ConfigDefault("","") public char getDelimiterChar();
  • 39. #ccc_cd4 / #embulk InputPlugin OutputPlugin Executor plugin Filter plugin Filter plugin Filter plugins 39 task schema report task schema report records records task schema records config config diff resume state
  • 40. #ccc_cd4 / #embulk Jacksonによるモデルクラス(schema) public class ColumnConfig { private final String name; private final Type type; @JsonCreator public ColumnConfig( @JsonProperty("name") String name, @JsonProperty("type") Type type) { this.name = name; this.type = type; } @JsonProperty("name") public String getName() { return name; } @JsonProperty("type") public Type getType() { return type; } }
  • 41. #ccc_cd4 / #embulk Jacksonによるモデルクラス デ/シリアライズが重要 > 並列・分散実行のため > Ruby <-> Javaのやりとりのため IDL生成でなくすべてJavaで書く系のモデル
  • 42. #ccc_cd4 / #embulk Immutableなモデルクラス ソースコード中のfinalなメンバー変数の割合 > Presto:83%(4714変数) > Embulk:72%(255変数) > Cassandra:59%(2348変数) > Elasticsearch:51%(6871変数) > Nashorn (OpenJDK 8):43%(852変数) > JRuby:40%(3154変数) > Hadoop:31%(9280変数) > Hive:23%(4600変数)
  • 43. #ccc_cd4 / #embulk Nettyバッファアロケータ レコード群のためのメモリをすべて自前管理 > OutOfMemoryが起きる前に検出 > GCコスト削減 複数のバルクロードセッションを
 サーバプロセス内で同時実行可能に
  • 44. #ccc_cd4 / #embulk Nettyバッファアロケータ レコード群のためのメモリをすべて自前管理 > OutOfMemoryが起きる前に検出 > GCコスト削減 複数のバルクロードセッションを
 サーバプロセス内で同時実行可能に public Buffer allocate(int minimumCapacity) { int size = MINIMUM_BUFFER_SIZE; while (size < minimumCapacity) { size *= 2; } return new NettyByteBufBuffer(nettyBuffer.buffer(size)); }
  • 45. #ccc_cd4 / #embulk Unsafe airlift/slice - sun.misc.Unsafe APIのwrapper > バイト列の直接操作(デ/シリアライズ) > コピー削減 参考: http://frsyuki.hatenablog.com/entry/ 2014/03/12/155231
  • 46. #ccc_cd4 / #embulk Unsafe airlift/slice - sun.misc.Unsafe APIのwrapper > バイト列の直接操作(デ/シリアライズ) > コピー削減 参考: http://frsyuki.hatenablog.com/entry/ 2014/03/12/155231 public void addRecord() { // record header bufferSlice.setInt(position, nextVariableLengthDataOffset); bufferSlice.setBytes(position + 4, nullBitSet); count++; this.position += nextVariableLengthDataOffset; this.nextVariableLengthDataOffset = fixedRecordSize; Arrays.fill(nullBitSet, (byte) 0); // flush if next record will not fit in this buffer if (buffer.capacity() < position +
 nextVariableLengthDataOffset + stringReferenceSize) { flush(); } }
  • 48. #ccc_cd4 / #embulk Contributing to the Embulk project > Pull-requests & issues on Github > Posting blogs > “使ってみた” > “コードを読んでみた” > “ここがイケてる / イケてない” > Talking on Twitter with a word “embulk" > Writing & releasing plugins > Windows support > Integration to other software > ETL tools, Fluentd, Hadoop, Presto, … 48
  • 49. 1. Distributed Systems Engineer 2. Integration Engineer 3. Software Engineer, MPP DBMS 4. Sales Engineer 5. Technical Support Engineer (日本,東京,丸の内)
 https://jobs.lever.co/treasure-data We’re hiring! ANALYTICS INFRASTRUCTURE. SIMPLIFIED IN THE CLOUD.
  • 50. 50
  • 54. M x N → M + N Nagios MongoDB Hadoop Alerting Amazon S3 Analysis Archiving MySQL Apache Frontend Access logs syslogd App logs System logs Backend Databases buffer/filter/route
  • 55. #ccc_cd4 / #embulk FluentdとEmbulk ストリーミングデータコレクター
 vs バルクデータローダー ストリーミングデータか、転送単位がはっきり しているバルクデータか 任意データ vs データバリデーション・正規化 即時 vs トランザクション性
  • 57. # install $ wget https://bintray.com/artifact/download/ embulk/maven/embulk-0.2.0.jar -o embulk.jar $ chmod 755 embulk.jar Installing embulk Bintray
 releases Embulk is released on Bintray wget embulk.jar
  • 58. # install $ wget https://bintray.com/artifact/download/ embulk/maven/embulk-0.2.0.jar -o embulk.jar $ chmod 755 embulk.jar
 # guess $ vi partial-config.yml $ ./embulk guess partial-config.yml
 -o config.yml Guess format & schema in: type: file paths: [data/examples/] out:
 type: example in: type: file paths: [data/examples/] decoders: - {type: gzip} parser: charset: UTF-8 newline: CRLF type: csv delimiter: ',' quote: '"' header_line: true columns: - name: time
 type: timestamp
 format: '%Y-%m-%d %H:%M:%S' - name: account
 type: long - name: purchase
 type: timestamp
 format: '%Y%m%d' - name: comment
 type: string out:
 type: example guess by guess plugins
  • 59. # install $ wget https://bintray.com/artifact/download/ embulk/maven/embulk-0.2.0.jar -o embulk.jar $ chmod 755 embulk.jar
 # guess $ vi partial-config.yml $ ./embulk guess partial-config.yml
 -o config.yml
 # preview $ ./embulk preview config.yml $ vi config.yml # if necessary +--------------------------------------+---------------+--------------------+ | time:timestamp | uid:long | word:string | +--------------------------------------+---------------+--------------------+ | 2015-01-27 19:23:49 UTC | 32,864 | embulk | | 2015-01-27 19:01:23 UTC | 14,824 | jruby | | 2015-01-28 02:20:02 UTC | 27,559 | plugin | | 2015-01-29 11:54:36 UTC | 11,270 | fluentd | +--------------------------------------+---------------+--------------------+ Preview & fix config
  • 60. # install $ wget https://bintray.com/artifact/download/ embulk/maven/embulk-0.2.0.jar -o embulk.jar $ chmod 755 embulk.jar
 # guess $ vi partial-config.yml $ ./embulk guess partial-config.yml
 -o config.yml
 # preview $ ./embulk preview config.yml $ vi config.yml # if necessary # run $ ./embulk run config.yml -o config.yml in: type: file paths: [data/examples/] decoders: - {type: gzip} parser: charset: UTF-8 newline: CRLF type: csv delimiter: ',' quote: '"' header_line: true columns: - name: time
 type: timestamp
 format: '%Y-%m-%d %H:%M:%S' - name: account
 type: long - name: purchase
 type: timestamp
 format: '%Y%m%d' - name: comment
 type: string last_paths: [data/examples/sample_001.csv.gz] out:
 type: example Deterministic run
  • 61. in: type: file paths: [data/examples/] decoders: - {type: gzip} parser: charset: UTF-8 newline: CRLF type: csv delimiter: ',' quote: '"' header_line: true columns: - name: time
 type: timestamp
 format: '%Y-%m-%d %H:%M:%S' - name: account
 type: long - name: purchase
 type: timestamp
 format: '%Y%m%d' - name: comment
 type: string last_paths: [data/examples/sample_002.csv.gz] out:
 type: example Repeat # install $ wget https://bintray.com/artifact/download/ embulk/maven/embulk-0.2.0.jar -o embulk.jar $ chmod 755 embulk.jar
 # guess $ vi partial-config.yml $ ./embulk guess partial-config.yml
 -o config.yml
 # preview $ ./embulk preview config.yml $ vi config.yml # if necessary # run $ ./embulk run config.yml -o config.yml # repeat $ ./embulk run config.yml -o config.yml $ ./embulk run config.yml -o config.yml
  • 62. #ccc_cd4 / #embulk Writing Embulk plugins 62
  • 63. InputPlugin module Embulk class InputExample < InputPlugin Plugin.register_input('example', self) def self.transaction(config, &control) # read config task = { 'message' => config.param('message', :string, default: nil) } threads = config.param('threads', :int, default: 2) columns = [ Column.new(0, 'col0', :long), Column.new(1, 'col1', :double), Column.new(2, 'col2', :string), ] # BEGIN here commit_reports = yield(task, columns, threads) # COMMIT here puts "Example input finished" return {} end def run(task, schema, index, page_builder) puts "Example input thread #{@index}…" 10.times do |i| @page_builder.add([i, 10.0, "example"]) end @page_builder.finish commit_report = { } return commit_report end end end
  • 64. OutputPlugin module Embulk class OutputExample < OutputPlugin Plugin.register_output('example', self) def self.transaction( config, schema, processor_count, &control) # read config task = { 'message' => config.param('message', :string, default: "record") } puts "Example output started." commit_reports = yield(task) puts "Example output finished. Commit reports = #{commit_reports.to_json}" return {} end def initialize(task, schema, index) puts "Example output thread #{index}..." super @message = task.prop('message', :string) @records = 0 end def add(page) page.each do |record| hash = Hash[schema.names.zip(record)] puts "#{@message}: #{hash.to_json}" @records += 1 end end def finish end def abort end def commit commit_report = { "records" => @records } return commit_report end end end
  • 65. GuessPlugin # guess_gzip.rb module Embulk class GzipGuess < GuessPlugin Plugin.register_guess('gzip', self) GZIP_HEADER = "x1f x8b".force_encoding('ASCII-8BIT').freeze def guess(config, sample_buffer) if sample_buffer[0,2] == GZIP_HEADER return {"decoders" => [{"type" => "gzip"}]} end return {} end end end # guess_ module Embulk class GuessNewline < TextGuessPlugin Plugin.register_guess('newline', self) def guess_text(config, sample_text) cr_count = sample_text.count("r") lf_count = sample_text.count("n") crlf_count = sample_text.scan(/rn/).length if crlf_count > cr_count / 2 && crlf_count > lf_count / 2 return {"parser" => {"newline" => "CRLF"}} elsif cr_count > lf_count / 2 return {"parser" => {"newline" => "CR"}} else return {"parser" => {"newline" => "LF"}} end end end end
  • 66. #ccc_cd4 / #embulk Releasing to RubyGems Examples > embulk-plugin-postgres-json.gem > https://github.com/frsyuki/embulk-plugin-postgres-json > embulk-plugin-redis.gem > https://github.com/komamitsu/embulk-plugin-redis > embulk-plugin-input-sfdc-event-log-files.gem > https://github.com/nahi/embulk-plugin-input-sfdc-event- log-files
  • 67. #ccc_cd4 / #embulk plugin bundle > embulk bundle <dir> > Gemfile
  • 68. Attention! Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto Presto 68
  • 69. Attention! Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive Hive 69
  • 70. Hive Hive Hive Hive Hive Hive HiveHive PrestoPrestogres hba.conf PostgreSQL 70