LevelDB on S3 As A KVS

LevelDB on S3 As A KVS

6e8d1cd646b7cc589fdd5bdea0fd9bf1?s=128

shunsukeaihara

June 02, 2015
Tweet

Transcript

  1. LevelDB'on'S3'As'A'KVS

  2. Who$am$I • Shunsuke)Aihara(@shunsukeaihara) • Ξυ΍ͬͯΔ • ܭࢉݴޠֶ • ը૾ॲཧɾԻ੠ॲཧɾݴޠॲཧͷϥΠ ϒϥϦ͍Ζ͍Ζॻ͍ͯΔ

    • h1ps:/ /bitbucket.org/aihara
  3. ΞυαʔόΛϦϓϨΠεͨ͠ • Python(tornado)͔Βgo.+.kamiʹॻ͖׵͑ • όουϊ΢ϋ΢Λ՚ྷʹશճආ

  4. 50ms%or%DieΛ્Ή΋ͷ 1. Redis 2. Redis 3. Redis 4. GIL 5.

    etc
  5. ՄೳͳݶΓڞ༗DBΛ৮Βͳ͍ ΫϥελͷϝϯςͭΒ͍ Redis͸γϯάϧεϨου

  6. ΞυḉͰRDB৮Δౕ͸ԿΛ΍ͬͯ΋μϝ

  7. AWSͰҰ൪҆ఆ͍ͯ҆͠෼ࢄDB͸?

  8. S3

  9. S3ͷ࢖͍υίϩ • S3Λͦͷ··KVSͱͯ͠࢖͏ • ผͷαʔϏεͰ࣮ࢪ&/&݁ߏεέʔϧ • shard&keyͱ͔ࢦఆͰ͖Δ͚ͲΞυαʔόͰ͸ϨΠςϯγͷ໰ ୊͕ • S3্ʹϑΝΠϧDBΛ഑ஔ

    • ϑΝΠϧDBΛόϥϚΩ
  10. LevelDBΛS3ʹ഑ஔ • Norikra(+(Redshi/(+(PythonΫϥελͰ౷ܭ৘ใ΍ɺλʔήςΟ ϯά৘ใΛ͍ΖΜͳϥΠϑαΠΫϧͰߋ৽ • MessagepackܗࣜͰɺLevelDBʹ์ΓࠐΉ • h=ps:/ /github.com/shunsukeaihara/goDleveldbDobjectstorage/ •

    ֎෦ެ։൛
  11. goଆ࣮૷ • golevelΛར༻ • ىಈ࣌ʹLevelDBΛμ΢ϯϩʔυ • λΠϚʔͰఆظతʹ࠶μ΢ϯϩʔυ • ҰͭͷLevelDBϑΝΠϧ΁ͷΞΫηε͸ҰͭͷGorou-neͰ •

    ϑΝΠϧͷચ͍ସ͑ͳΜ͔΋ಛʹؾʹ͠ͳ͍
  12. CommandύλʔϯͬΆ͍࣮૷ • get(unpack)/set/expireͱ͔ • ଎౓ΑΓ΋ChannelΛ༻͍ͨՄಡੑΛ • MessagepackΛUnpackͨ͠σʔλ͸ΦϯϝϞϦͰΩϟογϡ • RedisͬΆ͍ExpireΛ࣮૷ •

    Expire΋:merͱChannelͰ࣮૷
  13. 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 } }
  14. 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 }
  15. ͦΕͰ΋RedisɾMemcache͕ඞཁͳॴ΋…… • Redisࣗମ͸ਨ௚෼ࢄ/ਫฏ෼ࢄ • RedisΫϥελʹରͯ͠΋LevelDBΞΫηεͱಉ༷ɺػೳຖʹ 1Goru2neΛׂΓ౰ͯ • MessagepackΛUnpackͨ͠σʔλ΋Ωϟογϡ • ͬͪ͜ʹ΋RedisͬΆ͍expireઓུΛ࣮૷

  16. ݁Ռ • ςΩτ΢ʹॻ͍ͯे෼ૣ͍ • PythonͰॻ͍͍ͯͨαʔόͷ8ഒͷεϧʔϓοτ • 10ms-or-Die͙Β͍ͷ଎౓Ͱಈ࡞ • ܕ͕༗Δͷ͸େ෼خ͍͠ͱ͍͏ؾ࣋ͪ •

    ίʔυҾ͖ܧ͗࣌ͷܕͷ͋Γ͕ͨ͞