'개발새발'에 해당되는 글 56건



HBase를 운영하다보면 직면하는 문제 중 하나가 바로 Region이 Too Much하게 Split되는 현상이다.


이를 관리하기 위해서는 Split되는 기준 즉, SplitPolicy를 이해해야 한다.


가장 기본이 되는 Policy는 ConstantSizeRegionSplitPolicy이다.


하지만 0.94 버전 이후에는 IncreasingToUpperBoundRegionSplitPolicy가 기본 Policy로 설정된다.


물론 아래와 같이 전역 설정으로 변경하면 기본 Policy를 변경할 수 있고, 테이블 별 설정도 가능하다.


<property>
  <name>hbase.regionserver.region.split.policy</name>
  <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>


쉘에서 특정 테이블에 대해 SplitPolicy를 변경하려면 아래와 같이 커맨드를 실행한다.


hbase> alter 'test', {METADATA => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy'}}


각 SplitPolicy는 소스코드 내에서도 손쉽게 확인할 수 있다.


소스코드 위치는 hbase/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ 이다.


앞서 언급한 SplitPolicy 외에도 BusyRegionSplitPolicy, DelimitedKeyPrefixRegionSplitPolicy, KeyPrefixRegionSplitPolicy, SteppingSplitPolicy와 같은 다양한 Policy가 존재하며 Customize도 가능하다.


최근 버전의 기본 Policy인 IncreasingToUpperBoundRegionSplitPolicy는 과거 버전의 기본 Policy인 ConstantSizeRegionSplitPolicy를 상속 받아 구현되었다.


핵심 부분만 짚어보자면


/**
 * @return Region max size or {@code count of regions cubed * 2 * flushsize},
 * which ever is smaller; guard against there being zero regions on this server.
 */
protected long getSizeToCheck(final int tableRegionsCount) {
  // safety check for 100 to avoid numerical overflow in extreme cases
  return tableRegionsCount == 0 || tableRegionsCount > 100
             ? getDesiredMaxFileSize()
             : Math.min(getDesiredMaxFileSize(),
                        initialSize * tableRegionsCount * tableRegionsCount * tableRegionsCount);
}


위부분에 명시된 로직처럼 Table 내 Region 수가 100개 이하의 경우 RegionMaxFileSize vs Regions Cubed * initialSize(2 * Flush Size) 중 작은 값을 Region Split을 위한 비교 크기로 삼는다.


여기서 RegionMaxFileSize는 ConstantSizeRegionSplitPolicy에 선언된 함수로 다음과 같다.


@Override
protected void configureForRegion(HRegion region) {
  super.configureForRegion(region);
  Configuration conf = getConf();
  TableDescriptor desc = region.getTableDescriptor();
  if (desc != null) {
    this.desiredMaxFileSize = desc.getMaxFileSize();
  }
  if (this.desiredMaxFileSize <= 0) {
    this.desiredMaxFileSize = conf.getLong(HConstants.HREGION_MAX_FILESIZE,
      HConstants.DEFAULT_MAX_FILE_SIZE);
  }
  double jitter = conf.getDouble("hbase.hregion.max.filesize.jitter", 0.25D);
  this.jitterRate = (RANDOM.nextFloat() - 0.5D) * jitter;
  long jitterValue = (long) (this.desiredMaxFileSize * this.jitterRate);
  // make sure the long value won't overflow with jitter
  if (this.jitterRate > 0 && jitterValue > (Long.MAX_VALUE - this.desiredMaxFileSize)) {
    this.desiredMaxFileSize = Long.MAX_VALUE;
  } else {
    this.desiredMaxFileSize += jitterValue;
  }
}


이것 역시 주요 부분만 살펴보자면 Configuration으로부터 읽어온 HREGION_MAX_FILESIZE 값과 jitter 값으로 계산하여 desiredMaxFileSize를 계산하고 있다.


jitter 값은 hbase-site.xml에 기본 입력되지 않으므로 일반적으로 0.25D 값이 사용된다.


이를 간단하게 분석해보면 jitterRate은 (랜덤수 - 0.5D) * 0.25D가 되어 -0.125 ~ 0.125 사이 값으로 계산된다.


jitterRate * desiredMaxFileSize가 최종 jitterValue가 되며, 10G의 MaxFileSize를 갖는 경우 jitterValue는 -1280 MB ~ 1280 MB 범위를 가진다.


따라서 IncreasingToUpperBoundRegionSplitPolicy의 경우 jitterValue 만큼 +된 결과 값이 Table 내 Region 수가 101개 이상인 경우 비교 값으로 설정된다.


이와 같은 SplitPolicy로 100개 이하의 Region 수에서는 테이블이 Split을 MaxFileSize보다 작은 크기에서도 자주 수행하여 Region을 분산 시킨다.


실제로 적은 수의 Region을 수동으로 Split 하는 것보다 이러한 SplitPolicy를 이용하여 AutoSplit을 수행하는 것이 가장 바람직하며, Apache HBase 문서에서도 권장하고 있다.


jitter 값을 변경함에 따라 MaxFileSize에 대한 +/- 값으로 Split을 결정하기 때문에 때로는 jitter 값 변경도 필요할 때가 있다.


변경을 위해서는 아래와 같이 HBase 쉘 커맨드를 실행할 수 있다.


hbase> alter ‘t1’, CONFIGURATION => {‘hbase.hregion.max.filesize.jitter’ => ‘0.125’}


참조: Apache HBase Book, HBase Commands



'Development > Hadoop' 카테고리의 다른 글

HBase 공부 - Tuning, Monitoring  (0) 2019.01.24
HBase 공부 - Scan, Filter  (0) 2019.01.24
HBase 공부 - HBase의 특징과 구조  (1) 2019.01.24
하둡 공부 - Yarn Scheduler  (0) 2019.01.24
하둡 공부 - Apache Hadoop 3.0.0  (0) 2019.01.24
블로그 이미지

나뷜나뷜

,