10MPage.com: 2025년 인터넷 아카이브 – 천만 개의 이미지에 대한 타일 배치 최적화
저는 2025년 인터넷 상태를 포착하는 것을 목표로 하는 야심찬 프로젝트인 10MPage.com을 구축하고 있습니다. 각 사용자는 이 대규모 온라인 아카이브에 64x64 픽셀 이미지를 제공할 수 있습니다. 이미지 추가에는 다단계 프로세스가 포함됩니다. 업로드하면 대기 중인 타일이 생성되며 그리드에 배치하기 전에 승인이 필요합니다.
그리드 자체는 각 행이 X 및 Y 좌표가 있는 1x1 타일을 나타내는 데이터베이스 테이블(tiles
이라고 함)입니다. 보류 중인 더 큰 타일은 여러 개의 1x1 타일로 나뉩니다. 과제: 1,000만 개의 항목을 수용할 수 있도록 이러한 타일을 확장 그리드에 효율적으로 배치하는 것입니다.
빈 공간을 검색하는 간단한 루프인 나의 초기 접근 방식은 비참한 것으로 판명되었습니다. 수천 개의 타일을 추가하는 데 몇 초가 걸렸습니다. 1,000만 개로 추정하면 완료 시간이 몇 년이 걸릴 것으로 예상됩니다!
초기 접근 방식(비효율적):
첫 번째 시도에서는 사용 가능한 공간을 찾기 위해 전체 그리드를 반복했습니다. 그리드는 대략 정사각형 모양을 유지하도록 동적으로 확장되었습니다. 핵심 find()
방법은 다음과 같습니다.
<code class="language-php">public function find(int $blockWidth, int $blockHeight): array { // ... (code to determine grid dimensions) ... // Look for a fitting spot for ($y = 0; $y < $newHeight; $y++) { for ($x = 0; $x < $newWidth; $x++) { if ($this->canPlaceBlock($x, $y, $blockWidth, $blockHeight)) { return ['x' => $x, 'y' => $y]; } } } return [0, 0]; } // ... (canPlaceBlock method) ...</code>
항상 (0,0)부터 검색을 시작했기 때문에 속도가 느렸습니다. 최적화에는 단일 데이터베이스 쿼리를 사용하는 보다 효율적인 canPlaceBlock
방법이 포함되었습니다.
<code class="language-php">public function canPlaceBlock(int $startX, int $startY, int $blockWidth, int $blockHeight): bool { $ys = range($startY, $startY + $blockHeight - 1); $xs = range($startX, $startX + $blockWidth - 1); return !Tile::whereIn('x', $xs)->whereIn('y', $ys)->exists(); }</code>
최소 기존 X 및 Y 좌표에서 검색을 시작하여 find()
을 최적화하려는 추가 시도도 성능을 크게 향상시키지 못했습니다. 더 빠른 검사를 위해 전체 그리드를 메모리에 로드하는 것은 메모리를 너무 많이 사용하는 것으로 나타났습니다.
해결책: 배치 블록
확장성의 핵심은 블록 기반 접근 방식을 채택하는 것이었습니다. 새로운 placement_blocks
데이터베이스 테이블로 관리되는 100x100 타일 단위인 "배치 블록"을 소개했습니다. 각 블록은 최소/최대 X 및 Y 좌표와 "전체" 부울 플래그를 추적합니다.
이 접근 방식은 두 가지 주요 이점을 제공합니다.
배치 블록 찾기 및 사용:
재귀 함수는 사용 가능한 배치 블록을 효율적으로 찾거나 필요에 따라 새 블록을 생성합니다.
<code class="language-php">public function find(array $excludeBlocks = []): PlacementBlock { // ... (code to find or create placement blocks) ... }</code>
place()
메서드는 이 기능을 활용하며 전역 잠금을 사용하여 블록 선택을 조정하고 블록별 잠금을 사용하여 경쟁 조건을 방지합니다.
<code class="language-php">public function place(PendingTile $pendingTile): void { // ... (code to acquire locks and place tiles) ... }</code>
타일은 최적화된 canPlaceBlock
방법을 사용하여 배치 블록 내에 추가됩니다. 현재 단일 배치 블록보다 큰 타일은 지원되지 않습니다.
동시성 및 확장성:
Laravel 작업과 Horizon은 동시 타일 배치를 관리합니다. 작업자 수는 사용 가능한 배치 블록 수와 일치하거나 작아야 합니다. 이를 통해 쉽게 수평 확장이 가능합니다.
이러한 개선된 접근 방식은 타일 배치 프로세스의 속도와 확장성을 극적으로 향상시켜 10MPage.com의 야심 찬 목표를 달성할 수 있게 해줍니다. 오늘 프로젝트에 참여하고 기여도를 추가하세요!
위 내용은 인터넷 기록을 위해 PHP로 백만 개의 이미지 그리드 채우기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!