private BucketRegion createBucketRegion(int bucketId) {
    partitionedRegion.checkReadiness();

    BucketAttributesFactory factory = new BucketAttributesFactory();

    boolean isPersistent = partitionedRegion.getDataPolicy().withPersistence();
    if (isPersistent) {
      factory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
      setDiskAttributes(factory);
    } else {
      factory.setDataPolicy(DataPolicy.REPLICATE);
    }

    if (PartitionedRegion.DISABLE_SECONDARY_BUCKET_ACK) {
      factory.setScope(Scope.DISTRIBUTED_NO_ACK);
    } else {
      factory.setScope(Scope.DISTRIBUTED_ACK);
    }
    factory.setConcurrencyChecksEnabled(partitionedRegion.getConcurrencyChecksEnabled());
    factory.setIndexMaintenanceSynchronous(partitionedRegion.getIndexMaintenanceSynchronous());

    if (partitionedRegion.getValueConstraint() != null) {
      factory.setValueConstraint(partitionedRegion.getValueConstraint());
    }
    if (loader != null) {
      factory.setCacheLoader(loader);
    }
    factory.setEnableAsyncConflation(true);

    if (Boolean.getBoolean(GeodeGlossary.GEMFIRE_PREFIX + "PRDebug")) {
      factory.addCacheListener(createDebugBucketListener());
    }

    if (partitionedRegion.getStatisticsEnabled()) {
      factory.setStatisticsEnabled(true);
    }

    factory.setCloningEnabled(partitionedRegion.getCloningEnabled());

    ExpirationAttributes ea = partitionedRegion.getAttributes().getEntryIdleTimeout();
    if (ea != null) {
      factory.setEntryIdleTimeout(ea);
    }
    ea = partitionedRegion.getAttributes().getEntryTimeToLive();
    if (ea != null) {
      factory.setEntryTimeToLive(ea);
    }
    ea = partitionedRegion.getAttributes().getRegionIdleTimeout();
    if (ea != null) {
      if (ea.getAction() != ExpirationAction.DESTROY) {
        factory.setRegionIdleTimeout(ea);
      }
    }
    ea = partitionedRegion.getAttributes().getRegionTimeToLive();
    if (ea != null) {
      if (ea.getAction() != ExpirationAction.DESTROY) {
        factory.setRegionTimeToLive(ea);
      }
    }
    CustomExpiry ce = partitionedRegion.getAttributes().getCustomEntryIdleTimeout();
    if (ce != null) {
      factory.setCustomEntryIdleTimeout(ce);
    }
    ce = partitionedRegion.getAttributes().getCustomEntryTimeToLive();
    if (ce != null) {
      factory.setCustomEntryTimeToLive(ce);
    }

    if (partitionedRegion.getStatisticsEnabled()) {
      factory.setStatisticsEnabled(true);
    }
    EvictionAttributesImpl eva =
        (EvictionAttributesImpl) partitionedRegion.getEvictionAttributes();
    if (eva != null) {
      EvictionAttributes evBucket = eva;
      factory.setEvictionAttributes(evBucket);
      if (evBucket.getAction().isOverflowToDisk()) {
        setDiskAttributes(factory);
      }
    }

    factory.setCompressor(partitionedRegion.getCompressor());
    factory.setOffHeap(partitionedRegion.getOffHeap());

    factory.setBucketRegion(true); // prevent validation problems
    RegionAttributes attributes = factory.create();

    final String bucketRegionName = partitionedRegion.getBucketName(bucketId);

    LocalRegion rootRegion = PartitionedRegionHelper.getPRRoot(partitionedRegion.getCache());
    BucketRegion bucketRegion = null;

    if (Boolean.getBoolean(GeodeGlossary.GEMFIRE_PREFIX + "PRDebug")) {
      logger.info("createBucketRegion: Creating bucketId, {} name, {}.",
          partitionedRegion.bucketStringForLogs(bucketId),
          bucketRegionName);
    }
    try {
      final Bucket proxyBucket = partitionedRegion.getRegionAdvisor().getBucket(bucketId);
      bucketRegion = (BucketRegion) rootRegion.createSubregion(bucketRegionName, attributes,
          new InternalRegionArguments()
              .setPartitionedRegionBucketRedundancy(partitionedRegion.getRedundantCopies())
              .setBucketAdvisor(proxyBucket.getBucketAdvisor())
              .setPersistenceAdvisor(proxyBucket.getPersistenceAdvisor())
              .setDiskRegion(proxyBucket.getDiskRegion()).setCachePerfStatsHolder(this)
              .setLoaderHelperFactory(partitionedRegion)
              .setPartitionedRegion(partitionedRegion)
              .setIndexes(getIndexes(rootRegion.getFullPath(), bucketRegionName)));
      partitionedRegion.getPrStats().incBucketCount(1);
    } catch (RegionExistsException ex) {
      // Bucket Region is already created, so do nothing.
      if (logger.isDebugEnabled()) {
        logger.debug(
            "PartitionedRegionDataStore#createBucketRegion: Bucket region already created for bucketId={}{}{}",
            partitionedRegion.getPRId(), PartitionedRegion.BUCKET_ID_SEPARATOR, bucketId, ex);
      }
      bucketRegion = (BucketRegion) rootRegion.getSubregion(bucketRegionName);
    } catch (IOException ieo) {
      logger.debug("Unexpected error creating bucket in region", ieo);
      Assert.assertTrue(false, "IOException creating bucket Region: " + ieo);
    } catch (ClassNotFoundException cne) {
      if (logger.isDebugEnabled()) {
        logger.debug("Unexpected error creating bucket in region", cne);
      }
      Assert.assertTrue(false, "ClassNotFoundException creating bucket Region: " + cne);
    } catch (InternalGemFireError e) {
      if (logger.isDebugEnabled()) {
        logger.info("Assertion error creating bucket in region",
            e);
      }
      getPartitionedRegion().checkReadiness();
      throw e;
    }
    // Determine the size of the bucket (the Region in this case is mirrored,
    // get initial image has populated the bucket, compute the size of the
    // region)
    if (Boolean.getBoolean(GeodeGlossary.GEMFIRE_PREFIX + "PRDebug")) {
      dumpBuckets();
      dumpBucket(bucketId, bucketRegion);
    }

    return bucketRegion;
  }
This method creates bucket regions, based on redundancy level. If redundancy level is: a) = 1
it creates a local region b) >1 it creates a distributed region

@return @throws CacheException
geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegionDataStore.java