public void doSplit(final Long regionId, final Long newRegionId, final byte[] splitKey) {
        try {
            Requires.requireNonNull(regionId, "regionId");
            Requires.requireNonNull(newRegionId, "newRegionId");
            final RegionEngine parent = getRegionEngine(regionId);
            final Region region = parent.getRegion().copy();
            final RegionEngineOptions rOpts = parent.copyRegionOpts();
            region.setId(newRegionId);
            region.setStartKey(splitKey);
            region.setRegionEpoch(new RegionEpoch(-1, -1));

            rOpts.setRegionId(newRegionId);
            rOpts.setStartKeyBytes(region.getStartKey());
            rOpts.setEndKeyBytes(region.getEndKey());
            rOpts.setRaftGroupId(JRaftHelper.getJRaftGroupId(this.pdClient.getClusterName(), newRegionId));
            rOpts.setRaftDataPath(null);

            String baseRaftDataPath = this.storeOpts.getRaftDataPath();
            if (Strings.isBlank(baseRaftDataPath)) {
                baseRaftDataPath = "";
            }
            rOpts.setRaftDataPath(baseRaftDataPath + "raft_data_region_" + region.getId() + "_"
                                  + getSelfEndpoint().getPort());
            final RegionEngine engine = new RegionEngine(region, this);
            if (!engine.init(rOpts)) {
                LOG.error("Fail to init [RegionEngine: {}].", region);
                throw Errors.REGION_ENGINE_FAIL.exception();
            }

            // update parent conf
            final Region pRegion = parent.getRegion();
            final RegionEpoch pEpoch = pRegion.getRegionEpoch();
            final long version = pEpoch.getVersion();
            pEpoch.setVersion(version + 1); // version + 1
            pRegion.setEndKey(splitKey); // update endKey

            // the following two lines of code can make a relation of 'happens-before' for
            // read 'pRegion', because that a write to a ConcurrentMap happens-before every
            // subsequent read of that ConcurrentMap.
            this.regionEngineTable.put(region.getId(), engine);
            registerRegionKVService(new DefaultRegionKVService(engine));

            // update local regionRouteTable
            this.pdClient.getRegionRouteTable().splitRegion(pRegion.getId(), region);
        } finally {
            this.splitting.set(false);
        }
    }
Storage engine, there is only one instance in a node,
containing one or more {@link RegionEngine}.

@author jiachun.fjc
jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/StoreEngine.java