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

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

yujiosaka
November 11, 2014

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

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

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ʹॻ͖ࠐ·ͳ͍ -> υΩϡϝϯυͷαΠζ͸͜ΕҎ্େ͖͘ͳΒͳ͍