Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LevelDB on S3 As A KVS
Search
shunsukeaihara
June 02, 2015
Programming
2.9k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
LevelDB on S3 As A KVS
shunsukeaihara
June 02, 2015
More Decks by shunsukeaihara
See All by shunsukeaihara
BONXを支える技術:発話区間検出(VAD)の話/Akerun & BONX Tech Talk
shunsukeaihara
4
7.8k
Goのnet.TCPConnの話/shibuya.go01
shunsukeaihara
3
880
Norikra in Gunosy Network Ads@Norikra meetup #2
shunsukeaihara
1
6.1k
色恒常性仮説に基づく色補正ライブラリcolorcorrect / 2015-01-31-kantocv27
shunsukeaihara
3
2.6k
Sparkによる分散処理 / 2015-01-16 PyData.Tokyo#3
shunsukeaihara
11
3.6k
ゼロから始めた Gunosyアドサーバ開発運用記 / 2014-12-16-dots
shunsukeaihara
6
1.2k
Gunosy.Go#5 index/io/log
shunsukeaihara
0
200
Gunosy.go#2 package/compress
shunsukeaihara
0
140
Other Decks in Programming
See All in Programming
エンジニアと一緒にテストコードの設計と実装を改善した話
mototakatsu
0
260
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
230
共通化で考えるべきは、実装より公開する型だった
codeegg
0
220
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
130
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
2
300
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
440
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
Creating Composable Callables in Contemporary C++
rollbear
0
200
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
350
ランチタイムLT会3周年!ランチタイムLT会を3年間続けられたお話
y0hgi
1
140
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.4k
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
141
7.6k
A better future with KSS
kneath
240
18k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
610
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
240
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
190
The Limits of Empathy - UXLibs8
cassininazir
1
470
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
270
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
970
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.3k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
260
Transcript
LevelDB'on'S3'As'A'KVS
Who$am$I • Shunsuke)Aihara(@shunsukeaihara) • ΞυͬͯΔ • ܭࢉݴޠֶ • ը૾ॲཧɾԻॲཧɾݴޠॲཧͷϥΠ ϒϥϦ͍Ζ͍Ζॻ͍ͯΔ
• h1ps:/ /bitbucket.org/aihara
ΞυαʔόΛϦϓϨΠεͨ͠ • Python(tornado)͔Βgo.+.kamiʹॻ͖͑ • όουϊϋΛ՚ྷʹશճආ
50ms%or%DieΛ્Ήͷ 1. Redis 2. Redis 3. Redis 4. GIL 5.
etc
ՄೳͳݶΓڞ༗DBΛ৮Βͳ͍ ΫϥελͷϝϯςͭΒ͍ RedisγϯάϧεϨου
ΞυḉͰRDB৮ΔౕԿΛͬͯμϝ
AWSͰҰ൪҆ఆ͍ͯ҆͠ࢄDB?
S3
S3ͷ͍υίϩ • S3Λͦͷ··KVSͱͯ͠͏ • ผͷαʔϏεͰ࣮ࢪ&/&݁ߏεέʔϧ • shard&keyͱ͔ࢦఆͰ͖Δ͚ͲΞυαʔόͰϨΠςϯγͷ ͕ • S3্ʹϑΝΠϧDBΛஔ
• ϑΝΠϧDBΛόϥϚΩ
LevelDBΛS3ʹஔ • Norikra(+(Redshi/(+(PythonΫϥελͰ౷ܭใɺλʔήςΟ ϯάใΛ͍ΖΜͳϥΠϑαΠΫϧͰߋ৽ • MessagepackܗࣜͰɺLevelDBʹ์ΓࠐΉ • h=ps:/ /github.com/shunsukeaihara/goDleveldbDobjectstorage/ •
֎෦ެ։൛
goଆ࣮ • golevelΛར༻ • ىಈ࣌ʹLevelDBΛμϯϩʔυ • λΠϚʔͰఆظతʹ࠶μϯϩʔυ • ҰͭͷLevelDBϑΝΠϧͷΞΫηεҰͭͷGorou-neͰ •
ϑΝΠϧͷચ͍ସ͑ͳΜ͔ಛʹؾʹ͠ͳ͍
CommandύλʔϯͬΆ͍࣮ • get(unpack)/set/expireͱ͔ • ΑΓChannelΛ༻͍ͨՄಡੑΛ • MessagepackΛUnpackͨ͠σʔλΦϯϝϞϦͰΩϟογϡ • RedisͬΆ͍ExpireΛ࣮ •
Expire:merͱChannelͰ࣮
gcTick := time.NewTicker(10 * time.Second) defer gcTick.Stop() updateTick := time.NewTicker(time.Duration(ldb.dbConf.Options.UpdateInterval)
* time.Second) defer updateTick.Stop() for { select { case cmd := <-ldb.get: cmd.result <- ldb.execGet(cmd) case <-ldb.reset: ldb.cache = map[string]*cachedItem{} case <-updateTick.C: ldb.mu.RLock() if !ldb.downloading { go ldb.download(ctx, true) } ldb.mu.RUnlock() case msg := <-ldb.switchDB: oldDB := ldb.db oldPath := ldb.dbpath ldb.db = msg.db ldb.dbpath = msg.dbpath oldDB.Close() os.RemoveAll(oldPath) case <-ldb.expire: ldb.simpleExpire(1) case <-gcTick.C: ldb.simpleExpire(1) case msg := <-ldb.exit: ldb.db.Close() os.RemoveAll(ldb.dbpath) ldb.cache = map[string]*cachedItem{} msg <- struct{}{} break } }
IFͱ͔ • ςΩτʹΦϨΦϨDSL͔ΒδΣωͬͯΔ func GetCandidate(ctx context.Context, key string) ([]*data.Candidate, bool)
{ ldb, ok := levelDBFromContext(ctx, candidateDBKey) if !ok { panic("no candidate db in context") } res, ok, _ := ldb.getCandidate(key) return res, ok } func (ldb *LevelDB) getCandidate(key string) ([]*data.Candidate, bool, bool) { cmd := NewDBGetCmd(key, data.UnmarshalCandidates, int64(ldb.dbConf.Options.CacheExpire)) ldb.get <- cmd r := <-cmd.result if !r.ok { return nil, false, false } return r.val.([]*data.Candidate), r.ok, r.hit }
ͦΕͰRedisɾMemcache͕ඞཁͳॴ…… • Redisࣗମਨࢄ/ਫฏࢄ • RedisΫϥελʹରͯ͠LevelDBΞΫηεͱಉ༷ɺػೳຖʹ 1Goru2neΛׂΓͯ • MessagepackΛUnpackͨ͠σʔλΩϟογϡ • ͬͪ͜ʹRedisͬΆ͍expireઓུΛ࣮
݁Ռ • ςΩτʹॻ͍ͯेૣ͍ • PythonͰॻ͍͍ͯͨαʔόͷ8ഒͷεϧʔϓοτ • 10ms-or-Die͙Β͍ͷͰಈ࡞ • ܕ͕༗Δͷେخ͍͠ͱ͍͏ؾ࣋ͪ •
ίʔυҾ͖ܧ͗࣌ͷܕͷ͋Γ͕ͨ͞