Git LFS लागत विस्फोट और अवास्तविक एसेट संघर्ष को हल करने के लिए Lore VCS माइग्रेशन गाइड
जब प्रोजेक्ट बड़े हो जाते हैं, तो Git LFS एक आपदा में बदल जाता है। सोर्स कोड की कुछ लाइनों को ठीक करने में तो पलक झपकते ही देर नहीं लगती, लेकिन जब गीगाबाइट आकार की आर्ट एसेट्स जुड़ने लगती हैं, तो हर कमिट के साथ घंटों तक रेतघड़ी (hourglass) घूमती रहती है। LFS की सुस्त संरचना के कारण, जो बड़ी फाइलों को पूरा कॉपी करके जमा करती है, रिपॉजिटरी की क्षमता जल्द ही टेराबाइट को पार कर जाती है और बैंडविड्थ बिल पर डरावने आंकड़े छप जाते हैं।
Epic Games द्वारा ओपन-सोर्स के रूप में जारी किया गया Lore, बाइनरी फाइलों को सबसे अधिक प्राथमिकता देता है। यह फाइलों को ब्लॉक में विभाजित करने और डुप्लिकेट को हटाने के लिए FastCDC पद्धति का उपयोग करता है, जो पैकेज के आकार और ट्रांसमिशन बैंडविड्थ को नाटकीय रूप से कम कर देता है। यहाँ Lore के व्यावहारिक माइग्रेशन और अनुकूलन के तरीके दिए गए हैं जिन्हें छोटे दल भी, जिनके पास समर्पित DevOps विशेषज्ञ नहीं हैं, तुरंत लागू कर सकते हैं।
1. Git LFS से Lore में क्रमिक माइग्रेशन
पुरानी Git रिपॉजिटरी में जमा सोर्स कोड कमिट हिस्ट्री को छोड़ने की कोई आवश्यकता नहीं है। एक हाइब्रिड रणनीति सबसे व्यावहारिक है: हल्के कोड को Git में रहने दें और केवल भारी बाइनरी एसेट्स को Lore रिपॉजिटरी में स्थानांतरित करें।
नीचे दी गई स्क्रिप्ट उन फाइलों की सूची की पहचान करती है जिन्हें Git LFS ट्रैक कर रहा था, एक समान निर्देशिका संरचना बनाती है, और कॉपी की गई फाइलों के SHA-256 हैश की तुलना करके बिना किसी डेटा हानि के उन्हें Lore में माइग्रेट करती है।
`bash
#!/usr/bin/env bash
set -euo pipefail
GIT_REPO_DIR="HOME/projects/my−game−git"LOREREPODIR="HOME/projects/my-game-lore"
LORE_SERVER_URL="lore://127.0.0.1:41337/my-project"
echo "[1/5] Lore रिपॉजिटरी इनिशियलाइज़ेशन और रिमोट बाइंडिंग..."
if [ ! -d "LOREREPODIR"];thenmkdir−p"LORE_REPO_DIR"
cd "LOREREPODIR"lorerepositorycreate"LORE_SERVER_URL"
else
cd "$LORE_REPO_DIR"
fi
echo "[2/5] Git LFS ट्रैक की गई फाइलों की सूची एकत्र करना..."
cd "GITREPODIR"LFSFILES=(git lfs ls-files -n | grep -E ".(uasset|umap|fbx|png|psd)$" || true)
if [ -z "$LFS_FILES" ]; then
echo "माइग्रेट करने के लिए कोई LFS फाइल नहीं है।"
exit 0
fi
echo "[3/5] फाइलों को कॉपी करना और सत्यापन के लिए मैनिफेस्ट बनाना..."
echo "LFSFILES"∣whileread−rfilepath;doif[−f"filepath" ]; then
dest_dir="LOREREPODIR/(dirname "filepath")"mkdir−p"dest_dir"
cp -p "filepath""LORE_REPO_DIR/filepath"sourcehash=(openssl dgst -sha256 "$filepath" | awk '{print 2}')
echo "filepath:sourcehash">>"LORE_REPO_DIR/.lore_migration_manifest"
fi
done
echo "[4/5] Git LFS को हटाना और Lore स्टेजिंग..."
cd "GITREPODIR"echo"LFS_FILES" | while read -r filepath; do
git rm --cached "$filepath"
done
sed -i.bak -E 's/filter=lfs diff=lfs merge=lfs//g' .gitattributes
cd "LOREREPODIR"echo"LFS_FILES" | while read -r filepath; do
lore stage "$filepath"
done
lore commit -m "Migration: Transfer heavy assets from Git LFS to Lore"
lore push
echo "[5/5] डेटा अखंडता सत्यापन..."
lore repository verify state
lore repository verify fragment
if [ -f ".lore_migration_manifest" ]; then
migration_errors=0
while IFS=":" read -r file sha; do
if [ -f "file"];thencurrenthash=(openssl dgst -sha256 "$file" | awk '{print 2}')
if [ "sha" != "$current_hash" ]; then
echo "दूषित फाइल का पता चला: file"migrationerrors=((migration_errors + 1))
fi
fi
done < .lore_migration_manifest
if [ $migration_errors -eq 0 ]; then
echo "माइग्रेशन पूर्ण। सभी डेटा 100% अखंडता के साथ पुनर्प्राप्त किया गया।"
rm .lore_migration_manifest
else
echo "सत्यापन विफल: $migration_errors फाइलों की अखंडता में समस्या है।"
exit 1
fi
fi
`
टर्मिनल खोलें और उपरोक्त सामग्री को migrate.sh के रूप में सहेजें। chmod +x migrate.sh कमांड के साथ निष्पादन अनुमतियाँ दें, फिर अपने स्थानीय पथ के अनुसार वेरिएबल्स को संशोधित करके चलाएँ।
इस कार्य को पूरा करने के बाद, आपके रिमोट क्लाउड LFS स्टोरेज का उपयोग तुरंत कम हो जाएगा। Epic Games के स्वयं के कार्यान्वयन मामले के अनुसार, इस ब्लॉक-स्तरीय डिडुप्लीकेशन तकनीक के माध्यम से बुनियादी ढांचे के रखरखाव की लागत को 50% तक कम किया जा सकता है।
2. CI/CD पाइपलाइन में ऑन-डिमांड हाइड्रेशन लागू करना
हर बिल्ड चक्र में सैकड़ों गीगाबाइट के गेम एसेट्स को नए सिरे से डाउनलोड करना नेटवर्क कार्ड और डिस्क I/O को बर्बाद करने वाला मुख्य कारण है। Lore बिल्ड समय को कम करने के लिए वर्चुअल फाइल सिस्टम-आधारित लेजी रिकवरी (On-demand Hydration) का समर्थन करता है।
प्रारंभिक क्लोन चरण में, यह केवल मेटाडेटा संरचना श्रृंखला और निर्देशिका ट्री को एक खोल के रूप में क्लोन करता है, और जब कंपाइलर 'कुक' (Cook) प्रक्रिया के दौरान वास्तविक एसेट को पढ़ता है, तो केवल आवश्यक बाइनरी चंक्स को गतिशील रूप से स्ट्रीम करके डिस्क पर भरता है।
`yaml
name: Game Project On-Demand Production Build
on:
push:
branches: [ release-candidate ]
env:
LORE_SERVER: "lore://10.0.1.50:41337/game-depot"
SHARED_STORE_PATH: "/var/lib/lore_shared_chunk_store"
WORKSPACE_PATH: "game_build_workspace"
jobs:
assemble-assets:
runs-on: self-hosted
steps:
- name: Persistent Shared Store तैयार करना
run: |
if [ ! -d "env.SHAREDSTOREPATH"];thensudomkdir−p"{{ env.SHARED_STORE_PATH }}"
sudo chmod 777 "env.SHAREDSTOREPATH"loreshared−storecreate"{{ env.SHARED_STORE_PATH }}"
fi
- name: Shared Cache के माध्यम से Sparse Bare Clone
run: |
lore clone \
--bare \
--use-shared-store \
--shared-store-path "${{ env.SHARED_STORE_PATH }}" \
"${{ env.LORE_SERVER }}" \
"${{ env.WORKSPACE_PATH }}"
- name: व्यू फिल्टर के माध्यम से अनावश्यक सिनेमैटिक सोर्स को बाहर करना
run: |
cd "${{ env.WORKSPACE_PATH }}"
echo "+ /SourceCode/" > .lore/view
echo "+ /Config/" >> .lore/view
echo "+ /Content/Core_Assets/" >> .lore/view
echo "- /Content/Cinematic_RAW/" >> .lore/view
- name: केवल आवश्यक चंक्स को स्थानीय डिस्क पर सिंक करना
run: |
cd "${{ env.WORKSPACE_PATH }}"
lore sync
- name: Unreal Engine Cooker चलाना
run: |
cd "${{ env.WORKSPACE_PATH }}"
./RunUAT.sh BuildCookRun \
-project="$(pwd)/GameProject.uproject" \
-platform=Win64 \
-clientconfig=Development \
-cook -stage -pak -archive
`
यदि आप बिल्ड-विशिष्ट सर्वर पर /var/lib/lore_shared_chunk_store जैसा एक स्थायी कैश स्टोरेज तैयार करते हैं, तो प्रभाव अधिकतम हो जाता है। lore clone --bare कमांड के साथ केवल इंडेक्स जानकारी को तेजी से प्राप्त करने के बाद, .lore/view फिल्टर फाइल में केवल आवश्यक पथ छोड़ें और lore sync चलाएं। इस संरचना को स्थापित करने से, बिल्ड नोड पर भेजा जाने वाला ट्रैफिक सामान्य की तुलना में 85% से अधिक कम हो जाता है। कुल बिल्ड समय औसतन 30% कम हो जाता है।
3. फाइल लॉकिंग सिस्टम के साथ एसेट संघर्ष को रोकना
Unreal Engine की .uasset या लेवल मैप फाइलें जैसे बाइनरी एसेट्स को टेक्स्ट कोड की तरह मेन ब्रांच में स्वचालित रूप से मर्ज नहीं किया जा सकता है। यदि दो कलाकार एक ही एसेट को एक साथ संशोधित करते हैं, तो बाद में पुश करने वाला कलाकार पिछले व्यक्ति के काम को ओवरराइट करके उसे हटा सकता है या टाइमलाइन उलझ सकती है।
Lore रिमोट सर्वर के अपरिवर्तनीय लेजर के आधार पर विशेष नियंत्रण (Locking) सुविधा प्रदान करता है।
`bash
किसी विशिष्ट बाइनरी कैरेक्टर मॉडल फाइल पर विशेष संपादन अधिकार का अनुरोध
lore lock acquire Content/Characters/HeroMesh.uasset --branch main
विशिष्ट फ़ोल्डर के तहत संसाधनों की लॉक स्वामित्व स्थिति की जाँच
lore lock status Content/Characters/HeroMesh.uasset
रिमोट रिपॉजिटरी में किसी विशिष्ट कार्यकर्ता द्वारा लॉक की गई सभी फाइलें खोजना
lore lock query --branch main --owner developer_artist_03
काम पूरा करने और पुश करने के बाद अधिकार वापस लौटाना
lore lock release Content/Characters/HeroMesh.uasset --branch main
`
आपको ऐसे नियम बनाने चाहिए जो कलाकारों को फाइल को छूने से पहले lore lock acquire कमांड के साथ लॉक का दावा करने के लिए मजबूर करें। संशोधन पूरा होने और कमिट/पुश के सफलतापूर्वक रिमोट पर अपडेट हो जाने के बाद, lore lock release के साथ लॉक को जारी करें ताकि यह अगले कार्यकर्ता को सौंपा जा सके।
यदि योजनाकार और कलाकार टर्मिनल कमांड के साथ सहज नहीं हैं, तो आप इन पथों को Anchorpoint जैसे डेस्कटॉप GUI टूल के साथ एकीकृत कर सकते हैं, जिससे माउस के राइट-क्लिक से ही ये लॉक कमांड निष्पादित हो सकें।
4. हार्डवेयर विनिर्देशों के अनुसार कैश ट्यूनिंग गाइड
फाइल I/O बाधाओं (bottlenecks) को रोकने के लिए कार्य वातावरण के विनिर्देशों के अनुसार क्लाइंट सेटिंग्स को समायोजित किया जाना चाहिए।
कार्यकर्ता पीसी विनिर्देशों के अनुसार स्थानीय क्लाइंट ट्यूनिंग
- उच्च प्रदर्शन प्रणाली (NVMe SSD, 32GB RAM से अधिक, मल्टी-कोर CPU): OS वर्चुअल मेमोरी मैपिंग तकनीक के माध्यम से मेमोरी मैप-आधारित प्रत्यक्ष गणना की अनुमति दें। सिंक्रोनाइज़ेशन देरी को खत्म करने के लिए अधिकतम समानांतर डाउनलोड कनेक्शन थ्रेड्स का विस्तार करें और डिस्क कैश प्रतिधारण अवधि को लंबा रखें।
- एंट्री-लेवल और कलाकार प्रणाली (SATA SSD या HDD, 16GB से कम RAM): मेमोरी समाप्त होने के कारण होने वाले इंजन क्रैश को रोकने के लिए मेमोरी मैपिंग विधि को बंद कर दें।
--direct-file-write और --direct-file-io फ्लैग चालू करें, जो सीधे डिस्क पर लिखते हैं, और कार्य के दौरान अचानक डिस्क प्री-एम्प्शन को रोकने के लिए कचरा संग्रहण (Garbage Collection) शेड्यूल अंतराल को बढ़ाएं।
संपीड़न एल्गोरिदम चयन पर प्रदर्शन विश्लेषण
Lore आर्किटेक्चर निर्णय बैठक (ADR-00016) के परिणामों के अनुसार, डिफ़ॉल्ट संपीड़न इंजन के रूप में Zstandard Level 6 विनिर्देश निर्धारित करना दक्षता के मामले में सबसे संतुलित है।
| संपीड़न एल्गोरिदम का प्रकार |
डेटा अंतिम संपीड़न दर (%) |
संपीड़न गणना गति (MiB/s) |
डीकंप्रेसन गति (MiB/s) |
पोर्टेबिलिटी और विशेषताएं |
| LZ4 Default |
47.6% |
718.7 |
2494.5 |
गति तेज है लेकिन स्टोरेज क्षमता की बर्बादी अधिक है |
| Zstd Level 1 |
34.5% |
602.0 |
1363.1 |
गति और क्षमता संरक्षण का एक अच्छा समझौता |
| Zstd Level 6 (अनुशंसित) |
28.9% |
136.5 |
1284.9 |
स्थान बचत के मुकाबले सर्वोत्तम प्रसंस्करण दक्षता बनाए रखता है |
| Oodle Kraken 3 (Fast) |
28.2% |
95.6 |
1413.1 |
Epic Games की स्वामित्व वाली Oodle लाइब्रेरी की आवश्यकता होती है |
| Oodle Kraken 6 (मौजूदा डिफ़ॉल्ट) |
23.9% |
2.2 |
1312.6 |
गीगाबाइट स्तर पर स्थानांतरण के समय गति काफी धीमी हो जाती है |
आमतौर पर उपयोग किया जाने वाला Oodle Kraken Level 6, बैकएंड सीरियलाइजेशन प्रक्रिया के दौरान संपीड़न प्रसंस्करण गति को प्रति सेकंड 2.2 MiB के स्तर तक कम कर देता था, जो कलाकारों के लिए काम छोड़ने से पहले कमिट प्रतीक्षा समय को बढ़ाने का मुख्य कारण था।
इसके विपरीत, Zstd Level 6, Oodle Kraken 6 के करीब संपीड़न दर प्रदान करते हुए स्थानीय चंक ब्लॉक संपीड़न गति को 136.5 MiB/s पर बनाए रखता है, जो लगभग 62 गुना तेज है। यदि विदेशी कार्यालयों या घर से काम करने वाले कर्मचारियों की संख्या अधिक है और बैंडविड्थ हस्तक्षेप गंभीर है, तो स्थानीय नेटवर्क के भीतर प्रॉक्सी एज कैश नोड्स के साथ 2-स्तरीय सर्वर टोपोलॉजी कॉन्फ़िगरेशन पर विचार करें।