- 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 ความคิดเห็น
ความคิดเห็นบน Hacker News
คำสั่ง
git-surveyแบบใหม่ยังไม่ได้ถูกรวมเข้าในgit.gitแต่ถูกเพิ่มเข้ามาใน git fork ของ Microsoftตอนโคลน
nixpkgsตัวเลือก--window 250ลดขนาดลงเหลือ 1.7GB และตัวเลือก--path-walkของ Microsoft git fork ลดลงเหลือ 1.9GBผู้ใช้บางส่วนในยุโรปบอกว่าไม่สามารถโคลนรีโพขนาดใหญ่ได้ ดูเหมือนว่าจะโคลนไม่ได้จนกว่าจะมีการเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์
ปัญหาเกิดจากความผิดพลาดที่ชื่อไฟล์ไม่ได้รวมพาธเต็มไว้ โดยกำลังตรวจสอบแค่ 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 อย่างไร