บรรลุการปรับใช้เป็นศูนย์การหยุดทำงาน


40

ฉันกำลังพยายามทำให้การปรับใช้ไม่ทำงานเป็นศูนย์เพื่อให้ฉันสามารถปรับใช้น้อยลงในช่วงนอกเวลาทำงานและอื่น ๆ ในช่วงเวลาที่ "ช้าลง" - หรือทุกเวลาตามทฤษฎี

การตั้งค่าปัจจุบันของฉันค่อนข้างง่าย:

  • เว็บเซิร์ฟเวอร์ A (. NET App)
  • เว็บเซิร์ฟเวอร์ B (แอพ. NET)
  • เซิร์ฟเวอร์ฐานข้อมูล (SQL Server)

กระบวนการปรับใช้ปัจจุบันของฉัน:

  1. "หยุด" ไซต์บนทั้งเว็บเซิร์ฟเวอร์ A และ B
  2. อัพเกรดสกีมาฐานข้อมูลสำหรับเวอร์ชันของแอปที่กำลังปรับใช้
  3. อัปเดตเว็บเซิร์ฟเวอร์ A
  4. อัปเดตเว็บเซิร์ฟเวอร์ B
  5. นำทุกอย่างกลับมาออนไลน์

ปัญหาปัจจุบัน

สิ่งนี้นำไปสู่การหยุดทำงานเล็กน้อยในแต่ละเดือน - ประมาณ 30 นาที ฉันทำสิ่งนี้ในช่วงนอกเวลางานดังนั้นมันจึงไม่ใช่ปัญหาใหญ่ แต่เป็นสิ่งที่ฉันอยากหลีกหนี

นอกจากนี้ - ไม่มีทางที่จะ 'กลับ' จริงๆ โดยทั่วไปฉันไม่ได้สร้างสคริปต์ฐานข้อมูลย้อนกลับ - อัปเกรดสคริปต์เท่านั้น

การใช้ประโยชน์จาก Load Balancer

ฉันชอบที่จะสามารถอัปเกรดเว็บเซิร์ฟเวอร์หนึ่งครั้ง นำ Web Server A ออกจาก load balancer อัปเกรดนำกลับมาออนไลน์จากนั้นทำซ้ำสำหรับ Web Server B

ปัญหาคือฐานข้อมูล ซอฟต์แวร์ของฉันแต่ละรุ่นจะต้องดำเนินการกับฐานข้อมูลเวอร์ชันอื่น - ดังนั้นฉันจึง "ติด" อยู่

ทางออกที่เป็นไปได้

โซลูชันปัจจุบันที่ฉันกำลังพิจารณาใช้กฎต่อไปนี้

  • อย่าลบตารางฐานข้อมูล
  • อย่าลบคอลัมน์ฐานข้อมูล
  • อย่าเปลี่ยนชื่อคอลัมน์ฐานข้อมูล
  • ไม่ต้องเรียงลำดับคอลัมน์ใหม่
  • ทุกขั้นตอนการจัดเก็บจะต้องเป็นเวอร์ชัน
    • ความหมาย - 'spFindAllThings' จะกลายเป็น 'spFindAllThings_2' เมื่อมีการแก้ไข
    • จากนั้นจะกลายเป็น 'spFindAllThings_3' เมื่อแก้ไขอีกครั้ง
    • ใช้กฎเดียวกันกับมุมมอง

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

ในที่สุด - คำถามของฉัน

  • นี่เลอะเทอะหรือแฮ็ค?
  • มีใครทำแบบนี้อีกไหม?
  • คนอื่นกำลังแก้ไขปัญหานี้อย่างไร

2
แผนสำรองของคุณอยู่ที่ไหน คุณจะทดสอบว่าทุกอย่างทำงานได้อย่างไรและไม่มีการถดถอย
Deer Hunter

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

ขอบคุณโจอาคิม ... ฉันชอบที่จะพูดคุยอย่างสมบูรณ์แบบเพื่อให้แนวคิดพื้นฐานชัดเจน - แต่คุณถูกต้องเราอาจมีนโยบายที่จะเข้ากันได้ย้อนหลังโดยการเผยแพร่ N ซึ่งตอนนี้เราสามารถลบวัตถุ DB ที่ไม่จำเป็น
MattW

2
คุณจะต้องมีแผนย้อนกลับในสถานที่ วันหนึ่งคุณจะต้องการมัน
Thorbjørn Ravn Andersen

1
จากประสบการณ์ของฉันสำหรับเว็บไซต์ส่วนใหญ่ทางออกที่เป็นไปได้ของคุณแย่กว่าปัญหาที่แก้ไขได้ ความซับซ้อนที่จะเพิ่มจะมีราคาแพงกว่าที่คุณคาดการณ์ไว้ในขณะนี้ อาจเพิ่มเวลา / ความพยายามหลายครั้งในการเปลี่ยนแปลงและเพิ่มคุณสมบัติ ฉันคิดว่ามันเป็นเพียงสำหรับเว็บไซต์ที่อย่างไม่สามารถใด ๆ ที่มีการหยุดทำงานเลยทีเดียว
MGOwen

คำตอบ:


14

นี่เป็นวิธีปฏิบัติอย่างมากในการอัพเกรดซอฟต์แวร์ที่มีฐานข้อมูลสำรอง มันถูกอธิบายโดยมาร์ตินฟาวเลอร์และ Pramod Sadalage ในปี 2003 และต่อมาได้เขียนขึ้นมาในRefactoring ฐานข้อมูล: ฐานข้อมูลวิวัฒนาการการออกแบบ

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


5

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

  • หากคุณมีแพ็กเกจซอฟต์แวร์จำนวนมากที่เข้าถึงฐานข้อมูลของคุณคุณจะไม่ต้องตรวจสอบพวกเขาทั้งหมดหากการเปลี่ยนแปลงสคีมามีผลต่อพวกเขา (ในองค์กรขนาดใหญ่ที่มีหลายทีมที่เขียนโปรแกรมทั้งหมดที่เข้าถึงฐานข้อมูลเดียวกันการเปลี่ยนแปลงสคีมาอาจยากมาก)

  • หากคุณต้องการคุณสามารถตรวจสอบเวอร์ชันเก่ากว่าของโปรแกรมใดโปรแกรมหนึ่งของคุณและโปรแกรมส่วนใหญ่จะรันฐานข้อมูลที่ใหม่กว่า (ตราบใดที่คุณไม่คาดหวังว่าโปรแกรมเก่าจะจัดการคอลัมน์ที่ใหม่กว่าอย่างถูกต้อง)

  • การนำเข้า / ส่งออกข้อมูลที่เก็บถาวรลงในเวอร์ชันฐานข้อมูลปัจจุบันนั้นง่ายกว่ามาก

นี่คือกฎเพิ่มเติมสำหรับรายการของคุณ

  • แต่ละคอลัมน์ใหม่ควรเป็น NULLable หรือให้ค่าเริ่มต้นที่มีความหมาย

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

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


4

มันแตกต่างกันไปจากการปรับใช้หนึ่งไปยังอีก

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

คำถามที่คุณต้องถามตัวเองคือทุกครั้งที่รีลีสเปลี่ยนสกีมาในลักษณะที่เข้ากันไม่ได้หรือไม่

หากรีลีสน้อยมากเปลี่ยนสกีมาในลักษณะนั้นปัญหาฐานข้อมูลจะถูกปิดเสียง เพียงปรับใช้แอพพลิเคชั่นเซิร์ฟเวอร์

สองสิ่งที่ฉันได้เห็นช่วยมากที่สุดด้วยการปรับใช้เวลาน้อยที่สุดคือ:

  1. มุ่งมั่นเพื่อความเข้ากันได้แบบย้อนหลัง - อย่างน้อยภายในรีลีสเดียว คุณจะไม่ประสบความสำเร็จเสมอไป แต่ฉันสามารถเดิมพันได้ว่าคุณจะได้รับ 90% หรือมากกว่านั้นโดยเฉพาะอย่างยิ่งถ้าแต่ละรุ่นมีขนาดเล็ก
  2. มีสคริปต์ฐานข้อมูลก่อนเผยแพร่และโพสต์เผยแพร่ วิธีนี้ช่วยให้คุณสามารถจัดการการเปลี่ยนชื่อหรือการเปลี่ยนแปลงอินเทอร์เฟซโดยการสร้างวัตถุใหม่ของคุณก่อนที่จะปรับใช้รหัสแอปของคุณจากนั้นปล่อยอันเก่าหลังจากวางรหัสแอพ หากคุณเพิ่มคอลัมน์ที่ไม่เป็นโมฆะใหม่คุณสามารถเพิ่มคอลัมน์ดังกล่าวเป็นโมฆะในสคริปต์ก่อนเผยแพร่พร้อมกับทริกเกอร์ที่เติมค่าเริ่มต้น จากนั้นในโพสต์รีลีสคุณสามารถวางทริกเกอร์ได้

หวังว่าส่วนที่เหลือของ deploys ของคุณจะถูกบันทึกไว้สำหรับหน้าต่างการบำรุงรักษา

แนวคิดอื่น ๆ ที่อาจช่วยจัดการกับ deploys ไม่กี่แห่งที่ต้องหยุดทำงาน:

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

2

คุณอาจทำแบบนี้ได้เพื่อเพิ่มความพยายาม

  1. สำรองฐานข้อมูลด้วยการส่งออก
  2. นำเข้าข้อมูลสำรอง แต่เปลี่ยนชื่อใหม่เป็นรุ่นวางจำหน่ายเช่น myDb_2_1
  3. เรียกใช้งานฐานข้อมูลบน myDB_2_1
  4. "หยุด" พูลของแอปบน Web Server A หรือนำออกจาก load balancer
  5. อัปเดตเว็บเซิร์ฟเวอร์ A เรียกใช้การทดสอบการใช้งานโพสต์และย้อนกลับหากจำเป็น
  6. เซสชันตกเว็บเซิร์ฟเวอร์ B และทำให้เว็บเซิร์ฟเวอร์ A ย้อนกลับไปในลูป
  7. อัปเกรดเว็บเซิร์ฟเวอร์ B จากนั้นใส่กลับไปที่โหลดบาลานเซอร์

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


1
จะเป็นอย่างไรถ้า (เมื่อ) แอปบนเซิร์ฟเวอร์ A เขียนไปยังฐานข้อมูลของมันหลังจากที่คุณเก็บข้อมูลสำรองไว้ แต่ก่อนที่คุณจะหยุดเซิร์ฟเวอร์ A มีหน้าต่าง "ช่องโหว่" เสมอ การเขียนเหล่านี้จะสูญหายไปซึ่งอาจไม่เป็นที่ยอมรับ
sleske
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.