Upgrade to Pro — share decks privately, control downloads, hide ads and more …

月間10億PVから学んだMongoDBアンチパターン

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for yujiosaka yujiosaka
November 11, 2014

 月間10億PVから学んだMongoDBアンチパターン

ZenClerkが月間10億PVを支えるまでの
 過程で経験したアンチパターンを紹介

Avatar for yujiosaka

yujiosaka

November 11, 2014
Tweet

More Decks by yujiosaka

Other Decks in Technology

Transcript

  1. architecture: front-end: [ “AngularJS” “Ruby on Rails” “MySQL” “memcached”
 “AWS”

    ] back-end: [ “Node.js”
 “MongoDB” “socket.io” “Redis”
 “AWS” ]
  2. architecture: front-end: [ “AngularJS” “Ruby on Rails” “MySQL” “memcached”
 “AWS”

    ] back-end: [ “Node.js”
 “MongoDB” “socket.io” “Redis”
 “AWS” ]
  3. 1ԯPVʙ10ԯPV replica set shard mongos replica set shard replica set

    shard delayed replica delayed replica delayed replica mongoc
  4. -> ಡΈࠐΈॏࢹ -> 1ΫΤϦ1ώοτ -> ίϝϯτ਺ʹԠͯ͡
 ॻ͖ࠐΈ͕ॏ͘ͳΔ υΩϡϝϯτΛຒΊࠐΉ session:
 _id:

    “session_id”
 device: “iPhone”
 page_views: [
 {url: “/items/1”}
 ] timeline:
 _id: “yujiosaka”
 tag: “#dbtechshowcase”
 tweets: [
 {text: “MongoDB Rocks!”}
 ]
  5. -> ॻ͖ࠐΈॏࢹ -> 2ΫΤϦN+1ώοτ -> ॻ͖ࠐΈ͸εέʔϧ͢Δ υΩϡϝϯτΛຒΊࠐ·ͳ͍ session:
 _id: “session_id”


    device: “iPhone”
 page_views: [
 {url: “/items/1”}
 ] timeline:
 _id: “yujiosaka”
 tag: “#dbtechshowcase” ! tweet: _id: 1234
 user_id: “yujiosaka”
 text: “MongoDB Rocks!”
  6. timeline:
 _id: “yujiosaka-20141111”
 tag: “#dbtechshowcase”
 tweets: [
 {text: “MongoDB Rocks!”}


    ] -> όϥϯεܕ -> 1ΫΤϦ೔਺෼ώοτ -> ॻ͖ࠐΈ͸1೔෼·Ͱ
 ͔͠ॏ͘ͳΒͳ͍ ϋΠϒϦου
  7. before: user = new mongoose.Schema first: {type: String, required: true,

    index: true} last: {type: String, required: true, index: true} city: {type: String, required: true, index: true} ... created_at: {type: Date, default: Date.now, index: true} ! ॻ͖ࠐΈ͕٘ਜ਼ʹͳͬͯ΋ಡΈࠐΈ͕ૣ͚Ε͹͍͍͡ΌΜʂ
  8. after: user = new mongoose.Schema first: {type: String, required: true}

    last: {type: String, required: true} city: {type: String, required: true} ... created_at: {type: Date, default: Date.now} ! ॻ͖ࠐΈ͕٘ਜ਼ʹͳͬͯ΋ಡΈࠐΈ͕ૣ͚Ε͹͍͍͡ΌΜʂ
  9. Α͘ݟ͔͚Δίʔυᶄ -> σʔλ͕ݟ͔ͭͬͨΒߋ৽͠ɺݟ͔ͭΒͳ͔ͬͨΒ࡞੒͢Δ -> Ұݟෳࡶͳίʔυ var user = db.users.findOne({_id: “yujiosaka”});

    if (user) { user.count += 1;
 user.save(); } else { db.users.insert({_id: “yujiosaka”, count: 1}); }
  10. RedisΛ࢖Θͳ͍৔߹ db.col.update({_id: 1234}, {$push: {points: {x: 151, y: 100}});
 db.col.update({_id:

    1234}, {$push: {points: {x: 151, y: 179}});
 db.col.update({_id: 1234}, {$push: {points: {x: 151, y: 266}});
 …
 db.col.update({_id: 1234}, {$push: {points: {x: 151, y: 340}}); -> ࠲ඪ͕Ҡಈ͢ΔͨͼʹMongoDBʹॻ͖ࠐ·ΕΔ -> αΠζ͕ऩ·Γ੾Βͳ͍ͱɺσʔλͷҠಈ͕ى͖Δ
  11. RedisΛ࢖ͬͨ৔߹ db.col.insert({points: [
 {x: 151, y: 100},
 {x: 151, y:

    179},
 {x: 151, y: 266},
 …
 {x: 151, y: 340}
 ]}); -> Ұ౓͔͠MongoDBʹॻ͖ࠐ·ͳ͍ -> υΩϡϝϯυͷαΠζ͸͜ΕҎ্େ͖͘ͳΒͳ͍