File Manager
The File Manager is responsible for managing file metadata, chunk mappings, and replication status in the GFS system. It provides a persistent layer for file system metadata and handles file operations coordination.
Core Components
File Metadata Structure
@dataclassclass FileMetadata: file_path: str total_size: int chunk_ids: List[str] chunk_locations: Dict[str, List[str]] # chunk_id -> list of chunk server addresses chunk_offsets: Dict[str, int] # chunk_id -> offset within chunk last_chunk_id: str # ID of the last chunk for appends last_chunk_offset: int # Current offset in the last chunk pending_replication: Dict[str, int] = None # chunk_id -> required additional replicasKey attributes:
- File path and size tracking
- Chunk mapping and locations
- Offset management for appends
- Replication status tracking
File Manager Implementation
class FileManager: def __init__(self, metadata_dir: str, config: Dict): self.metadata_dir = metadata_dir self.metadata_lock = threading.Lock() self.files: Dict[str, FileMetadata] = {}Core Functionality
Metadata Persistence
- Loading Metadata
def _load_metadata(self): """Load metadata from disk.""" metadata_file = os.path.join(self.metadata_dir, 'metadata.json') if os.path.exists(metadata_file): with open(metadata_file, 'r') as f: data = json.load(f) self.files = { path: FileMetadata(**metadata) for path, metadata in data.items() }- Saving Metadata
def _save_metadata(self): """Save metadata to disk.""" metadata_file = os.path.join(self.metadata_dir, 'metadata.json') with open(metadata_file, 'w') as f: json.dump({ path: asdict(metadata) for path, metadata in self.files.items() }, f, indent=2)File Operations
- Adding Files
def add_file(self, file_path: str, total_size: int, chunk_ids: List[str]): """Add a new file to the metadata.""" with self.metadata_lock: self.files[file_path] = FileMetadata( file_path=file_path, total_size=total_size, chunk_ids=chunk_ids, chunk_locations={}, chunk_offsets={chunk_id: 0 for chunk_id in chunk_ids}, last_chunk_id=chunk_ids[-1] if chunk_ids else None, last_chunk_offset=total_size % self.config['master']['chunk_size'] )- Updating Metadata
def update_file_metadata(self, file_path: str, chunk_id: str, locations: List[str], size: int): """Update file metadata with new chunk information.""" with self.metadata_lock: if file_path not in self.files: self.add_file(file_path, size, [chunk_id]) else: metadata = self.files[file_path] if chunk_id not in metadata.chunk_ids: metadata.chunk_ids.append(chunk_id) metadata.chunk_locations[chunk_id] = locations metadata.total_size += sizeChunk Management
- Location Tracking
def update_chunk_locations(self, file_path: str, chunk_id: str, locations: List[str]): """Update the locations of a chunk.""" with self.metadata_lock: if file_path in self.files: self.files[file_path].chunk_locations[chunk_id] = locations- Offset Management
def update_chunk_offset(self, file_path: str, chunk_id: str, offset: int): """Update the offset of a chunk.""" with self.metadata_lock: if file_path in self.files: metadata = self.files[file_path] metadata.chunk_offsets[chunk_id] = offset if chunk_id == metadata.last_chunk_id: metadata.last_chunk_offset = offsetReplication Management
- Pending Replications
def get_pending_replications(self, file_path: str) -> Dict[str, int]: """Get chunks that need additional replicas.""" metadata = self.get_file_metadata(file_path) if metadata and metadata.pending_replication: return metadata.pending_replication return {}- Replication Status
def update_replication_status(self, file_path: str, chunk_id: str, needed_replicas: int): """Update the replication status of a chunk.""" with self.metadata_lock: metadata = self.files.get(file_path) if metadata: metadata.pending_replication[chunk_id] = needed_replicasError Handling
- Metadata Operations
try: self._save_metadata()except IOError as e: self.logger.error(f"Failed to save metadata: {e}")- File Operations
if file_path not in self.files: self.logger.warning(f"Attempted to update non-existent file: {file_path}")Best Practices
-
Metadata Management
- Regular backups
- Atomic updates
- Lock-based synchronization
-
Performance Optimization
- In-memory caching
- Batch updates
- Periodic persistence
-
Data Integrity
- Validate metadata
- Check file consistency
- Handle corruption