เมื่อคุณกำลังทำงานในโครงการใหม่ คุณกำลังตัดสินใจอยู่ตลอดเวลาซึ่งจะทำให้ง่ายขึ้นหรือยากขึ้นในการขยายขนาดในภายหลัง บางครั้งก็เป็นการดีที่จะเลือกกำไรระยะสั้น สะสมหนี้ทางเทคนิคเล็กน้อย เพื่อให้คุณสามารถจัดส่งได้เร็วขึ้น แต่ในบางครั้ง เรารับหนี้ทางเทคนิคเพราะเราไม่รู้ว่ามีทางเลือกอื่น
ฉันสามารถพูดแบบนี้ได้เพราะที่ฮันนี่แบดเจอร์ เราทำบางสิ่งที่ทำให้ชีวิตของเรายากขึ้นกว่าที่ควรจะเป็น หากเราเข้าใจว่าการปรับขนาดจุดสำคัญสองสามจุดจะเจ็บปวดน้อยกว่ามาก
ใช้ 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 ส่วนตัวของคุณได้ยากขึ้น
นับและนับ
เมื่อคุณเริ่มมองหา การนับและตัวนับมีอยู่ทุกที่ โปรแกรมรับส่งเมลของคุณแสดงจำนวนอีเมลที่ยังไม่ได้อ่าน บล็อกมีส่วนท้ายเลขหน้าที่ใช้จำนวนโพสต์ทั้งหมดเพื่อคำนวณจำนวนหน้า
มีปัญหาเรื่องมาตราส่วนสองตัวกับตัวนับ:
- การสืบค้นฐานข้อมูล เช่น
select count(*) from users
จะช้าโดยเนื้อแท้ โดยจะวนซ้ำแต่ละระเบียนในชุดระเบียนเพื่อสร้างผลลัพธ์ หากคุณมีล้านระเบียนก็จะใช้เวลาสักครู่ - ความพยายามที่จะเร่งความเร็วตัวนับโดยใช้ "แคชตัวนับ" นั้นได้ผล แต่จะจำกัดความสามารถของคุณในการกระจายการเขียนในเซิร์ฟเวอร์ฐานข้อมูลจำนวนมาก
ทางออกที่ง่ายที่สุดคือการหลีกเลี่ยงการใช้เคาน์เตอร์ทุกที่ที่ทำได้ สิ่งนี้ง่ายกว่ามากเมื่อคุณทำการออกแบบเบื้องต้น
ตัวอย่างเช่น คุณอาจเลือกหน้าตามช่วงวันที่แทนการนับ คุณอาจเลือกที่จะไม่แสดงสถิติที่มีประโยชน์เล็กน้อยซึ่งจะสร้างนรกในภายหลัง คุณได้รับความคิด
ข้อมูลการหมดอายุและการจัดเก็บ
มีขีดจำกัดสูงสุดสำหรับจำนวนข้อมูลที่คุณสามารถเก็บไว้ในตาราง 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 หรือไม่ แต่อย่าถามตัวเองว่าไม่มีชัยชนะง่าย ๆ ที่คุณสามารถทำได้โดยการวางแผนล่วงหน้าหรือไม่