kyungmin-Earnest-Lim / Studing_thesis_seminar

0 stars 0 forks source link

page & block & FTL 에 관련된 개념들 #4

Open kyungmin-Earnest-Lim opened 1 year ago

kyungmin-Earnest-Lim commented 1 year ago

NAND flash memory 의 구성 특성상, 특성 셀을 단독으로 읽고 쓰는 작업은 불가능하다. 메모리는 그룹핑되어 있고, 특별한 방법으로 접근할 수 있다. 그래서 NAND flash memory의 특별한 방법을 숙지하는 것이 SSD의 데이터 구조를 최적화하고 작동 방식을 이해하는 데 있어서 꼭 필요한 부분이다.

읽기는 페이지 사이즈 단위로 실행된다.

쓰기는 페이지 사이즈 단위로 실행된다.

페이지는 덮어쓰기 ( Overwrite ) 될 수 없다.

삭제 ( Erase ) 는 블록 사이즈 단위로 실행된다.

Write Amplification

쓰기는 고정된 페이지 사이즈에서 (Aligned ) 실행되므로, 페이지 사이즈에 일치하지 않는 모든 쓰기는 필요 이상의 부가적인 쓰기 ( Write Amplification ) 를 필요로 한다. 한 바이트 쓰기는 결국 하나의 페이지를 통째로 쓰기해야 하므로, 페이지 사이즈가 16KB인 SSD에서는 16KB를 기록해야 하고 이는 상당히 비효율적이다.

그러나 이것은 SSD의 문제점은 아니다. 필요 이상의 데이터를 쓰게 되면, 필요 이상의 내부 오퍼레이션을 유발하게 된다. 페이지 크기에 맞춰지지 않은 쓰기는 먼저 해당 페이지의 데이터를 캐시로 읽어야 하며, 다시 페이지에 기록되어야 하기 때문에 즉시 페이지에 기록하는 것보다 느리게 작동한다. 이런 현상을 “Read-Modify-Write”라고 하는데, 가능하다면 이런 현상은 피하는 것이 좋다.

페이지 사이즈보다 작은 데이터 쓰기는 피하는 것이 좋다.

Align Writes

작은 데이터의 쓰기는 버퍼링

Wear Leveling

프로그램-삭제 ( P/E Cycles ) 횟수가 제한되어 있으므로 NAND flash shell은 제한된 수명을 가지게 된다. 예를 들어서 하나의 블록에만 데이터를 읽고 쓰는 가상의 SSD를 가정해보면, 이 블록은 아주 빨리 P/E Cycles 제한을 넘어서게 되어서 사용하지 못하게 될 것이다. 그러면 SSD Controller는 이 블록을 “사용 불가능”으로 마킹하게 된다. 결과적으로 SSD의 전체 사용 가능한 공간이 줄어들게 된다. 500GB 용량의 SSD 드라이브를 구매했는데 2년 후에는 250GB 공간만 남게 된다면, 극혐 …

이러한 이유로 SSD 컨트롤러의 중요한 역할 중 하나는, SSD의 전체 블록에 대해서 P/E cycle이 골고루 분산되도록 쓰기 ( Wear leveling ) 를 실행하는 것이다. 이상적으로 모든 블록이 P/E cycle 한계에 동시에 도달하여 한번에 모든 블록이 사용 불가능 상태로 만드는 것이다.

최고의 “Wear leveling”을 위해서, SSD는 쓰기가 발생하면 현명하게 블록을 선택해야 하며 때로는 특정 블록을 주위로 옮겨야 할 수도 있다. 이 과정에서 또 다른 “Write Amplification”이 발생하는 것이다. 그래서 블록 관리는 “Write Amplification”과 “Wear leveling” 의 사이에서 적절한 타협점을 찾아야 하는 것이다. 그래서 SSD 제조사들은 Garbage-collection과 같은 “Wear leveling”을 위한 기능들을 가진 제품을 출시하고 있는 것이다.

Wear Leveling

FTL ( Flash Translation Layer )

FTL의 필요성

업계에 SSD가 이렇게 쉽게 받아들여지게 만든 중요한 요소 중 하나는 SSD가 HDD와 동일한 호스트 인터페이스를 이용한다는 것이다. 물론 현재의 LBA ( Logical Block Address ) 어레이는 덮어쓰기가 가능한 HDD에서만 적합한 요소이며, SSD에는 적합하진 않지만 말이다. 이 때문에 NAND flash memory는 내부적인 특성을 숨기고 LBA 어레이를 호스트로 노출하기 위해서 부가적인 컴포넌트를 필요로 한다. 이 컴포넌트를 FTL이라고 하며, SSD 컨트롤러 내부에 위치하고 있다. FTL은 아주 중요한 역할을 담당하며, 논리적 블록 매핑 ( Logical Block Mapping ) 과 Garbage Collection 2개의 중요한 부분을 담당한다.

논리적 블록 매핑 ( Logical Block Mapping )

논리적 블록 매핑은 호스트 영역의 논리 주소 ( LBA ) 를 NAND flash memory의 물리적 주소 ( PBA ) 로 변환해주는 역할을 한다. 블록 매핑은 LBA 와 PBA로 구성된 테이블을 가지며, 이 맵핑 테이블은 빠른 액세스를 위해서 SSD의 메모리 ( RAM )에 저장되며, 전원이 꺼지거나 만약의 경우를 대비해서 SSD의 플래시 메모리에도 저장된다. SSD의 전원이 켜지면 플래시 메모리에 저장된 매핑 테이블을 읽어서 메모리 ( RAM ) 에 로딩된다.

블록 매핑을 구현하는 단순한 방법은 페이지 단위로 매핑 테이블을 구성하는 것이다. 이 방법은 아주 유연하지만, 매핑 테이블 자체가 아주 많은 메모리를 사용하게 된다는 큰 단점이 있다. 필요한 메모리가 커지면 SSD의 생산 단가가 상당이 높아지게 된다. 이를 해결하기 위한 방법으로는 페이지 단위가 아니라 블록 단위의 매핑을 이용할 수도 있다. SSD 드라이브가 256개의 페이지를 가지고 있다고 가정해보면, 블록 단위의 매핑은 페이지 단위의 매핑보다는 256배 적은 메모리를 필요로 하게 되니까 그만큼 적은 메모리가 필요하게 된다. 그러나 페이지 하나만 기록돼도 될 정도의 작은 데이터를 자주 업데이트하는 경우에는 불필요하게 블록을 통째로 기록해야 하기 때문에 불필요한 쓰기가 많이 발생하게 된다. 이것은 SSD의 Write Amplification을 증가시키기 때문에 블록 단위의 매핑은 상당히 비효율적이라고 볼 수 있다.

블록 레벨과 페이지 레벨 매핑의 trade-off는 성능과 용량의 문제라고 볼 수 있다. 그래서 일부 연구원들에 의해서 "Hybrid" 한 방법들이 제시되었는데, 이 중에서 가장 일반적인 방법이 Log Structured file system과 비슷한 형태의 Log-block 매핑이다. 유입되는 write operation은 sequential 하게 로그 블록에 기록되고, 로그 블록이 꽉 채워지면 동일한 LBN ( Logical Block Number )을 가지는 블록의 데이터와 병합하여 새로운 "free" 블록으로 기록하는 방법이다. 이 방법에서 로그 블록은 몇 개만 유지되기 때문에, 페이지 단위의 매핑은 아주 소량만 관리되면 된다.

아래의 그림은 단순화한 Hybrid log block FTL을 보여주고 있는데, 각 블록은 4개의 페이지만을 가지고 있다. 4번의 쓰기가 FTL에 의해서 처리되고 모든 페이지들이 가득 데이터를 가지게 될 것이다. 논리적인 페이지 번호 ( Logical Page Number ) 5와 9는 LBN = 1와 연결되며, LBN = 1은 물리 주소 1000번과 연결되어 있다. 초기 LBN = 1이 로그 블록 매핑 테이블에 있을 때는, 모든 물리 페이지의 offset은 null이며 1000번 로그 블록은 비어있는 상태이다.

처음 b' 가 LPN = 5에 기록되고 로그 블록 매핑 테이블 ( PBN = 1000, log block #1000)에 의해서 LBN = 1로 연결된다. 즉, 페이지 b'는 1000번 블록의 offset 0 위치에 기록된 것이다. 매핑의 메타 데이터가 업데이트되어야 하는데, 이를 위해서 물리 offset이 논리 offset 1의 위치에 null에서 0으로 저장된다.

write operation은 계속 유입되고 그에 맞게 매핑 메타 데이터도 변경된다. 1000번 로그 블록이 가득 채워지면, 3000번 논리 데이터 블록과 병합 ( merge ) 된다. 이 정보는 데이터 블록 매핑 테이블을 통해서 확인할 수 있다. 병합 작업의 결과는 "free" 상태였던 9000번 블록에 기록되는데, 이 작업이 끝나면 1000번과 3000번 블록은 삭제 ( Erase ) 되어 "free"블록이 되고 9000번 블록은 데이터 블록이 된다. 데이터 블록 매핑 테이블의 LBN = 1을 위한 메타 데이터는 처음 3000번 데이터 블록에서 9000번 데이터 블록으로 업데이트된다.

여기서 중요한 것은 4번의 쓰기가 2개의 LPN에만 집중되어 있다는 것이다. 로그 블록 매핑 방법은 병합이 진행되는 동안 "Write Amplification"을 줄이기 위해서, b' 와 d' 는 무시하고 더 최신의 b'' 와 d''만 데이터 블록에 저장한다는 것이다. 마지막으로 로그 블록이 병합되기 전에 최근 업데이트된 데이터를 읽으려고 하면, 그 데이터는 로그 블록에서 읽어야 한다. 물론 이미 병합된 데이터라면 데이터 블록을 읽어야 할 것이다. 이 때문에 읽기 요청은 로그 블록 매핑 테이블과 데이터 블록 매핑 테이블을 모두 읽어야 하는 이유인데, 이는 그림에서 보여준다.

image

로그 블록 FTL은 더 나은 최적화를 할 수 있도록 해주는 데, 그 중에서도 중요한 것은 "switch-merge" ( "swap-merge" 라고도 한다. ) 이다. 논리 블록의 주소가 한번에 기록된다고 가정해보자.이는 그 논리 주소의 새로운 데이터들이 동일한 로그 블록에 기록된다는 것을 의미한다. 이 로그 블록은 전체 논리 블록의 데이터를 모두 가지기 때문에, 이 로그 블록을 별도로 병합하여 새로운 블록으로 옮기는 과정은 불필요한 작업이 될 것이다. ( 병합 전/후의 블록이 동일한 데이터를 가지게 될 것이므로) 이런 경우에는 단순히 로그 블록 매핑을 거치지 않고 데이터 블록 매핑을 바로 변경할 수 있으면 ( 데이터 블록 매핑의 메타 데이터만 변경하면 되므로 ) 더 빠를 것이다. 이렇게 데이터 블록 매핑 테이블에서 데이터 블록과 로그 블록을 바꾸는 ( switch ) 것을 "switch-merge" 라고 한다.

로그 블록 매핑 스키마 ( scheme ) 는 많은 논문의 주제가 되곤 했으며, FAST ( Fully Associative Sector Translation ), 슈퍼 블록 매핑 그리고 flexible Group Mapping 등과 같은 발전을 이루어 왔다.