Home 용어정리 7. RAID
Post
Cancel

용어정리 7. RAID

RAID라는 말은 사실 HDFS를 공부할 때 한번쯤은 보게되는 용어입니다.

대표적으로 ‘HDFS의 데이터노드에는 RAID를 쓰지않는다’라는 짧은 문구를 보게되죠.

근데 사실 그냥 별 신경안쓰고 넘어가도 HDFS라는 것을 이해하는데 큰 영향은 없었습니다. 저는 안쓰면 말지 뭐 어쩌라고 하는 느낌으로 넘어갔었거든요.

다만 문제는 하둡 3.0부터입니다. 하둡 3.0에서는 HDFS에 EC(Erasure Coding)라는 것을 적용하기 시작했는데, 이를 공부하다보면 RAID가 계속 등장합니다.

뭔가 혼용되는 느낌이 있다고해야되나 그런게 되게 강하게 듭니다. 근데 또 많은 레퍼런스들에서는 엄연히 두개는 구분 된다고 하니 상당히 머리가 복잡해진 상태입니다.

당연히 그 사람들이 잘못쓰고 있을리는 없고 아무리봐도 제가 RAID와 EC를 명확하게 구분하지 못해서 발생하는 혼란이겠거니 해서 정리가 필요하다는 생각에 이 포스팅을 시작합니다.

RAID는 무엇인가?

데이터 보호를 위해서 떠올릴 수 있는 가장 보편적인 방법은 사실 외부 스토리지에 데이터를 백업용으로 저장해두는 것입니다. 일상생활로 예를 들면 중요한 데이터들은 복제본을 만들어 USB에 따로 저장해두는 것처럼 말이죠.

그런데 시스템 범위 내에서 데이터 보호가 이루어지도록 하는 방법도 있습니다. 시스템 자체적으로 데이터들을 복제하여 저장하는 경우들을 의미하죠. 그리고 이 RAID가 바로 시스템의 범위안에서 데이터를 보호하는 방법 중 한가지입니다.

RAID1

RAID(Redundant Array Of Inexpensive Disk)는 1984 UC 버클리의 3명의 과학자로부터 시작해 1988년에 발표된 이후부터 스토리지 시스템에서 데이터의 보호를 위한 1옵션으로 사용된 굉장히 오래된 기술입니다.

RAID는 이름에서 보다시피 여러개의 값싼 하드디스크를 묶어서 하나의 고성능/고용량 하드디스크처럼 구성해서 사용합니다. 당시에는 하드디스크의 용량도 제한적이였고 아무나 사용할 수 없을 정도로 가격이 비쌌기 때문에 보다 저렴하고 용량이 작고 성능이 낮은 하드디스크들을 묶어 성능이 좋은 하나의 하드디스크보다 좋게 할 수 있다는 이들의 주장은 혁신적이였습니다.

그러나 재밌는건 하드디스크의 발전속도가 이들의 예상 밖이였다는 겁니다. 그들이 RAID를 계속 연구하는 동안 하드디스크의 성능이 올라가면서 용량대비 가격이 저렴해지기 시작한 것이죠. 그래서 초기 가격적인 면에서 부각되었던 RAID는 데이터의 안정성과 에러보정 그리고 하드디스크의 장애에 의한 데이터의 손실을 막기위한 측면이 강조되기 시작했고 RAID의 의미가 Inexpensive에서 Indepensive로 바뀌게 되었습니다.

여기까지 보면 우리가 아는 일반적인 분산 파일 시스템에서 fault-tolerance를 보장하는 방식과 거시적인 관점에서는 큰 차이가 없습니다. 다만 RAID는 구체적으로 어떻게 데이터를 나누고 저장하는지와 추가적으로 어떤 기능들을 가지고 있느냐에 따라 데이터의 안정성, 에러보정, 장애에 의한 데이터 손실 등에 대한 다양한 양상을 보입니다.

다시 말하면 RAID의 종류에 따라 다양한 모습으로 구현이 된다는 거죠. 따라서 RAID를 온전히 이해하기 위해선 종류별로 어떠한 특징을 가지는지를 보는것이 훨씬 더 효과적입니다.

RAID의 종류(RAID Level)

RAID의 종류에 대한 이야기는 같은 용량의 디스크로 구성한다는 가정에서 시작됩니다. 물론 현실에서는 여러 변수가 있고 이에 대한 이야기들도 많지만 처음 RAID를 공부하는 입장에서 최대한 단순 명료하게 정리하기 위해 앞선 가정을 채택하여 진행하겠습니다.

RAID의 종류는 성능(읽기 및 쓰기 속도)과 Fault tolerance 그리고 저장소 용량에 따라 결정됩니다. 각 종류별로 성능을 더 중시하는지 아니면 Fault tolerance를 더 중시하는지 아니면 저장소 용량을 더 중시하는지가 결정되기 때문입니다.

그런데 RAID는 종류가 꽤 많아서 모든 것을 다루기에는 좀 무리가 있습니다. 또한 거의 사용되지 않는 것들은 배제할 필요가 있다고 생각이 들어서 자주 사용되는 5종류를 위주로 살펴보도록 하겠습니다.

RAID 0

RAID2

RAID 0는 파일을 스토리지용 세그먼트(Segment)로 분리 및 분산 저장하는 프로세스인 데이터 스트라이핑(Striping)을 사용합니다. 여기서 세그먼트는 분산 파일 시스템의 청크, 블록 등에 상응하는 개념입니다. 스트라이핑을 통해 만들어진 데이터 세그먼트는 스트라이프 유닛이라고 불리며 RAID에 구성된 모든 디스크에 분할되어 저장됩니다.

(이 포스팅에서는 데이터 세그먼트 혹은 스트라이프 유닛을 이해의 편의성을 위해 블록으로 지칭하여 진행합니다.)

이 스트라이핑이라는 개념안에는 병렬처리라는 개념도 포함되어 있습니다. 파일을 분할하여 디스크에 동시에 병렬로 저장하기 때문입니다. 반대로 읽어 올때도 병렬로 모든 디스크에서 블록을 읽어서 처리합니다.

이 때문에 RAID 0는 성능면에서 이론적으로 무한한 가능성을 누릴 수 있습니다. 가령 5GB의 데이터를 하나의 디스크에 저장하는데 5분이 걸린다면, 분할 후 2개의 디스크에 나눠서 저장하면 2분 30초가 걸립니다. 이런식으로 개념을 확장하면 RAID 0의 처리시간은 {데이터를 하나의 디스크에 쓰는데 걸리는 시간/디스크의 수}가 되는데 디스크의 수를 무한히 늘리면 처리시간이 0에 수렴합니다. 이는 성능이 이론상 무한히 증가할 수 있다는 것을 의미합니다. 쉽게 바꿔말하면 디스크의 개수가 N배되면 성능도 N배로 늘어난다는 것이죠. 이 이야기는 파일을 읽어오는 경우에도 마찬가지 입니다.

이 외에도 RAID 0는 사용자가 디스크의 전체 용량을 활용할 수 있다는 장점이 있습니다. RAID 0은 복제본을 생성하지 않기 때문에 온전히 파일을 저장하기 위해서만 디스크를 사용할 수 있기 때문입니다.

가령 RAID 0는 400GB의 데이터를 저장하기 위해서는 100GB짜리 4개의 디스크를 사용하면 되는데 반해 HDFS에서는 2개의 복제본을 더 생성해야하기때문에 총 1200GB의 저장용량이 필요합니다. 같은 100GB짜리 디스크로 HDFS를 구축한다면 RAID 0의 3배인 12개가 필요한 것이죠.

다만, RAID0는 모든 디스크가 정상일 때만 데이터를 읽을 수 있습니다. RAID 0라는 방식 자체가 구성되는 모든 디스크를 사용하도록 되어있기 때문입니다.

앞의 그림을 예로들면 두 디스크 중 하나만 에러가 나도 파일을 읽을 수 없게 됩니다. 모든 디스크에 분산되어 있는 블록들이 전부 모여야만 온전한 파일을 읽어낼수 있기 때문이죠. 따라서 RAID 0는 Fault tolerance를 가지고 있지 않아 안정성이 매우 낮다는 단점이 있습니다.

RAID 1

RAID3

RAID 1은 미러링(Mirroring)이라는 기술을 사용하여 데이터를 저장합니다. 미러링이라는 이름에서 유추할 수 있듯이 미러링은 데이터를 복제하여 복수의 디스크에 저장합니다.

원본 파일과 그 것의 복제본들이 각 디스크에 저장되기 때문에 쓰기속도에서 향상은 없습니다. 다만 RAID 0처럼 블록단위로 저장 후 모든 디스크에서 블록을 하나씩 가져와서 읽을 수 있다면, 이론적으로 RAID 0만큼의 읽기 성능을 구현할 수는 있습니다. 하지만 보통은 그렇게 사용을 하지 않기 때문에 성능면에서 메리트가 떨어집니다.

그리고 RAID 1은 지나치게 많은 저장 용량을 필요로 합니다. 원본데이터와 똑같은 복제본을 다른 디스크에 저장해야하기 때문입니다. RAID 1의 필요 저장 용량은 {원본 데이터의 크기 * 디스크의 수} 입니다. 100GB 짜리 디스크 4개로 RAID 1을 구현하면, 100GB의 파일만 저장할 수 있다는 것 입니다. 나머지 300GB는 전부 복제본으로 채워져야 하기 때문이죠. 따라서 RAID 1은 저장 효율이 매우 안좋다는 단점이 있습니다.

대신 RAID 1은 모든 디스크들 중 하나만 살아있어도 데이터를 읽는데 문제가 없습니다. 즉, RAID 1은 디스크가 N개 있을 때 N-1개의 fault tolerance를 갖게 됩니다. 여기서 디스크의 수를 무한히 늘린다면, fault tolerance는 무한대로 발산하죠. 따라서 RAID 1은 매우 높은 수준의 fault tolerance를 가질 수 있어 안정성이 매우 높다는 장점이 있습니다.

RAID 5

RAID4

RAID 5는 RAID 종류들 중에 가장 많이 사용되는 방식입니다. RAID 5는 반드시 디스크가 3개 이상이여야하고 패리티(Parity)라는 새로운 개념이 도입된다는 점에서 앞의 두 종류의 RAID와 구분됩니다. (RAID 0와 RAID1은 최소 2개이상의 디스크를 요구합니다)

RAID 5는 RAID 0처럼 스트라이핑을 통해 데이터를 블록단위로 쪼개고 이를 분산 저장합니다. 그런데 데이터 중복성이 없어 fault tolerance가 없는 RAID 0와 다르게 RAID 5는 패리티라는 기술을 통해 fault tolerance를 가지게 됩니다.

그럼 페리티가 어떻게 fault tolerance를 가지게 해주는 것일까요?

위의 그림처럼 데이터 A, B, C, D가 RAID에 저장되면 각자 3개의 블록으로 나눠지고 이 블록 데이터를 가지고 XOR 연산을 통해 패러티 블록을 하나 생성합니다. 만일 디스크 1번이 망가지면 0, 2, 3번 디스크에 있는 데이터와 패리티 블록을 가지고 다시 XOR연산을 하면 1번 디스크의 데이터를 복구할 수 있습니다. 이는 RAID 5가 하나의 디스크의 손상에도 견딜 수 있는 fault tolerance를 가진다는 것을 의미합니다.

다만 RAID 5는 단하나의 디스크의 손상만을 허용합니다. XOR 알고리즘 자체가 하나의 미지수값만 계산할 수 있도록 되어있기 때문입니다. 그래서 두개 이상의 디스크에 동시에 장애가 발생한다면 데이터의 유실을 막을 수 없습니다.

RAID 5는 스트라이핑을 사용한다는 점에서 성능은 좋은 편입니다. 다만 RAID 0와 비교해서는 데이터를 디스크에 쓸 때 패리티 블록을 XOR 연산을 통해 생성하고 같이 쓰기 작업이 이루어져야하기 때문에 성능이 떨어집니다. 동시에 읽기 작업에서도 스트라이핑으로 생성된 스트라이프 그룹(불록 + 패리티 블록)에서 패리티 블록만 빼고 읽어오도록 하는 작업이 추가 되기때문에 이 또한 성능이 RAID 0에 비하면 떨어지게 됩니다.

이외에도 RAID 1 처럼 미러링을 통해 블록 자체를 복제하는 방식으로 fault tolerance를 확보하는 대신, 패리티 블록을 사용하여 fault tolerance를 확보하는 것은 요구되는 디스크 용량면에서 이점을 누릴 수 있습니다.

패리티 블록은 기본적으로 다른 블록들과 같은 크기를 갖기 때문에 모든 블록을 복제해야했던 RAID 1에 비하면 {디스크의 크기 * (디스크의 수 - 1) }만큼의 용량이 사용가능하다고 할 수 있습니다.

결과적으로 RAID 5는 RAID 0와 비교해서 어느정도 성능과 디스크 효율성에서 타협을 본 대신 fault tolerance를 확보한 것이라고 이해할 수 있습니다.

RAID 6

RAID5

RAID 6는 기본적으로 디스크 중 2개 이상이 장애가 나면 복구가 불가능한 RAID 5 약점을 보완하기위해 만들어 졌습니다.

그래서 많은 부분이 RAID 5와 같지만, 차이점들도 꽤 있습니다. 이를 하나씩 살펴보도록 하죠.

우선 RAID 6는 스트라이핑을 사용한다는 점에서 RAID 5와 같지만 패리티 블록을 2개 생성한다는 점에서 차이가 존재합니다. 그리고 패리티 블록 생성을 위해 XOR 알고리즘을 사용했던 RAID 5와 달리 RAID 6부터는 Reed-Solomon(RS) 알고리즘이 사용됩니다.

또한 패리티 블록이 2개가 됐기 때문에 RAID 5보다 좀 더 성능이 안좋습니다. 동시에 패리티 블록을 RAID 5에 비해 하나 더 저장해야되니 요구되는 최소 디스크의 수도 4개로 RAID 5보다 하나가 더 많고, 사용가능한 디스크 용량도 {디스크의 크기 * (디스크의 수 - 2) }로 RAID 5보다 더 작습니다.

대신 RAID 6는 패티리 블록이 2개가 서로다른 디스크에 저장되어 있기 때문에 2개의 디스크의 장애에도 복구가 가능합니다. 즉. 2개의 디스크 장애에 대한 fault tolerance를 갖게 된다는 이점이 있습니다.

결국 RAID 6는 RAID 5에 대해 어느정도 성능과 디스크 효율성에서 타협을 보고 fault tolerance를 더 확보한 것으로 이해할 수 있습니다.

아래의 표는 RAID 0~6까지를 요약한 내용입니다. 참고하면 좋을 듯하여 Wikipedia에서 가져왔습니다.

RAID6

여기서 하나 설명을 추가하자면, 디스크의 공간 효율성(Space efiicency)은 n의 값에 디스크의 수가 들어갑니다.

가령 RAID 5를 3개의 디스크로 구성했다고 한다면 2/3의 디스크 효율성을 갖는데 전체 디스크의 용량 중에서 1/3이 패리티 블록을 저장하기 위한 용도로 저장된다는 이야기입니다. 앞선 설명에서 패리티 블록이 하나 생성되고 세개의 디스크에 번갈아가면서 저장되었던 것을 기억한다면 이해가 바로 될 겁니다.

또한 저는 앞선 설명들에서 사용가능한 용량이라는 말을 디스크의 크기 * (디스크의 수 - 1)라고 표현을 했는데 디스크 효율성은 그걸 디스크의 크기 * 디스크의 수으로 나누어서 계산한 것 입니다. 식으로 표현하면 {디스크의 크기 * (N - 1)} / (디스크의 크기 * N) 인 것이죠 이를 풀면 디스크 효율성과 똑같은 형태가 됩니다.

추가로 디스크 효율성은 복제본이나 패리티를 제외하고 순수하게 원본 데이터를 얼마나 저장할 수 있느냐에 대한 것이기 때문에 RAID 0처럼 복제본과 패리티를 만들지 않는 이상 1보다 작은 값을 갖게 됩니다.

RAID 10

RAID의 큰 특징 중 하나는 여러 RAID들을 조합하여 사용할 수 있다는 점입니다. 그래서 RAID 10도 사실은 RAID 1 + 0입니다.

RAID7

RAID 10은 RAID1을 여러개 구성한 후 그걸 RAID 0로 묶은 형태입니다. 따라서 최소 필요 디스크 수도 4개가 됩니다.

RAID 10은 두 디스크를 미리 미러링해서 연결해놓고 그다음 데이터를 스트라이핑해서 저장하는 구조입니다. 스트라이핑해서 저장된 데이터는 당연히 각 RAID1의 디스크 중 하나에 저장이 되고 RAID1의 다른 디스크에 복제가 진행이 됩니다.

이를 그림을 보면서 설명하면, 우선 DISK 1-2와 DISK 3-4가 각각 별개의 RAID 1으로 구성됩니다. 두 RAID 1의 디스크는 미러링되어 있는 상태입니다. 그리고 데이터가 RAID 10으로 들어오면 스트라이핑을 시행하고 블록들이 두 RAID 1에 분산되어 저장됩니다.

이때, RAID 1을 구성하는 하나의 디스크 가령 DISK 1과 DISK 3에 블록 데이터가 저장되었다고 하면, 미러링 되어있기 때문에 DISK 2와 DISK 4에 같은 블록 데이터가 복제되어 저장됩니다.

RAID 10은 RAID 1과 RAID 0의 장점을 모두 취하고 있으므로, 높은 성능과 높은 fault tolerance를 가질 수 있습니다.

다만, 미러링을 사용하기 때문에 여전히 총 디스크 용량의 절반만 사용한다는 단점이 있어서 실제로 구축하기에는 많은 비용이 든다는 문제도 존재합니다.

번외 : JBOD

RAID8

JBOD도 RAID처럼 여러 디스크의 묶음입니다. JBOD가 RAID와 구분되는 건 데이터를 저장하는 방식에 있습니다.

JBOD는 디스크별로 하나씩 순차적으로 저장을합니다. 하나의 디스크가 다 차면 다음으로 넘어가는 방식으로 말이죠. 이때 저장할 디스크의 순서는 라운드 로빈이라는 방식을 따릅니다.

라운드 로빈이 어떻게 작동하는지는 적어도 여기서는 중요하지않습니다. 다만 라운드로빈에서 알아야할 건 라운드로빈 방식으로 순서를 정하면 반드시 구성원들에게 적어도 한번의 차례가 돌아간다는 사실입니다. 즉, JBOD는 라운드로빈 방식을 사용해서 자신이 가지고 있는 모든 디스크에 순차적으로 데이터를 저장한다는 것입니다.

사실 이렇게만 보면 RAID와 비교해서 별로 안좋아 보이는 느낌이 있습니다. 그리고 그 느낌이 정확하게 맞습니다. JBOD는 단독으로 사용되면 데이터 중복성도 보장하지 못하니 데이터 보호 기능을 전혀 수행하지 못하고 병렬처리를 못하기 때문에 RAID보다 성능도 훨씬 낮기 때문입니다.

JBOD의 장점은 확장이 쉽다는 것과 다양한 용량의 디스크로 배열을 구성할 수 있다는 것, 그리고 각 디스크의 저장용량이 완전히 활용된다는 것 정도입니다.

근데 여기서 진짜 재밌는 사실은 하둡이 JBOD 방식을 사용하고 있다는 겁니다. 도대체 왜 하둡은 JBOD 대신 RAID를 쓰지 않는걸까요?

답은 간단 명료합니다. JBOD와 하둡, 정확히는 HDFS는 서로 완벽하게 보완하고 있기 때문입니다.

JBOD와 HDFS

HDFS는 Replication이라는 기능을 통해서 데이터노드간에 복제본을 생성할 수 있습니다. 이때문에 JBOD가 가지고 있던 데이터 중복성 문제를 해결해주죠. 심지어 네임노드는 특정 블록 복제본이 유실되면 같은 복제본을 가지고 있는 데이터노드에게 복제본을 만들도록 지시할 수도 있습니다. 실제로 이를 통해 HDFS는 매우 높은수준의 fault tolerance를 가지고 있죠.

또한 HDFS의 시작을 생각해보면 HDFS는 서로다른 성능의 상용 하드웨어들을 전제로 만들었다는 사실을 기억해낼 수 있습니다. 이는 JBOD가 서로다른 용량의 디스크를 하나로 묶어줄수 있다는 장점과 정확하게 맞아 떨어지는 이야기죠.

그리고 HDFS는 데이터노드의 Scale out이 용이하다는 점을 생각해보면, JBOD방식과 상당히 잘 어울린다는 것을 알 수 있습니다. JBOD 역시 언제든 쉽게 디스크를 추가할 수 있기 때문이죠. 즉, JBOD 방식은 HDFS의 Scale out이 용이하다는 이점을 제대로 활용할 수 있다는 것입니다.

게다가 JBOD의 순차 저장방식은 데이터 노드의 스토리지를 낭비없이 모두 사용하도록 만들어주니 효율적이기도 합니다. 방대한 데이터를 저장해야되는 HDFS와 너무나도 어울리죠.

RAID와 HDFS

JBOD와 HDFS가 잘어울리는건 잘 이해했습니다. 근데 한가지 궁금증이 생기는건 정말 RAID는 필요가 없는가 하는 부분입니다.

RAID 0을 제외한 나머지는 미러링으로 복제본을 만들던지 아니면 패리티 블록을 만들어서 fault tolerance를 확보합니다.

반면 HDFS는 Replication 이라는 자체적인 시스템을 사용합니다. 데이터노드 간에 블록을 복제하는 기능이 존재하죠. 이를 통해 데이터 중복성을 확보하고 결국 HDFS는 fault tolerance를 갖게 됩니다. 따라서 HDFS는 자체적으로 fault tolerance를 확보하고 있기 때문에 굳이 데이터노드 서버들을 RAID로 구성할 필요가 전혀 없습니다.

그럼 성능은 어떨까요? HDFS에서 네임노드는 라운드로빈이라는 방식으로 데이터 블록들을 여러 데이터노드에 차례로 분배합니다. 쉽게말하면 라운드 로빈이라는 일련의 패턴을 가지고 순차적으로 하나씩 블록을 저장한다는 것입니다.

그러면 당연히 병렬처리의 개념이 포함된 스트라이핑을 사용하는 RAID가 성능면에서 더 뛰어날까요?

재밌게도 HDFS가 더 빠르다는 실험 결과가 존재합니다. 심지어 RAID에서 가장 빠른 RAID 0도 라운드로빈으로 배열하는 HDFS의 JBOD방식보다 느립니다.

이유는 RAID의 한계 때문입니다. 앞선 RAID에 대한 설명들은 모두 동일한 디스크로 RAID를 구성했다는 것을 전제했죠. 하지만 RAID의 디스크가 서로다른 경우에는 RAID를 구성하는 디스크 중 가장 낮은 성능을 가진 디스크의 성능에 전체 RAID가 영향을 받습니다.

근데 HDFS는 서로다른 성능을 가진 상용 하드웨어들의 집합입니다. 따라서 HDFS에 RAID를 적용한다면 가장 낮은 성능을 가진 디스크에 의해 전체 RAID 성능이 제한을 받게됩니다. 그런데 기존의 JBOD방식을 사용하면 모든 디스크의 동작들은 독립적이고 이러한 동작들의 평균적인 속도는 가장 느린 디스크의 속도보다 빠르게 됩니다. 따라서 데이터 노드에는 RAID를 사용할 필요가 없죠.

또 JBOD환경에서 디스크 장애가 발생해도 HDFS는 계속해서 동작합니다. 여기서 말하는 디스크의 문제는 완전히 망가져서 작동을 안하는 경우를 말합니다. 디스크들은 하나로 묶여있긴하지만 JBOD의 작동원리 상 디스크들은 서로 독립적이고, HDFS는 그 독립적인 디스크에 블록 복제본들을 완전히 분산 저장시킬 뿐만 아니라 복제본의 수가 부족하다는 걸 인지하면 데이터노드에게 복제본을 추가로 생성하도록 할 수 도 있습니다.

하지만 RAID는 단 한개의 디스크만 문제가 생겨도 전체 디스크 배열이 작동을 못합니다. 데이터의 유실은 어느정도 감당할 수 있으나 디스크 자체가 망가져버리면 아무것도 하지못한다는 것이죠. 그래서 HDFS에서 RAID를 사용하다가 하나의 디스크라도 망가지면 HDFS도 사용이 불가능해집니다. 역시나 데이터 노드에서 RAID는 필요가 없습니다.

다만 네임노드에 한해서는 메타데이터 보호를 위해 RAID1을 사용하는 것이 좋다는 이야기들이 있습니다. 반대로 HDFS에는 RAID를 아예 쓰지않는게 맞다는 이야기들도 있습니다. 결국 확실한건 데이터 노드에 대해서는 RAID가 필요없다는 사실 하나 입니다.

그래서 개인적으로 이 이상 풀어내기에는 상당히 애매하다는 생각이 들어 여기서 마무리 하겠습니다.

This post is licensed under CC BY 4.0 by the author.

용어정리 6. 패리티(Parity)

이코테 Ch.5 이진탐색(Binary search) 알고리즘 (1)