7 คะแนน โดย GN⁺ 2024-10-28 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • 1JS ซึ่งเป็น JavaScript monorepo ขนาดใหญ่ของ Microsoft มีทั้งโค้ดและปริมาณการมีส่วนร่วมจำนวนมากมาก รีโปที่โคลนล่าสุดมีขนาดถึง 178GB
  • ขนาดของรีโปใหญ่เกินไปจนผู้ใช้บางส่วนในยุโรปไม่สามารถโคลนได้

บทเรียนที่ 1

  • ตอนที่เข้ามาร่วมดูแลรีโปเมื่อหลายปีก่อน พบว่ารีโปเติบโตอย่างรวดเร็ว ตอนโคลนครั้งแรกมีขนาดเพียง 1~2GB แต่ไม่กี่เดือนต่อมาก็แตะ 4GB แล้ว
  • ใช้เครื่องมือ git-sizer เพื่อตรวจสอบ blob ขนาดใหญ่ ซึ่งมักเกิดขึ้นเมื่อมีการเช็กอินไฟล์ไบนารีโดยไม่ตั้งใจ สามารถป้องกันได้ด้วยฟีเจอร์จำกัดขนาดการเช็กอินของ Azure DevOps
  • อีกปัญหาหนึ่งเกิดจากการไม่ลบไฟล์เปลี่ยนแปลงของ Beachball ซึ่งเป็นเครื่องมือคล้าย Changesets ที่ใช้เพิ่มช่วง semver ของแพ็กเกจโดยอัตโนมัติ
  • ได้บทเรียนว่าไม่ควรเก็บไฟล์หลายพันไฟล์ไว้ในโฟลเดอร์เดียว เพื่อแก้ปัญหานี้จึงส่ง pull request ให้ Beachball รองรับการรวมหลายการเปลี่ยนแปลงไว้ในไฟล์เดียว และเขียน pipeline สำหรับล้างโฟลเดอร์การเปลี่ยนแปลงเป็นระยะ

บทเรียนที่ 2

  • สาขา versioned ซึ่งเป็น mirror ของ main โคลนได้ยากขึ้นเรื่อย ๆ ทั้งที่มีการเปลี่ยนแปลงแค่ไฟล์ CHANGELOG.md และ CHANGELOG.json แต่กลับต้องดึงข้อมูล git เพิ่มอีก 125GB
  • พบปัญหาในโค้ดการ pack แบบเก่าที่ Linus Torvalds เคยเช็กอินไว้ ซึ่งเปรียบเทียบเพียง 16 อักขระสุดท้ายของชื่อไฟล์ตอนบีบอัด ส่งผลให้ git เปรียบเทียบกับไฟล์ CHANGELOG.md ของแพ็กเกจอื่น และ push ทั้งไฟล์เดิมซ้ำ ๆ
  • ใช้คำสั่ง git repack -adf --window=250 เพื่อลดขนาดรีโป และใช้คำสั่งใหม่ git repack -adf --path-walk จนลดจาก 178GB เหลือ 5GB
  • เพิ่มการตั้งค่า git config --global pack.usePathWalk true เพื่อให้สร้าง delta ที่ถูกต้องตอน git push

สรุป

  • ถ้าใน monorepo ขนาดใหญ่มีไฟล์ชื่อยาวอย่าง CHANGELOG.md ที่ถูกอัปเดตบ่อย ควรจับตาดูฟีเจอร์ path walk
  • สามารถใช้คำสั่ง git survey เพื่อตรวจสอบไฟล์ที่ใหญ่ที่สุดตามขนาดบนดิสก์ หรือไดเรกทอรีที่ใหญ่ที่สุดตามขนาดเมื่อขยายออก เป็นต้น
  • Microsoft กำลังพัฒนาโซลูชันสำหรับการขยายขนาดรีโปซิทอรี และเปิดให้ใช้งานทั่วโลก

สรุปโดย GN⁺

  • บทความนี้แชร์ประสบการณ์การลดขนาด git ของ JavaScript monorepo ขนาดใหญ่ โดยเฉพาะการแก้ปัญหาในโค้ด pack เก่าของ git จนทำให้ขนาดรีโปลดลงอย่างมาก
  • บทความนี้ให้ข้อมูลที่มีประโยชน์สำหรับการแก้ปัญหาเกี่ยวกับ git ที่อาจเกิดขึ้นในโปรเจกต์ขนาดใหญ่ โดยเฉพาะวิธีจัดการปัญหาจากการอัปเดตไฟล์อย่าง CHANGELOG.md ซ้ำ ๆ
  • โปรเจกต์ที่มีแนวคิดคล้ายกัน ได้แก่ Buck ของ Facebook และ Bazel ของ Google ซึ่งช่วยให้จัดการโค้ดเบสขนาดใหญ่ได้อย่างมีประสิทธิภาพ

1 ความคิดเห็น

 
GN⁺ 2024-10-28
ความคิดเห็นบน Hacker News
  • คำสั่ง git-survey แบบใหม่ยังไม่ได้ถูกรวมเข้าใน git.git แต่ถูกเพิ่มเข้ามาใน git fork ของ Microsoft

  • ตอนโคลน nixpkgs ตัวเลือก --window 250 ลดขนาดลงเหลือ 1.7GB และตัวเลือก --path-walk ของ Microsoft git fork ลดลงเหลือ 1.9GB

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

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

  • Derick Stolee ได้เขียนบล็อกเกี่ยวกับโครงสร้างภายในของ git ทำให้ได้เรียนรู้อย่างมากเกี่ยวกับวิธีลดขนาด git clone ทั้งบนเครื่องโลคัลและใน CI

  • การแฮ็ก Git นั้นสนุก แต่ก็สงสัยว่ามีวิธีหลีกเลี่ยงการรวมแพ็กเกจ 2,500 ตัวไว้ใน monorepo หรือไม่

  • Microsoft ควรใช้ Azure DevOps ของตัวเอง ดูเหมือนว่าบริการ Azure จะมี native connector ให้เฉพาะ GitHub เท่านั้น

  • การมีคนที่รู้โครงสร้างภายในของ Git เป็นอย่างดีอยู่ใกล้ตัวเป็นข้อได้เปรียบที่ดีเมื่อทำงานกับโปรเจกต์ขนาดใหญ่

  • ขอบคุณสำหรับโพสต์นี้ มันช่วยซอฟต์แวร์โอเพนซอร์สได้มาก Microsoft, GitHub และ GitLab ต่างก็มอบสิ่งดี ๆ มากมาย

  • อยากเข้าใจประเด็นเรื่องการตรวจสอบ 16 อักขระสุดท้ายกับพาธเต็มให้ดีขึ้น และสงสัยว่ามันเชื่อมโยงกับ delta compression, package index และ multi-package index อย่างไร