439 lines
No EOL
12 KiB
Markdown
439 lines
No EOL
12 KiB
Markdown
# S3 Migration Guide
|
|
|
|
Complete guide for migrating existing Brainy data to the new optimized system, with special considerations for shared S3 buckets.
|
|
|
|
## 🎯 Overview
|
|
|
|
When upgrading to Brainy v0.36.0+ with the new optimization system, you can migrate existing data without starting from scratch. This guide covers migration strategies, shared bucket considerations, and best practices.
|
|
|
|
## ✅ Key Points
|
|
|
|
- **No data loss** - All existing data is preserved and enhanced
|
|
- **Automatic optimization** - System applies all optimizations during migration
|
|
- **Backward compatible** - Can read data from any previous version
|
|
- **Zero-downtime options** - Multiple strategies for production systems
|
|
|
|
## 🔄 Migration Methods
|
|
|
|
### Method 1: Backup & Restore (Recommended)
|
|
|
|
The safest and most reliable migration approach.
|
|
|
|
```typescript
|
|
// Step 1: Export from existing Brainy instance
|
|
const oldBrainy = new BrainyData({ /* existing config */ })
|
|
const backupData = await oldBrainy.backup()
|
|
|
|
// Step 2: Save backup (optional)
|
|
import fs from 'fs'
|
|
fs.writeFileSync('brainy-backup.json', JSON.stringify(backupData))
|
|
|
|
// Step 3: Create new optimized instance
|
|
import { createAutoBrainy } from '@soulcraft/brainy'
|
|
const newBrainy = createAutoBrainy({
|
|
bucketName: 'my-optimized-vectors'
|
|
})
|
|
|
|
// Step 4: Restore data with optimizations
|
|
const result = await newBrainy.restore(backupData, {
|
|
clearExisting: true
|
|
})
|
|
|
|
console.log(`Migrated ${result.nounsRestored} vectors successfully`)
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Clean migration with no conflicts
|
|
- ✅ Can test before switching production
|
|
- ✅ Rollback option available
|
|
- ✅ Works with any storage backend
|
|
|
|
### Method 2: In-Place Upgrade
|
|
|
|
Upgrade existing data without moving it.
|
|
|
|
```typescript
|
|
import { createAutoBrainy } from '@soulcraft/brainy'
|
|
|
|
// Point to existing data location
|
|
const brainy = createAutoBrainy({
|
|
bucketName: 'existing-bucket' // Same as old instance
|
|
})
|
|
|
|
// System automatically:
|
|
// 1. Detects existing data format
|
|
// 2. Rebuilds optimized HNSW index
|
|
// 3. Applies semantic partitioning
|
|
// 4. Enables all optimizations
|
|
|
|
// First operation triggers optimization
|
|
const results = await brainy.search([0.1, 0.2, 0.3], 10)
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ No data movement required
|
|
- ✅ Immediate optimization benefits
|
|
- ✅ Minimal downtime
|
|
|
|
**Limitations:**
|
|
- ⚠️ Requires exclusive access during initial optimization
|
|
- ⚠️ No rollback without backup
|
|
|
|
### Method 3: Sparse Data Import
|
|
|
|
For migrating raw data without vectors.
|
|
|
|
```typescript
|
|
// Import data without vectors (they'll be regenerated)
|
|
const sparseData = {
|
|
nouns: [
|
|
{
|
|
id: 'doc-1',
|
|
metadata: {
|
|
text: 'Machine learning algorithms',
|
|
noun: 'Thing',
|
|
category: 'technology'
|
|
}
|
|
// No vector field - will be auto-generated
|
|
}
|
|
],
|
|
verbs: [],
|
|
version: '1.0.0'
|
|
}
|
|
|
|
const brainy = createAutoBrainy()
|
|
const result = await brainy.importSparseData(sparseData)
|
|
```
|
|
|
|
**Benefits:**
|
|
- ✅ Smaller backup files
|
|
- ✅ Ensures vectors use latest embedding model
|
|
- ✅ Good for data format migrations
|
|
|
|
## 🗄️ Shared S3 Bucket Considerations
|
|
|
|
When multiple Brainy instances share the same S3 bucket, special care is needed during migration.
|
|
|
|
### Understanding Shared Bucket Architecture
|
|
|
|
```
|
|
shared-bucket/
|
|
├── nouns/ # Vector data
|
|
├── verbs/ # Relationships
|
|
├── metadata/ # Additional metadata
|
|
├── index/ # HNSW index data
|
|
├── statistics/ # System statistics
|
|
├── change-log/ # Change tracking with instance IDs
|
|
└── locks/ # Distributed locks for coordination
|
|
```
|
|
|
|
### Built-in Safety Features
|
|
|
|
1. **Distributed Locking**
|
|
- Prevents concurrent modifications
|
|
- 30-second TTL with automatic cleanup
|
|
- Coordinates between multiple instances
|
|
|
|
2. **Instance Tracking**
|
|
```typescript
|
|
// Each modification includes instance identification
|
|
{
|
|
timestamp: 1234567890,
|
|
operation: 'add',
|
|
instanceId: 'process-123' // or 'browser'
|
|
}
|
|
```
|
|
|
|
3. **Conflict Detection**
|
|
- Change logs track all modifications
|
|
- Enables conflict resolution
|
|
- Maintains data consistency
|
|
|
|
### ⚠️ Potential Issues with Shared Buckets
|
|
|
|
| Issue | Impact | Solution |
|
|
|-------|--------|----------|
|
|
| **Namespace Collision** | Different apps overwrite data | Use unique prefixes |
|
|
| **Index Corruption** | Multiple rebuilds conflict | Coordinate migrations |
|
|
| **Lock Contention** | Performance degradation | Stagger instance updates |
|
|
| **Statistics Conflicts** | Incorrect metrics | Use distributed locking |
|
|
|
|
## 📋 Migration Strategies for Shared Buckets
|
|
|
|
### Strategy 1: Dedicated Namespace (Recommended)
|
|
|
|
Create isolation using bucket subfolders.
|
|
|
|
```typescript
|
|
// Each application uses its own namespace
|
|
const brainy = createAutoBrainy({
|
|
bucketName: 'shared-bucket/app-name/v2',
|
|
region: 'us-east-1'
|
|
})
|
|
|
|
// Data structure becomes:
|
|
// shared-bucket/
|
|
// app-name/
|
|
// v2/
|
|
// nouns/
|
|
// verbs/
|
|
// ...
|
|
```
|
|
|
|
### Strategy 2: Blue-Green Migration
|
|
|
|
Run old and new systems in parallel.
|
|
|
|
```typescript
|
|
// Phase 1: Create new optimized instance in separate bucket
|
|
const newBrainy = createAutoBrainy({
|
|
bucketName: 'optimized-vectors',
|
|
region: 'us-east-1'
|
|
})
|
|
|
|
// Phase 2: Sync data from old to new
|
|
const backupData = await oldBrainy.backup()
|
|
await newBrainy.restore(backupData)
|
|
|
|
// Phase 3: Run both systems in parallel
|
|
// - Old system: Handles writes
|
|
// - New system: Handles reads (testing)
|
|
|
|
// Phase 4: Switch traffic to new system
|
|
// Phase 5: Decommission old system
|
|
```
|
|
|
|
### Strategy 3: Rolling Migration
|
|
|
|
Gradually migrate instances with zero downtime.
|
|
|
|
```typescript
|
|
// Step 1: Set read-only mode on secondary instances
|
|
const readOnlyInstances = instances.map(instance => {
|
|
instance.setReadOnly(true)
|
|
return instance
|
|
})
|
|
|
|
// Step 2: Migrate primary write instance
|
|
const primaryBrainy = createAutoBrainy({
|
|
bucketName: 'shared-bucket',
|
|
learningEnabled: true
|
|
})
|
|
|
|
// Step 3: Gradually migrate read instances
|
|
for (const instance of readOnlyInstances) {
|
|
const optimized = createAutoBrainy({
|
|
bucketName: 'shared-bucket',
|
|
readOnlyMode: true
|
|
})
|
|
// Replace old instance with optimized
|
|
}
|
|
```
|
|
|
|
### Strategy 4: Coordinated In-Place Migration
|
|
|
|
Migrate with careful coordination.
|
|
|
|
```typescript
|
|
async function coordinatedMigration() {
|
|
// Step 1: Announce maintenance window
|
|
console.log('Starting coordinated migration...')
|
|
|
|
// Step 2: Stop all write operations
|
|
const instances = await getAllInstances()
|
|
instances.forEach(i => i.setReadOnly(true))
|
|
|
|
// Step 3: Wait for in-flight operations
|
|
await new Promise(resolve => setTimeout(resolve, 5000))
|
|
|
|
// Step 4: Perform migration
|
|
const brainy = createAutoBrainy({
|
|
bucketName: 'shared-bucket',
|
|
autoConfigureEnvironment: true,
|
|
learningEnabled: true
|
|
})
|
|
|
|
// Step 5: Verify migration
|
|
const stats = await brainy.getStatistics()
|
|
console.log(`Migrated ${stats.nounCount} vectors`)
|
|
|
|
// Step 6: Resume operations
|
|
instances.forEach(i => i.setReadOnly(false))
|
|
}
|
|
```
|
|
|
|
## 🛡️ Best Practices
|
|
|
|
### 1. Pre-Migration Checklist
|
|
|
|
- [ ] **Backup existing data** using `backup()` method
|
|
- [ ] **Test migration** with subset of data
|
|
- [ ] **Monitor S3 costs** during migration (increased API calls)
|
|
- [ ] **Plan maintenance window** if using shared bucket
|
|
- [ ] **Verify credentials** for S3 access
|
|
- [ ] **Check available storage** for temporary duplication
|
|
|
|
### 2. Performance Monitoring
|
|
|
|
```typescript
|
|
// Monitor migration progress and performance
|
|
const brainy = createAutoBrainy({ /* config */ })
|
|
|
|
// Check optimization status
|
|
setInterval(async () => {
|
|
const metrics = brainy.getPerformanceMetrics()
|
|
console.log({
|
|
vectorsProcessed: metrics.indexSize,
|
|
searchLatency: metrics.averageSearchTime,
|
|
cacheHitRate: metrics.cacheHitRate,
|
|
memoryUsage: metrics.memoryUsage
|
|
})
|
|
}, 10000)
|
|
```
|
|
|
|
### 3. Handling Large Datasets
|
|
|
|
For datasets over 1M vectors:
|
|
|
|
```typescript
|
|
// Use scenario-based configuration
|
|
const brainy = await createQuickBrainy('enterprise', {
|
|
bucketName: 'large-vectors',
|
|
region: 'us-east-1'
|
|
})
|
|
|
|
// Or manual configuration for fine control
|
|
const brainy = createAutoBrainy({
|
|
expectedDatasetSize: 5000000,
|
|
maxMemoryUsage: 16 * 1024 * 1024 * 1024, // 16GB
|
|
targetSearchLatency: 500,
|
|
s3Config: {
|
|
bucketName: 'large-vectors',
|
|
region: 'us-east-1'
|
|
}
|
|
})
|
|
```
|
|
|
|
### 4. Rollback Plan
|
|
|
|
Always maintain ability to rollback:
|
|
|
|
```typescript
|
|
// Before migration
|
|
const backupData = await oldBrainy.backup()
|
|
fs.writeFileSync('backup-{timestamp}.json', JSON.stringify(backupData))
|
|
|
|
// If rollback needed
|
|
const oldBrainy = new BrainyData({ /* old config */ })
|
|
await oldBrainy.restore(backupData, { clearExisting: true })
|
|
```
|
|
|
|
## 📊 Expected Performance Improvements
|
|
|
|
After migration with optimizations:
|
|
|
|
| Dataset Size | Before | After | Improvement |
|
|
|-------------|--------|-------|-------------|
|
|
| **10k vectors** | ~200ms | ~50ms | **4x faster** |
|
|
| **100k vectors** | ~2s | ~200ms | **10x faster** |
|
|
| **1M vectors** | ~10s | ~500ms | **20x faster** |
|
|
| **Memory Usage** | 100% | 25-30% | **70-75% reduction** |
|
|
| **S3 API Calls** | 100% | 10-50% | **50-90% reduction** |
|
|
|
|
## 🔍 Troubleshooting
|
|
|
|
### Common Issues and Solutions
|
|
|
|
| Problem | Cause | Solution |
|
|
|---------|-------|----------|
|
|
| **"Lock timeout" errors** | Multiple instances competing | Stagger migration timing |
|
|
| **High memory usage** | Large dataset loading | Enable compression, reduce cache |
|
|
| **Slow initial searches** | Index rebuilding | Wait for optimization to complete |
|
|
| **S3 rate limiting** | Too many concurrent operations | Reduce batch sizes |
|
|
| **Missing vectors** | Sparse data import | Ensure embedding function available |
|
|
|
|
### Debug Logging
|
|
|
|
Enable detailed logging during migration:
|
|
|
|
```typescript
|
|
// Set environment variable
|
|
process.env.BRAINY_DEBUG = 'true'
|
|
|
|
const brainy = createAutoBrainy({
|
|
bucketName: 'my-bucket',
|
|
// Logs will show optimization decisions
|
|
})
|
|
```
|
|
|
|
### Verification Steps
|
|
|
|
After migration, verify success:
|
|
|
|
```typescript
|
|
async function verifyMigration(brainy) {
|
|
// 1. Check data integrity
|
|
const stats = await brainy.getStatistics()
|
|
console.log(`Vectors: ${stats.nounCount}`)
|
|
console.log(`Relationships: ${stats.verbCount}`)
|
|
|
|
// 2. Test search performance
|
|
const testVector = [0.1, 0.2, 0.3]
|
|
const start = Date.now()
|
|
const results = await brainy.search(testVector, 10)
|
|
console.log(`Search time: ${Date.now() - start}ms`)
|
|
|
|
// 3. Verify optimizations active
|
|
const metrics = brainy.getPerformanceMetrics()
|
|
console.log(`Cache hit rate: ${metrics.cacheHitRate}`)
|
|
console.log(`Compression ratio: ${metrics.compressionRatio}`)
|
|
|
|
return stats.nounCount > 0 && results.length > 0
|
|
}
|
|
```
|
|
|
|
## 🎯 Quick Decision Guide
|
|
|
|
Choose your migration approach:
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[Start Migration] --> B{Shared S3 Bucket?}
|
|
B -->|Yes| C{Can Stop All Instances?}
|
|
B -->|No| D[Use Backup & Restore]
|
|
C -->|Yes| E[In-Place Migration]
|
|
C -->|No| F{Need Zero Downtime?}
|
|
F -->|Yes| G[Blue-Green Migration]
|
|
F -->|No| H[Rolling Migration]
|
|
D --> I[Complete]
|
|
E --> I
|
|
G --> I
|
|
H --> I
|
|
```
|
|
|
|
## 💡 Tips for Success
|
|
|
|
1. **Start Small**: Test with 1% of data first
|
|
2. **Monitor Metrics**: Use `getPerformanceMetrics()` frequently
|
|
3. **Use Read-Only Mode**: For instances that only search
|
|
4. **Plan S3 Costs**: Migration causes temporary spike in API calls
|
|
5. **Keep Backups**: Always maintain rollback capability
|
|
6. **Leverage Auto-Config**: Let system optimize automatically
|
|
7. **Document Process**: Record settings for reproducibility
|
|
|
|
## 🔗 Related Documentation
|
|
|
|
- [Large-Scale Optimizations](./large-scale-optimizations.md) - Understanding the optimization system
|
|
- [Auto-Configuration Guide](./auto-configuration.md) - How automatic optimization works
|
|
- [Storage Optimization](./storage-optimization.md) - S3 and storage best practices
|
|
- [Production Migration Guide](../guides/production-migration-guide.md) - General production deployment
|
|
|
|
## 🆘 Getting Help
|
|
|
|
- **GitHub Issues**: Report migration problems
|
|
- **Discussions**: Share migration experiences
|
|
- **Documentation**: Check other guides for specific features
|
|
|
|
---
|
|
|
|
**Ready to migrate?** Start with a backup, test thoroughly, and enjoy 10-20x performance improvements! 🚀 |