Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> ฐานข้อมูล

Optimizing MongoDB: เทคนิคพิสูจน์แล้วลด Storage Waste

Appboy = Leading Marketing Automation Platform สำหรับ Mobile Apps รวบรวม Billions of Data Points/เดือน Track User Behavior ใน Apps ให้ Customers Target Users สำหรับ Emails, Push Notifications, In-app Messages ตาม Behavior/Demographics MongoDB Power Most Database Stack โหลดหลายสิบ Shards Across Clusters ที่ ObjectRocket

Common Performance Optimization: ใช้ Short Field Names ใน Documents แทนที่จะเป็น:

{first_name: "Jon", last_name: "Hyman"}

ใช้ Short Field Names:

{fn: "Jon", ln: "Hyman"}

MongoDB ไม่มี Columns/Predefined Schemas Field Names Duplicate บนทุก Document หาก 1 Million Documents มี Field "first_name" = Store String 1 Million Times -> More Space/Document -> Impact Documents Fit in Memory -> Large Scale ส่งผล Performance เล็กน้อย (Map Documents into Memory ขณะ Read)

Appboy เก็บ "Custom Attributes" บน User Document เช่น Sports App: "Favorite Player" Magazine App: "Annual Subscriber" User Document เก็บ Custom Attributes + Fields (First/Last Name) Shorten Field Names ทุกอย่าง Known Fields (First Name, Email, Gender) -> Alias เอง (fn = first name) แต่ Custom Attributes Names ไม่ Predict ได้ หาก Customer ตั้ง "supercalifragilisticexpialidocious" ไม่อยาก Store บนทุก Document

แก้ด้วย: Tokenize Custom Attribute Field Names ด้วย "Name Store" = Document ใน MongoDB Map Values (เช่น "Favorite Player") -> Unique, Predictable, Very Short String Generate Map ด้วย MongoDB Atomic Operators เท่านั้น

Name Store Document Schema: 1 Document ต่อ Customer, 1 Array Field "list" Array เก็บ Custom Attribute Values ทั้งหมด Index ของ String = Token Translate "Favorite Player" -> Short Field Name: Check "list" หาตำแหน่งใน Array ไม่มี -> Atomic Push Add Element ท้าย Array (db.custom_attribute_name_stores.update({_id:X, list:{$ne:"Favorite Player"}}, {$push:{list:"Favorite Player"}})) Reload Document หา Index $addToSet ไม่ Guarantee Ordering $push Documented Append ท้าย Default

ตอนนี้ Translate "Favorite Player" -> Integer Value สมมติ 1 User Document:

{ fn: "Jon", ln: "Hyman", custom: { 1: "LeBron James" } }

Field Names Short และ Tidy! Side Effect: ไม่ต้องกังวล Characters ที่ MongoDB ไม่รองรับโดยไม่ Escape (Dollar Signs, Periods)

MongoDB Warn Against Constantly Growing Documents Name Store Document อาจ Grow Unbounded ใน Practice Extend Implementation: Store >1 Document Per Customer Cap Array Elements ก่อน Generate New Document ยัง Atomic ด้วย MongoDB เพิ่ม Field "leastvalue" = Elements Added ใน Previous Documents ก่อน Create Document นี้ ตัวอย่าง: leastvalue 100, list ["Season Ticket Holder", "Favorite Player"] -> Token "Favorite Player" = 101 (Zero-based) Store 100 Values ใน "list" ก่อน New Document Insert: Modify Push Operate บน Document ที่ leastvalue สูงสุด และ Ensure "list.99" ไม่มี (Index 99 ว่าง) หากมี Element อยู่ Index 99 Push ไม่ทำอะไร -> Create New Name Store Document leastvalue = Total Elements Across All Documents Atomic $findAndModify Create New Doc If Not Exist Fetch Back Retry $push

Customer มี Custom Attributes เยอะ Read Back All Name Store Docs Translate Values->Tokens = Expensive Bandwidth/Processing แต่ Token Value คงที่หลัง Compute -> Cache Tokens Speed Up Translation

Applied "Name Store Token" Paradigm ในหลายส่วน App ลด Field Name Sizes รักษา Flexible Schema ช่วย Values ด้วย เช่น Radio App: Custom Attribute = Array Top 50 Artists แทน 50 Strings -> Tokenize Artist Names Store 50 Integers Query Users ชอบ Artist = 2 Token Lookups (Field + Value) Cache Translation -> Multi-get Cache Layer Single Round-trip

Optimization นี้ Add Indirection/Complexity แต่ Store Hundreds of Millions Users เหมือน Appboy Worthwhile Saved Hundreds of GBs Expensive SSD Space

อยากเรียนรู้เพิ่ม? ผมพูด DevOps at Appboy ระหว่าง Rackspace Solve NYC Conference Sept 18th ที่ Cipriani