수십억 개의 행을위한 최고의 데이터 저장소


86

수십억 개의 레코드 (1 년에 약 30 억 / 월)에 대한 작은 데이터 비트 (약 50-75 바이트)를 저장할 수 있어야합니다.

유일한 요구 사항은 GUID가 동일한 모든 레코드에 대한 빠른 삽입 및 빠른 조회와 .net에서 데이터 저장소에 액세스 할 수있는 기능입니다.

저는 SQL 서버 전문가이고 SQL Server 가이 작업을 수행 할 수 있다고 생각 하지만 BigTable, CouchDB 및 기타 nosql 솔루션에 대한 모든 논의를 통해 점점 더 전통적인 RDBS의 대안이 될 수 있습니다. 분산 쿼리 및 확장. 나는 cassandra를 시도했고 .net 라이브러리는 현재 컴파일되지 않거나 모두 변경 될 수 있습니다 (cassandra 자체와 함께).

사용 가능한 많은 nosql 데이터 저장소를 살펴 보았지만 강력한 프로덕션 준비 플랫폼으로서의 요구 사항을 충족하는 저장소를 찾을 수 없습니다.

.net에서 액세스 할 수 있도록 360 억 개의 작고 평평한 레코드를 저장해야한다면 무엇을 선택하고 그 이유는 무엇입니까?


네, 제 전화 번호가 맞습니다. 현재이 정도의 데이터가 시스템에 들어오지 만이를 집계하고 집계 개수 만 저장하므로 레코드 당 데이터가 손실되고 시간당 데이터 합계 만 유지됩니다. 비즈니스 요구 사항으로 인해 각 레코드를 원래 발생한대로 유지하려고합니다. 이는 월 3Bil 행입니다.
Jody Powlette

좋은 질문을 많이하셨습니다. 대답은 다음과 같습니다. 95 % 가동 시간이면 충분합니다. 데이터가 이미 가변적 인 양으로 지연되었으므로 어쨌든 사실 후에 동기화해야하므로 잠시 중단되는 것은 거래 중단이 아닙니다. 잃어버린 인서트 또는 수천 개의 인서트가 세상의 끝이 아닙니다. 하루 분량의 데이터를 잃는 것은 꽤 나쁠 것입니다. 일관성도 그다지 중요하지 않습니다. 기본적으로 하루에 30Mil 행을 삽입 한 후 동일한 GUID (아마도 20 행)로 모든 행을 가져 와서 모두 다시 가져올 수 있는지 합리적으로 확신해야합니다.
Jody Powlette

매일 / 시간 단위로 예약 된 배치 작업에서 하루에 3 천만 개의 행을 덤프합니까, 아니면 한 번에 하나씩 일정한 흐름을 유지합니까?
Remus Rusanu

데이터는 FTP 사이트에서 도착합니다. 파일은 지속적으로 들어오고 파일을 구문 분석하는 프로세스가 있으며 현재 집계 된 데이터를 생성하고 집계 된 값 (아마도 1000 행)을 트랜잭션으로 삽입합니다. 새 프로세스는 도착하는 각 파일에서 수십만 개의 행을 삽입해야합니다. 대량 삽입을 사용하는 것이 가장 효율적인 방법 일 것입니다.
Jody Powlette

SSIS 및 SQL Server에 대한 ETL 작업처럼 들립니다. 시간당 2TB 이상의 업로드 속도로 ETL에 대한 세계 기록을 보유하고 있습니다. blogs.msdn.com/sqlperf/archive/2008/02/27/etl-world-record.aspx
Remus Rusanu

답변:


102

~ 3.5TB의 데이터를 저장하고 약 1K / sec 24x7 삽입 및 지정되지 않은 속도로 쿼리하는 것도 SQL Server에서 가능하지만 더 많은 질문이 있습니다.

  • 이에 대한 가용성 요구 사항은 무엇입니까? 99.999 % 가동 시간 또는 95 % 충분합니까?
  • 어떤 신뢰성 요구 사항이 있습니까? 삽입물을 놓치면 백만 달러의 비용이 듭니까?
  • 어떤 복구 가능성 요구 사항이 있습니까? 하루의 데이터를 잃어버린다면 상관 없나요?
  • 어떤 일관성 요구 사항이 있습니까? 쓰기가 다음 읽기에서 표시되도록 보장해야합니까?

내가 강조한 이러한 모든 요구 사항이 필요한 경우 제안하는로드는 어떤 기믹 (샤딩, 파티셔닝 등)을 시도하더라도 관계형 시스템, 모든 시스템에 대한 하드웨어 및 라이센스에 수백만 달러의 비용이들 것입니다. nosql 시스템은 정의상 이러한 모든 요구 사항을 충족하지 못합니다 .

따라서 이미 이러한 요구 사항 중 일부를 완화했습니다. Visual Guide to NoSQL Systems 에서 'pick 2 of 3'패러다임을 기반으로 nosql 제품을 비교하는 멋진 시각적 가이드가 있습니다 .

nosql 비교

OP 코멘트 업데이트 후

SQL Server를 사용하면 간단하게 구현할 수 있습니다.

  • 단일 테이블 클러스터 (GUID, 시간) 키. 예, 조각화 될 예정 이지만 조각화는 미리 읽기에 영향을 미치며 중요한 범위 스캔에만 미리 읽기가 필요합니다. 특정 GUID 및 날짜 범위에 대해서만 쿼리하므로 조각화는 그다지 중요하지 않습니다. 예,은 와이드 키이므로 리프가 아닌 페이지는 키 밀도가 낮습니다. 예, 채우기 비율이 좋지 않습니다. 예, 페이지 분할이 발생할 수 있습니다. 이러한 문제에도 불구하고 요구 사항을 고려할 때 여전히 최상의 클러스터 키 선택입니다.
  • 자동 슬라이딩 창을 통해 만료 된 레코드를 효율적으로 삭제할 수 있도록 테이블을 시간별로 분할합니다 . GUID 클러스터링으로 인해 발생하는 빈약 한 채우기 비율 및 조각화를 제거하기 위해 지난달의 온라인 인덱스 파티션 재 구축으로이를 확장합니다.
  • 페이지 압축을 활성화합니다. GUID별로 클러스터 된 키 그룹이 먼저이기 때문에 GUID의 모든 레코드가 서로 옆에 있으므로 페이지 압축 이 사전 압축을 배포 할 수있는 좋은 기회를 제공 합니다 .
  • 로그 파일을위한 빠른 IO 경로가 필요합니다. 로그가 초당 1K 삽입을 유지하기위한 짧은 지연 시간이 아닌 높은 처리량에 관심이 있으므로 스트리핑 이 필수입니다.

분할 및 페이지 압축에는 각각 Enterprise Edition SQL Server가 필요하며 Standard Edition에서는 작동하지 않으며 둘 다 요구 사항을 충족하는 데 매우 중요합니다.

참고로 레코드가 프런트 엔드 웹 서버 팜에서 가져온 경우 각 웹 서버에 Express를 배치하고 백 엔드에 INSERT 대신 SEND로컬 연결 / 트랜잭션을 사용하여 백 엔드에 정보를 입력합니다. 웹 서버와 같은 위치에있는 Express에서. 이것은 솔루션에 훨씬 더 나은 가용성 스토리를 제공합니다.

그래서 이것이 SQL Server에서 수행하는 방법입니다. 좋은 소식은 직면하게 될 문제가 잘 이해되고 해결책이 알려져 있다는 것입니다. 그렇다고 Cassandra, BigTable 또는 Dynamo로 달성 할 수있는 것보다 이것이 반드시 더 나은 것은 아닙니다. 나는 SQL이 아닌 일에 대해 더 많은 지식을 가진 사람에게 그들의 주장을 주장하도록 할 것입니다.

프로그래밍 모델, .Net 지원 등에 대해서는 언급 한 적이 없습니다. 솔직히 대규모 배포에는 관련이 없다고 생각합니다. 그들은 개발 프로세스에서 큰 차이를 만들지 만, 일단 배포되면 ORM 오버 헤드가 성능을 저하시키는 경우 개발 속도는 중요하지 않습니다. :)


나는 뜨거운 나단의 사이트를 연결,하지만이 첫 페이지를 슬래시닷 (Slashdot)되지 않는다)
레무스 Rusanu에게

@RemusRusanu : dba.se 마이그레이션을 살펴 봅니다. 준비하기 위해 :-) 그리고 +1
gbn

테이블 분할 이제 SQL 서버의 거의 모든 버전 2016에서 사용할 수 있습니다로 마이크로 소프트 SQL 서버 2016로, 엔터프라이즈 버전은 더 이상 테이블 분할 필요하지 않습니다
TChadwick

17

대중적인 믿음과는 달리 NoSQL은 성능이나 확장성에 관한 것이 아닙니다. 이는 주로 소위 Object-Relational 임피던스 불일치를 최소화하는 것이지만 수평 확장 성 대 RDBMS 의보다 일반적인 수직 확장 성에 관한 것이기도 합니다.

빠른 삽입 및 빠른 조회의 간단한 요구 사항에 대해서는 거의 모든 데이터베이스 제품이 가능합니다. 관계형 데이터 또는 조인을 추가하거나 적용해야하는 복잡한 트랜잭션 논리 또는 제약 조건이있는 경우 관계형 데이터베이스가 필요합니다. NoSQL 제품은 비교할 수 없습니다.

스키마없는 데이터가 필요한 경우 MongoDB 또는 CouchDB와 같은 문서 지향 데이터베이스를 사용하는 것이 좋습니다. 느슨한 스키마가 이들의 주요 매력입니다. 저는 개인적으로 MongoDB를 좋아하고 몇 가지 맞춤형보고 시스템에서 사용합니다. 데이터 요구 사항이 지속적으로 변경 될 때 매우 유용합니다.

다른 주요 NoSQL 옵션은 BigTable 또는 Cassandra와 같은 분산 키-값 저장소입니다. 이는 상용 하드웨어를 실행하는 많은 컴퓨터에서 데이터베이스를 확장하려는 경우 특히 유용합니다. 그들은 분명히 서버에서도 잘 작동하지만 SQL Server 또는 Oracle 또는 수직 확장을 위해 설계된 기타 데이터베이스뿐만 아니라 고급 하드웨어를 활용하지 않으며 분명히 관계형이 아니며 정규화를 시행하는 데 좋지 않습니다. 또는 제약. 또한 아시다시피 .NET 지원은 기껏해야 불안정한 경향이 있습니다.

모든 관계형 데이터베이스 제품은 제한된 종류의 파티셔닝을 지원합니다. BigTable이나 다른 DKVS 시스템만큼 유연하지 않고 수백 대의 서버에 쉽게 분할 되지는 않지만 실제로 원하는 것처럼 들리지 않습니다. 데이터를 적절하게 인덱싱하고 정규화하고 강력한 하드웨어 (특히 여유가있는 경우 SSD)에서 데이터베이스를 실행하고 다음과 같은 경우 2 개 또는 3 개 또는 5 개의 물리적 디스크로 분할하는 한 수십억 개의 레코드 수를 처리하는 데 매우 능숙합니다. 필요한.

위의 기준을 충족하고 기업 환경에서 일하고 있고 적절한 하드웨어 및 데이터베이스 최적화에 지출 할 돈이 있다면 지금은 SQL Server를 고수 할 것입니다. 돈이 많이 들고 저가형 Amazon EC2 클라우드 컴퓨팅 하드웨어에서이를 실행해야하는 경우 대신 Cassandra 또는 Voldemort를 선택하는 것이 좋습니다 (.NET으로 작업 할 수 있다고 가정).


11

수십억 행 집합 크기로 작업하는 사람은 거의 없으며 대부분의 경우 스택 오버플로에서 이와 같은 요청을 볼 때 데이터는보고되는 크기에 가까운 곳에 없습니다.

매월 360 억, 30 억, 이는 대략 하루 1 억, 시간당 416 만, 분당 ~ 70k 행, 시스템에 초당 1.1k 행이 12 개월 동안 지속적으로 들어오는데, 이는 다운 타임이 없다고 가정합니다.

그 수치는 긴 마진으로 불가능하지 않습니다. 저는 더 큰 시스템을 수행했지만 실제로 의미하는 수량인지 다시 확인하고 싶습니다. 실제로이 수량을 가진 앱은 거의 없습니다.

저장 / 검색과 관련하여 언급하지 않은 매우 중요한 측면은 오래된 데이터의 노화입니다. 삭제는 무료가 아닙니다.

일반적인 기술은 파티셔닝이지만 GUID 기반의 조회 / 검색은 전체 12 개월 동안 일치하는 모든 값을 가져와야한다고 가정하면 성능이 저하됩니다. GUID 열에 클러스터형 인덱스를 배치하면 읽기 / 쓰기를 위해 관련 데이터가 클러스터링되지만 이러한 양과 삽입 속도에서는 조각화가 너무 높아 지원할 수 없으며 바닥에 떨어집니다.

또한 이것이 OLTP 유형 응답 속도를 가진 심각한 응용 프로그램 인 경우, 대략 2.7TB의 데이터 인덱싱 오버 헤드가 거의 없다고 가정 할 때 대략적인 추측에 의한 경우 매우 적절한 하드웨어 예산이 필요하다고 제안합니다.

SQL Server 진영에서 살펴볼 수있는 유일한 것은 대규모 데이터 마트에 대해 고속을 제공하기 위해 데이터를 분할하고 이에 대해 병렬 쿼리를 실행하도록 설계된 새로운 병렬 데이터웨어 하우스 에디션 (madison)입니다.


3
생물 정보학에서 십억 행 데이터 세트는 드문 일이 아닙니다. 그러나 플랫 파일에서 순수한 스트리밍 방식으로 처리되는 경우가 많습니다.
Erik Garrison

3
@Erik : 스트림 처리 (즉, 특정 조건을 감지해야하지만 나중에 쿼리하기 위해 데이터를 저장할 필요가 없음)의 경우 StreamInsight와 같은 것이 어떤 데이터베이스보다 낫습니다. microsoft.com/sqlserver/2008/en/us/r2 -complex-event.aspx
Remus Rusanu

2

"저는 수십억 개의 레코드 (1 년에 약 30 억 / 월)에 대해 작은 데이터 비트 (약 50-75 바이트)를 저장할 수 있어야합니다.

유일한 요구 사항은 GUID가 동일한 모든 레코드에 대한 빠른 삽입 및 빠른 조회와 .net에서 데이터 저장소에 액세스 할 수있는 기능입니다. "

2009 년 초에이 작업을 수행했기 때문에 SQL Server에서 이것이 가능하다는 것을 경험을 통해 말할 수 있습니다. 그리고 지금까지도 여전히 작동하며 매우 빠릅니다.

테이블은 256 개의 파티션으로 분할되었습니다.이 버전은 2005 SQL 버전이라는 점을 명심하십시오. 우리는 정확히 말씀하신대로 GUID로 정보를 저장하고 GUID로 빠르게 검색했습니다.

내가 떠났을 때 우리는 약 2-3 억 개의 레코드를 가지고 있었고 데이터 보존 정책이 막 인스턴스화 되려고했지만 데이터 검색은 여전히 ​​꽤 좋았습니다 (UI를 통하는 경우 1-2 초, RDBMS의 경우 그 이하).

짧게 말하면 GUID 문자열에서 8 번째 문자 (즉, 중간 어딘가)를 가져와 SHA1이 해시하고 작은 정수 (0-255)로 캐스팅하고 적절한 파티션에 저장하고 가져올 때 동일한 함수 호출을 사용했습니다. 다시 데이터.

더 많은 정보가 필요하면 나에게 ping을 ...


2

다음 문서에서는 Microsoft SQL에서 160 억 개의 행 테이블을 가져오고 사용하는 방법에 대해 설명합니다 . http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

기사에서 :

내 경험에서 얻은 몇 가지 팁은 다음과 같습니다.

  • 정의 된 클러스터형 인덱스가있는 테이블에 데이터가 많을수록 정렬되지 않은 레코드를 테이블로 가져 오는 속도가 느려집니다. 어느 시점에서 실용적 이기에는 너무 느려집니다.
  • 테이블을 가능한 가장 작은 파일로 내보내려면 기본 형식으로 만드십시오. 이것은 문자 데이터보다 이진 필드에서 더 간결하게 표현되기 때문에 대부분 숫자 열을 포함하는 테이블에서 가장 잘 작동합니다. 모든 데이터가 영숫자이면 기본 형식으로 내보내는 것으로 많은 것을 얻을 수 없습니다. 숫자 필드에 널을 허용하지 않으면 데이터를 더 압축 할 수 있습니다. 필드가 널 입력 가능하도록 허용하는 경우 필드의 이진 표현에는 뒤에 오는 데이터 바이트 수를 나타내는 1 바이트 접 두부가 포함됩니다.
  • BCP 카운터 변수가 4 바이트 정수이므로 2,147,483,647 개 이상의 레코드에 대해 BCP를 사용할 수 없습니다. MSDN이나 인터넷에서 이에 대한 참조를 찾을 수 없었습니다. 테이블
    이 2,147,483,647 개 이상의 레코드 로 구성된 경우 청크로 내보내
    거나 고유 한 내보내기 루틴을 작성해야합니다.
  • 미리 채워진 테이블에 클러스터형 인덱스를 정의하면 많은 디스크 공간이 필요합니다. 내 테스트에서 내 로그는
    완료되기 전에 원래 테이블 크기의 10 배로 폭발했습니다 .
  • BULK INSERT 문을 사용하여 많은 레코드를 가져올 때 BATCHSIZE 매개 변수를 포함하고
    한 번에 커밋 할 레코드 수를 지정합니다 . 이 매개 변수를 포함하지 않으면
    전체 파일을 단일 트랜잭션으로 가져 오므로
    많은 로그 공간 이 필요합니다.
  • 클러스터형 인덱스가있는 테이블로 데이터를 가져 오는 가장 빠른 방법은 먼저 데이터를 사전 정렬하는 것입니다. 그런 다음
    ORDER 매개 변수와 함께 BULK INSERT 문을 사용하여 가져올 수 있습니다 .

1

간과 된 것 같은 특이한 사실이 있습니다.

" 기본적으로 하루에 3 천만 행을 삽입 한 후 동일한 GUID (아마도 20 행)로 모든 행을 가져 와서 모두 다시 가져올 수 있는지 확인해야합니다. "

20 개의 열만 필요하면 GUID의 클러스터되지 않은 인덱스가 제대로 작동합니다. 파티션간에 데이터 분산을 위해 다른 열에 클러스터링 할 수 있습니다.

데이터 삽입에 대해 질문이 있습니다. 어떻게 삽입되고 있습니까?

  • 특정 일정 (분당, 시간당 등)에 대한 대량 삽입입니까?
  • 이 데이터는 어떤 소스 (플랫 파일, OLTP 등)에서 가져 오나요?

방정식의 한쪽을 이해하는 데 도움이되도록 이것에 대한 답이 필요하다고 생각합니다.


1

Amazon Redshift는 훌륭한 서비스입니다. 질문이 원래 2010 년에 게시되었을 때는 사용할 수 없었지만 이제는 2017 년에 주요 플레이어입니다. Postgres에서 분기 된 열 기반 데이터베이스이므로 표준 SQL 및 Postgres 커넥터 라이브러리가 함께 작동합니다.

보고 목적, 특히 집계에 가장 적합합니다. 단일 테이블의 데이터는 Amazon 클라우드의 여러 서버에 저장되고 정의 된 테이블 distkey를 통해 배포되므로 분산 된 CPU 성능에 의존합니다.

따라서 SELECT 및 특히 집계 된 SELECT는 매우 빠릅니다. 대용량 데이터로드는 Amazon S3 csv 파일에서 COPY 명령을 사용하여 수행하는 것이 좋습니다. 단점은 DELETE 및 UPDATE가 평소보다 느리다는 것입니다. 그렇기 때문에 Redshift는 주로 초국적 데이터베이스가 아니라 데이터웨어 하우스 플랫폼에 더 가깝습니다.


0

Cassandra 또는 HBase를 사용해 볼 수 있지만 사용 사례에 따라 column family를 디자인하는 방법을 읽어야합니다. Cassandra는 자체 쿼리 언어를 제공하지만 데이터에 직접 액세스하려면 HBase의 Java API를 사용해야합니다. Hbase를 사용해야하는 경우 오픈 소스 프로젝트 인 Map-R에서 Apache Drill로 데이터를 쿼리하는 것이 좋습니다. Drill의 쿼리 언어는 SQL 호환입니다 (드릴의 키워드는 SQL에서와 동일한 의미를 가짐).


0

연간 기록이 너무 많으면 결국 공간이 부족해질 것입니다. 2 ^ 64 파일을 지원하고 더 작은 상자를 사용하는 xfs와 같은 파일 시스템 스토리지는 어떻습니까? 얼마나 멋진 사람들이 원하는지 또는 돈의 양에 관계없이 데이터베이스 SQL NoSQL ..이 많은 기록이 일반적으로 전기 회사 및 기상청 / 환경부와 같은 제공자가 작성하는 데이터베이스를 사용하여 시스템을 얻는 데 지출하게됩니다. 전국의 방송국. 압력 저장 .. 온도 .. 풍속 .. 습도 등을 저장하는 것과 같은 작업을하고 guid가 위치 인 경우에도 데이터를 연 / 월 / 일 / 시간으로 나눌 수 있습니다. 하드 드라이브 당 4 년의 데이터를 저장한다고 가정합니다. 그런 다음 더 나은 읽기 속도를 제공하고 여러 마운트 지점을 갖는 미러가있는 더 작은 Nas에서 실행할 수 있습니다. 생성 된 연도를 기준으로합니다. 검색을위한 웹 인터페이스를 간단하게 만들 수 있습니다. 그래서 덤핑 위치 1 / 2001 / 06 / 01 // 온도 및 위치 1 / 2002 / 06 / 01 // 온도는 2 년 (24 시간 * 2) 48 개의 작은 파일에서 여름 1 일 동안 시간별 온도의 내용 만 덤프하고 수십억 개의 레코드와 아마도 수백만 개의 지출이있는 데이터베이스를 검색합니다. 사물을 보는 간단한 방법 .. 하나님과 함께 세계에서 15 억 개의 웹 사이트는 각각 몇 페이지의 페이지가 있는지 알고 있습니다. 만약 구글과 같은 회사가 슈퍼 컴퓨터에 대한 비용을 지불하기 위해 30 억 검색 당 수백만을 지출해야한다면 그들은 파산 될 것입니다. 대신에 그들은 전력 청구서 ... 몇 백만 대의 쓰레기 컴퓨터를 가지고 있습니다. 그리고 카페인 인덱싱 ... 미래 보장 .. 계속 추가합니다. 그리고 예, SQL에서 실행되는 인덱싱이 의미있는 곳이라면 날씨 ... 통계 등과 같은 고정 된 작업을 위해 슈퍼 컴퓨터를 구축하여 기술자가 xtb에 xtb를 자랑 할 수 있습니다. 다른 곳에서 보냈습니다 ..


-2

레코드를 일반 바이너리 파일 (GUID 당 하나의 파일)로 저장하는 것은 그보다 더 빠르지 않습니다.


5
이것이 정말로 잘 수행되기를 기대합니까?
ChaosPandion

3
예, 파일 시스템에 수십억 개의 파일을 생성하는 것은 일부 파일 시스템에 치명적일 수 있습니다. 나는 이런 일을하는 실수를 저질렀지만, 단 1 백만으로 그 폴더 중 하나에 대한 셸을 열려고 시스템을 거의 중단했습니다. 또한 GUID를 기반으로 검색하지 않는 한 쿼리 메커니즘은 어떻게 작동해야합니까?
Rob Goodwin

얼마나 많은 고유 GUID가 예상되는지 알지 못하면 이것이 어떻게 수행되는지 추측하기 어렵습니다. :) 그러나 일반 파일에 쓰는 것보다 더 간단하지 않습니다. GUID에 의한 조회와 함께 빠른 삽입이 유일한 요구 사항이었습니다.
Thomas Kjørnes

작동 할 수 있지만 폴더 당 파일 수를 제한해야합니다. n 개의 파일마다 새 폴더를 생성해야합니다. guid의 하위 문자열을 폴더 이름으로 사용할 수 있습니다.
TTT

1
예, 많은 파일 시스템에 대한 inode 수에 제한이 있으며 redhat 기본 파일 시스템에 대한 제한에 도달 한 것을 기억합니다. 제한은 약 1,000,000 개 파일입니다.
Dean Hiller

-3

MongoDB를 사용하고 guid를 샤딩 키로 사용할 수 있습니다. 즉, 여러 머신에 데이터를 배포 할 수 있지만 샤딩 키로 선택하기 때문에 선택하려는 데이터는 하나의 머신에만 있습니다.

MongoDb의 샤딩은 아직 생산 준비가되지 않았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.