Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
LevelDB on S3 As A KVS
Search
shunsukeaihara
June 02, 2015
Programming
3k
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
890
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
150
Other Decks in Programming
See All in Programming
The Rails Doctrine Decade
koic
2
550
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
220
AWSに止められる覚悟してますか?
morizo_1984
2
520
sbt 2.0: takeoff
eed3si9n
0
120
速習iPhone Duo対応
yuukiw00w
2
980
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.1k
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
330
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
160
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.3k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
110
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
610
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
740
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
520
Testing 201, or: Great Expectations
jmmastey
46
8.3k
A Soul's Torment
seathinner
8
3.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
Chasing Engaging Ingredients in Design
codingconduct
0
350
How to make the Groovebox
asonas
2
2.5k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.1k
Writing Fast Ruby
sferik
630
63k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
440
Abbi's Birthday
coloredviolet
4
10k
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͙Β͍ͷͰಈ࡞ • ܕ͕༗Δͷେخ͍͠ͱ͍͏ؾ࣋ͪ •
ίʔυҾ͖ܧ͗࣌ͷܕͷ͋Γ͕ͨ͞