Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เคล็ดลับง่ายๆ ในการทำให้การปรับขนาดฐานข้อมูลของคุณง่ายขึ้นเมื่อคุณเติบโต

เมื่อคุณกำลังทำงานในโครงการใหม่ คุณกำลังตัดสินใจอยู่ตลอดเวลาซึ่งจะทำให้ง่ายขึ้นหรือยากขึ้นในการขยายขนาดในภายหลัง บางครั้งก็เป็นการดีที่จะเลือกกำไรระยะสั้น สะสมหนี้ทางเทคนิคเล็กน้อย เพื่อให้คุณสามารถจัดส่งได้เร็วขึ้น แต่ในบางครั้ง เรารับหนี้ทางเทคนิคเพราะเราไม่รู้ว่ามีทางเลือกอื่น

ฉันสามารถพูดแบบนี้ได้เพราะที่ฮันนี่แบดเจอร์ เราทำบางสิ่งที่ทำให้ชีวิตของเรายากขึ้นกว่าที่ควรจะเป็น หากเราเข้าใจว่าการปรับขนาดจุดสำคัญสองสามจุดจะเจ็บปวดน้อยกว่ามาก

ใช้ UUID

เมื่อคุณพูดว่า "คีย์หลัก" พวกเราส่วนใหญ่นึกถึงตัวเลขที่เพิ่มขึ้นอัตโนมัติ วิธีนี้ใช้ได้ผลดีกับระบบขนาดเล็ก แต่จะทำให้เกิดปัญหาใหญ่เมื่อคุณปรับขนาด

ในช่วงเวลาใดก็ตาม เซิร์ฟเวอร์ฐานข้อมูลเดียวเท่านั้นที่สามารถสร้างคีย์หลักได้ นั่นหมายถึง ทั้งหมด การเขียนต้องผ่านเซิร์ฟเวอร์เดียว นั่นเป็นข่าวร้ายถ้าคุณต้องการเขียนหลายพันครั้งต่อวินาที

การใช้ UUID เป็นคีย์หลักช่วยหลีกเลี่ยงปัญหานี้ หากคุณไม่คุ้นเคย UUID คือตัวระบุที่ไม่ซ้ำกันซึ่งมีลักษณะดังนี้:123e4567-e89b-12d3-a456-426655440000 .

วิกิพีเดียอธิบายไว้ดังนี้:

เมื่อสร้างตามวิธีการมาตรฐาน UUID มีไว้สำหรับวัตถุประสงค์ในทางปฏิบัติโดยเฉพาะ โดยไม่ต้องมีหน่วยงานกลางในการจดทะเบียนหรือการประสานงานระหว่างฝ่ายต่างๆ ความน่าจะเป็นที่ UUID จะถูกทำซ้ำนั้นไม่ใช่ศูนย์ แต่ใกล้เคียงกับศูนย์มากจนแทบไม่มีนัยสำคัญ

ดังนั้น ใครๆ ก็สามารถสร้าง UUID และใช้เพื่อระบุบางสิ่งด้วยความมั่นใจว่าตัวระบุไม่ซ้ำกับตัวระบุที่สร้างขึ้นแล้วเพื่อระบุอย่างอื่น และจะไม่ถูกทำซ้ำในอนาคต ข้อมูลที่ติดป้ายกำกับ UUID โดยบุคคลอิสระจึงสามารถรวมเป็นฐานข้อมูลเดียวหรือส่งผ่านช่องทางเดียวกันได้ในภายหลัง โดยไม่ต้องแก้ไขข้อขัดแย้งระหว่างตัวระบุ

เมื่อคุณใช้ UUID เป็นคีย์หลัก การเขียนทั้งหมดไม่จำเป็นต้องผ่านฐานข้อมูลเดียวอีกต่อไป แต่คุณสามารถกระจายออกไปยังเซิร์ฟเวอร์ต่างๆ ได้

นอกจากนี้ ยังให้ความยืดหยุ่นในการทำสิ่งต่างๆ เช่น สร้าง ID ของบันทึก ก่อน มันบันทึกลงในฐานข้อมูล ซึ่งอาจเป็นประโยชน์ถ้าคุณต้องการส่งเรกคอร์ดไปยังแคชหรือเซิร์ฟเวอร์การค้นหา แต่ไม่ต้องการรอให้ธุรกรรมฐานข้อมูลเสร็จสมบูรณ์

การเปิดใช้งาน UUID ตามค่าเริ่มต้นในแอป Rails นั้นง่ายมาก เพียงแก้ไขไฟล์ปรับแต่ง:

# config/application.rb
config.active_record.primary_key = :uuid

คุณสามารถใช้ UUID สำหรับแต่ละตารางที่มีการโยกย้าย Rails:

create_table :users, id: :uuid do |t|
  t.string :name
end

เป็นตัวเลือกการกำหนดค่าอย่างง่าย ซึ่งหากคุณเปิดใช้งานเมื่อคุณเริ่มการพัฒนา จะช่วยคุณกอบกู้โลกของปัญหาเมื่อคุณพยายามขยายขนาด เป็นโบนัสพิเศษ จะทำให้บอทและผู้ไม่หวังดีคาดเดา URL ส่วนตัวของคุณได้ยากขึ้น

นับและนับ

เมื่อคุณเริ่มมองหา การนับและตัวนับมีอยู่ทุกที่ โปรแกรมรับส่งเมลของคุณแสดงจำนวนอีเมลที่ยังไม่ได้อ่าน บล็อกมีส่วนท้ายเลขหน้าที่ใช้จำนวนโพสต์ทั้งหมดเพื่อคำนวณจำนวนหน้า

มีปัญหาเรื่องมาตราส่วนสองตัวกับตัวนับ:

  1. การสืบค้นฐานข้อมูล เช่น select count(*) from users จะช้าโดยเนื้อแท้ โดยจะวนซ้ำแต่ละระเบียนในชุดระเบียนเพื่อสร้างผลลัพธ์ หากคุณมีล้านระเบียนก็จะใช้เวลาสักครู่
  2. ความพยายามที่จะเร่งความเร็วตัวนับโดยใช้ "แคชตัวนับ" นั้นได้ผล แต่จะจำกัดความสามารถของคุณในการกระจายการเขียนในเซิร์ฟเวอร์ฐานข้อมูลจำนวนมาก

ทางออกที่ง่ายที่สุดคือการหลีกเลี่ยงการใช้เคาน์เตอร์ทุกที่ที่ทำได้ สิ่งนี้ง่ายกว่ามากเมื่อคุณทำการออกแบบเบื้องต้น

ตัวอย่างเช่น คุณอาจเลือกหน้าตามช่วงวันที่แทนการนับ คุณอาจเลือกที่จะไม่แสดงสถิติที่มีประโยชน์เล็กน้อยซึ่งจะสร้างนรกในภายหลัง คุณได้รับความคิด

ข้อมูลการหมดอายุและการจัดเก็บ

มีขีดจำกัดสูงสุดสำหรับจำนวนข้อมูลที่คุณสามารถเก็บไว้ในตาราง postgres เดียวตามจำนวน RAM, CPU และดิสก์ IO ที่คุณมี นั่นหมายความว่าคุณจะต้องย้ายข้อมูลเก่าออกจากตารางหลักของคุณ

ลองดูกรณีง่ายๆ คุณต้องการลบระเบียนที่เก่ากว่าหนึ่งปีในฐานข้อมูลที่มีขนาดใหญ่สองสามกิกะไบต์

หากคุณไม่เคยจัดการกับปัญหานี้มาก่อน คุณอาจถูกล่อลวงให้ทำสิ่งนี้:

MyRecords.where("created_at < ?", 1.year.ago).destroy

ปัญหาคือคิวรีนี้จะใช้เวลาหลายวันหรือหลายสัปดาห์จึงจะรันได้ ฐานข้อมูลของคุณใหญ่เกินไป

นี่เป็นปัญหาที่เจ็บปวดเป็นพิเศษ เพราะบ่อยครั้งที่คุณไม่รู้ว่าคุณมีมันจนสายเกินไป แทบไม่มีใครคิดเกี่ยวกับกลยุทธ์การล้างข้อมูลเมื่อบริษัทยังเด็กและฐานข้อมูลของพวกเขามี 1,000 ระเบียน

หากคุณสามารถวางแผนล่วงหน้าได้ มีวิธีแก้ไขที่ง่าย เพียงแค่แบ่งตารางของคุณ แทนที่จะเขียนข้อมูลทั้งหมดของคุณไปที่ my_records คุณเขียนข้อมูลของสัปดาห์นี้ไปที่ my_records_1 และข้อมูลของสัปดาห์หน้าไปที่ my_records_2 . เมื่อถึงเวลาลบของสัปดาห์ที่แล้ว เพียง drop table my_records_1 . ไม่เหมือนกับการลบ แบบสอบถามนี้จะเสร็จสิ้นอย่างรวดเร็ว

สามารถแบ่งพาร์ติชันตามฟิลด์อื่นที่ไม่ใช่วันที่ได้เช่นกัน อะไรก็ตามที่สมเหตุสมผลสำหรับกรณีการใช้งานของคุณ

มีแม้กระทั่งส่วนขยาย postgres ชื่อ pg_partman ที่ดูแลรายละเอียดทั้งหมดและให้คุณแบ่งพาร์ติชั่นฐานข้อมูลของคุณโดยไม่ต้องเปลี่ยนบรรทัดของรหัสของคุณ หรือหากคุณต้องการจัดการพาร์ติชั่นใน Ruby ก็มี Gem ที่มีประโยชน์ที่เรียกว่า partitionable

การแยกคำ

ครั้งต่อไปที่คุณพบว่าตัวเองกำลังสร้างโครงการตั้งแต่เริ่มต้น เราขอแนะนำให้คุณใช้เวลาสักครู่เพื่อคิดเกี่ยวกับการปรับขนาด อย่าหมกมุ่นอยู่กับมัน อย่าใช้เวลาหลายวันกังวลว่าจะใช้ HAML หรือ ERB หรือไม่ แต่อย่าถามตัวเองว่าไม่มีชัยชนะง่าย ๆ ที่คุณสามารถทำได้โดยการวางแผนล่วงหน้าหรือไม่