HBase와 스키마 설계

HBase와 스키마 설계

이 문서는 HBase에서 스키마를 어떻게 설계하고 만들고 수정하는지 알려줘요. HBase는 RDBMS와 모델링 방식이 많이 달라요. 비관계형 데이터스토어의 장단점과 HBase 스키마 설계의 실용적인 규칙(rule of thumb)을 이해하고 싶다면 이 문서를 읽어 보세요.

출처: 문서

본문

다양한 비-RDBMS 데이터스토어에서 모델링의 장점과 단점에 대한 좋은 소개는 Ian Varley의 석사 논문, No Relation: The Mixed Blessings of Non-Relational Databases에서 찾을 수 있어요. 조금 오래됐지만 HBase 스키마 모델링이 RDBMS에서 하는 방식과 어떻게 다른지에 대한 좋은 배경 읽을거리예요. 또한 HBase가 데이터를 내부적으로 어떻게 저장하는지 keyvalue, 그리고 schema.casestudies 섹션도 읽어 보세요.

Cloud Bigtable 웹사이트의 문서인 Designing Your Schema는 관련이 깊고 잘 정리되어 있어요. 거기서 얻은 교훈은 HBase에서도 똑같이 적용돼요. 다만 인용된 값을 약 10으로 나누면 HBase에 맞아요. 예를 들어 개별 값이 ~10MB가 될 수 있다고 하면 HBase도 비슷하게 할 수 있고, 가능하면 더 작게 하는 게 좋아요. Cloud Bigtable에서 최대 100개의 column family라고 하면 HBase에서는 ~10개로 생각하세요.

Robert Yokota의 HBase Application Archetypes(다른 HBase 사용자들이 한 작업의 업데이트)도 참고하세요. HBase 모델 위에서 잘 동작하는 사용 사례의 유용한 분류입니다.

스키마 생성

HBase 스키마는 Apache HBase Shell을 사용하거나 Java API의 Admin을 사용해 만들거나 업데이트할 수 있어요.

ColumnFamily를 수정할 때는 테이블을 비활성화(disable)해야 해요. 예를 들어:

Configuration config = HBaseConfiguration.create();
Admin admin = new Admin(conf);
TableName table = TableName.valueOf("myTable");

admin.disableTable(table);

HColumnDescriptor cf1 = ...;
admin.addColumn(table, cf1);      // adding new ColumnFamily
HColumnDescriptor cf2 = ...;
admin.modifyColumn(table, cf2);    // modifying existing ColumnFamily

admin.enableTable(table);

클라이언트 연결 구성에 대한 자세한 내용은 client dependencies를 참고하세요.

온라인 스키마 변경은 0.92.x 코드베이스에서 지원되지만, 0.90.x 코드베이스는 테이블을 비활성화해야 해요.

스키마 업데이트

Table 또는 ColumnFamily에 변경(예: region 크기, block 크기)이 이뤄지면, 이 변경은 다음 메이저 컴팩션 때 StoreFiles가 다시 쓰여질 때 효과가 나타나요.

StoreFiles에 대한 자세한 내용은 store를 참고하세요.

테이블 스키마 규칙

데이터 세트가 다양하고 접근 패턴과 서비스 수준 기대치도 다르기 때문에, 이 규칙들은 개요일 뿐이에요. 이 목록을 훑은 후 이 장의 나머지를 읽어 더 자세한 내용을 확인하세요.

  • region 크기는 10~50GB 사이를 목표로 해요.
  • cell 크기는 10MB 이하, 또는 mob을 사용한다면 50MB 이하를 목표로 해요. 그렇지 않으면 cell 데이터를 HDFS에 저장하고 HBase에는 데이터에 대한 포인터를 저장하는 방법을 고려하세요.
  • 일반적인 스키마는 테이블당 1~3개의 column family를 가져요. HBase 테이블은 RDBMS 테이블을 모방하도록 설계하면 안 돼요.
  • column family가 12개인 테이블은 region 수가 약 50100개가 좋아요. region은 column family의 연속된 세그먼트라는 점을 기억하세요.
  • column family 이름은 가능한 한 짧게 유지하세요. column family 이름은 모든 값마다 저장돼요(prefix encoding은 무시). 일반 RDBMS처럼 자기 설명적이면서 기술적인 이름이면 안 돼요.
  • 시간 기반 머신 데이터나 로깅 정보를 저장하고 row key가 device ID나 service ID+시간을 기반으로 한다면, 특정 나이를 넘으면 오래된 데이터 region에 더 이상 쓰기가 발생하지 않는 패턴이 생길 수 있어요. 이런 상황에서는 활성 region 수가 적고 새 쓰기가 없는 오래된 region이 많아지게 돼요. 이럴 때는 리소스 소비가 활성 region에 의해서만 결정되므로 더 많은 수의 region을 허용할 수 있어요.
  • 하나의 column family만 쓰기로 바쁘다면 그 column family만 메모리를 축적해요. 리소스를 할당할 때 쓰기 패턴을 인지하세요.

더 알아보기 (Learn more)