com.staros.manager.StarManager Maven / Gradle / Ivy
// Copyright 2021-present StarRocks, Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.staros.manager;
import com.staros.exception.ExceptionCode;
import com.staros.exception.StarException;
import com.staros.filestore.FilePath;
import com.staros.filestore.FileStore;
import com.staros.filestore.FileStoreMgr;
import com.staros.filestore.FileStoreMgrs;
import com.staros.heartbeat.HeartbeatManager;
import com.staros.journal.DummyJournalSystem;
import com.staros.journal.Journal;
import com.staros.journal.JournalReplayer;
import com.staros.journal.JournalSystem;
import com.staros.proto.CreateMetaGroupInfo;
import com.staros.proto.CreateShardGroupInfo;
import com.staros.proto.CreateShardInfo;
import com.staros.proto.CreateShardJournalInfo;
import com.staros.proto.DeleteShardGroupInfo;
import com.staros.proto.FilePathInfo;
import com.staros.proto.FileStoreInfo;
import com.staros.proto.FileStoreType;
import com.staros.proto.MetaGroupInfo;
import com.staros.proto.MetaGroupJournalInfo;
import com.staros.proto.ReplicaInfo;
import com.staros.proto.ServiceInfo;
import com.staros.proto.ShardGroupInfo;
import com.staros.proto.ShardInfo;
import com.staros.proto.ShardInfoList;
import com.staros.proto.StarManagerFileMetaFooter;
import com.staros.proto.StarManagerFileMetaHeader;
import com.staros.proto.StarManagerFileMetaHolder;
import com.staros.proto.UpdateMetaGroupInfo;
import com.staros.proto.WorkerInfo;
import com.staros.schedule.ShardSchedulerV2;
import com.staros.service.Service;
import com.staros.service.ServiceManager;
import com.staros.service.ServiceTemplate;
import com.staros.shard.Shard;
import com.staros.shard.ShardChecker;
import com.staros.shard.ShardGroup;
import com.staros.shard.ShardManager;
import com.staros.util.Config;
import com.staros.util.IdGenerator;
import com.staros.util.LockCloseable;
import com.staros.util.LogUtils;
import com.staros.util.Text;
import com.staros.worker.Worker;
import com.staros.worker.WorkerManager;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
public class StarManager {
public static final String FILE_META_RAW_HEADER = "STARMGR1";
private static final Logger LOG = LogManager.getLogger(StarManager.class);
private AtomicBoolean isLeader;
private ServiceManager serviceManager;
private WorkerManager workerManager;
private FileStoreMgrs fsMgrs;
private ShardSchedulerV2 shardScheduler;
private ShardChecker shardChecker;
private HeartbeatManager heartbeatManager;
private JournalReplayer journalReplayer;
private JournalSystem journalSystem;
private IdGenerator idGenerator;
// FOR TEST
public StarManager() {
this(new DummyJournalSystem());
}
public StarManager(JournalSystem journalSystem) {
this.journalSystem = journalSystem;
fsMgrs = new FileStoreMgrs();
idGenerator = new IdGenerator(journalSystem);
isLeader = new AtomicBoolean(false);
serviceManager = new ServiceManager(this.journalSystem, idGenerator);
workerManager = new WorkerManager(this.journalSystem, idGenerator);
shardScheduler = new ShardSchedulerV2(serviceManager, workerManager);
shardChecker = new ShardChecker(serviceManager, workerManager, shardScheduler);
heartbeatManager = new HeartbeatManager(workerManager);
journalReplayer = new JournalReplayer(this);
serviceManager.setShardScheduler(shardScheduler);
}
// pre check, mostly used to check if we can accept non-read request
private void checkLeader() throws StarException {
if (!isLeader.get()) {
throw new StarException(ExceptionCode.NOT_LEADER,
"request rejected, current star manager is not leader.");
}
}
public void becomeLeader() {
journalSystem.onBecomeLeader();
isLeader.set(true);
startBackgroundThreads();
LOG.info("star manager background threads start, now is leader.");
}
public void becomeFollower() {
journalSystem.onBecomeFollower();
isLeader.set(false);
stopBackgroundThreads();
LOG.info("star manager background threads stop, now is follower.");
}
public void startBackgroundThreads() {
shardScheduler.start();
shardChecker.start();
heartbeatManager.start();
}
public void stopBackgroundThreads() {
heartbeatManager.stop();
shardChecker.stop();
shardScheduler.stop();
}
public void registerService(String serviceTemplateName, List serviceComponents) throws StarException {
checkLeader();
serviceManager.registerService(serviceTemplateName, serviceComponents);
}
public void deregisterService(String serviceTemplateName) throws StarException {
checkLeader();
serviceManager.deregisterService(serviceTemplateName);
}
public String bootstrapService(String serviceTemplateName, String serviceName) throws StarException {
checkLeader();
String serviceId = serviceManager.bootstrapService(serviceTemplateName, serviceName);
workerManager.createDefaultServiceWorkerGroup(serviceId);
return serviceId;
}
public void shutdownService(String serviceId) throws StarException {
checkLeader();
serviceManager.shutdownService(serviceId);
}
public ServiceInfo getServiceInfoById(String serviceId) throws StarException {
return serviceManager.getServiceInfoById(serviceId);
}
public ServiceInfo getServiceInfoByName(String serviceName) throws StarException {
return serviceManager.getServiceInfoByName(serviceName);
}
public long addWorker(String serviceId, long groupId, String ipPort) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
long workerId = workerManager.addWorker(serviceId, groupId, ipPort);
return workerId;
}
}
public void removeWorker(String serviceId, long groupId, long workerId) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
workerManager.removeWorker(serviceId, groupId, workerId);
}
}
public WorkerInfo getWorkerInfo(String serviceId, long workerId) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
WorkerInfo workerInfo = workerManager.getWorkerInfo(workerId);
if (!workerInfo.getServiceId().equals(serviceId)) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("worker %d not belong to service %s.",
workerId, serviceId));
}
return workerInfo;
}
}
public WorkerInfo getWorkerInfo(String serviceId, String ipPort) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
WorkerInfo workerInfo = workerManager.getWorkerInfo(ipPort);
if (!workerInfo.getServiceId().equals(serviceId)) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("worker %s not belong to service %s.",
ipPort, serviceId));
}
return workerInfo;
}
}
public List createShard(String serviceId,
List createShardInfos) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.createShard(createShardInfos, fsMgrs);
}
}
public void deleteShard(String serviceId, List shardIds) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.deleteShard(shardIds);
// just let shard scheduler do remove shard, do nothing here
}
}
private List gatherWorkerInfoForShard(List shardInfos) throws StarException {
List shardInfosFinal = new ArrayList<>(shardInfos.size());
for (ShardInfo shardInfo : shardInfos) {
ShardInfo.Builder shardInfoBuilder = ShardInfo.newBuilder().mergeFrom(shardInfo);
shardInfoBuilder.clearReplicaInfo();
for (ReplicaInfo replicaInfo : shardInfo.getReplicaInfoList()) {
try {
WorkerInfo workerInfo = workerManager.getWorkerInfo(
replicaInfo.getWorkerInfo().getWorkerId());
ReplicaInfo replicaInfoFinal = ReplicaInfo.newBuilder()
.mergeFrom(replicaInfo)
.setWorkerInfo(workerInfo)
.build();
shardInfoBuilder.addReplicaInfo(replicaInfoFinal);
} catch (StarException e) {
if (e.getExceptionCode() == ExceptionCode.NOT_EXIST) {
// worker might already removed, but shard has stale replica info
} else {
throw e;
}
}
}
shardInfosFinal.add(shardInfoBuilder.build());
}
return shardInfosFinal;
}
public List getShardInfo(String serviceId, List shardIds) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
List shardInfos = gatherWorkerInfoForShard(shardManager.getShardInfo(shardIds));
return shardInfos;
}
}
public List listShardInfo(String serviceId, List groupIds) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
List> shardInfos = shardManager.listShardInfo(groupIds);
List shardInfoLists = new ArrayList<>(shardInfos.size());
for (List infos : shardInfos) {
ShardInfoList shardInfoList =
ShardInfoList.newBuilder().addAllShardInfos(gatherWorkerInfoForShard(infos)).build();
shardInfoLists.add(shardInfoList);
}
return shardInfoLists;
}
}
public List createShardGroup(String serviceId,
List createShardGroupInfos) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.createShardGroup(createShardGroupInfos);
}
}
public void deleteShardGroup(String serviceId, List groupIds, boolean deleteShards) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.deleteShardGroup(groupIds, deleteShards);
}
}
public List listShardGroupInfo(String serviceId, boolean includeAnonymousGroup) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.listShardGroupInfo(includeAnonymousGroup);
}
}
public MetaGroupInfo createMetaGroup(String serviceId, CreateMetaGroupInfo createMetaGroupInfo) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.createMetaGroup(createMetaGroupInfo);
}
}
public void deleteMetaGroup(String serviceId, long metaGroupId) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.deleteMetaGroup(metaGroupId);
}
}
public void updateMetaGroup(String serviceId, UpdateMetaGroupInfo updateMetaGroupInfo) throws StarException {
checkLeader();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.updateMetaGroup(updateMetaGroupInfo);
}
}
public MetaGroupInfo getMetaGroupInfo(String serviceId, long metaGroupId) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.getMetaGroupInfo(metaGroupId);
}
}
public List listMetaGroupInfo(String serviceId) throws StarException {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
return shardManager.listMetaGroupInfo();
}
}
public void processWorkerHeartbeat(String serviceId, long workerId, long startTime, Map workerProperties,
List shardIds) {
checkLeader();
long currentTime = System.currentTimeMillis();
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
LOG.debug("process heartbeat from worker {} for service {}.", workerId, serviceId);
boolean isRestart = workerManager.processWorkerHeartbeat(serviceId, workerId, startTime,
shardIds.size(), workerProperties, currentTime);
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
if (isRestart) {
shardManager.scheduleShardsBelongToWorker(workerId);
}
// validate and possibly remove invalid replicas from the worker
shardManager.validateWorkerReportedReplicas(shardIds, workerId);
}
}
public FilePathInfo allocateFilePath(String serviceId, FileStoreType fsType, String suffix) {
checkLeader();
FileStoreMgr fsMgr = fsMgrs.getFileStoreMgr(fsType);
if (fsMgr == null) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("invalid file store type %s", fsType));
}
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
throw new StarException(ExceptionCode.NOT_EXIST,
String.format("service %s not exist.", serviceId));
}
}
FileStore fs = fsMgr.allocFileStore();
FilePath fp = new FilePath(fs, String.format("%s/%s", serviceId, suffix));
return fp.toProtobuf();
}
public void addFileStore(FileStoreInfo fsInfo) throws StarException {
checkLeader();
FileStoreMgr fsMgr = fsMgrs.getFileStoreMgr(fsInfo.getFsType());
if (fsMgr == null) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("invalid file store type %s", fsInfo.getFsType()));
}
FileStore fs = fsMgr.newFsFromProtobuf(fsInfo);
fsMgr.addFileStore(fs);
}
public void removeFileStore(FileStoreInfo fsInfo) throws StarException {
checkLeader();
FileStoreMgr fsMgr = fsMgrs.getFileStoreMgr(fsInfo.getFsType());
if (fsMgr == null) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("invalid file store type %s", fsInfo.getFsType()));
}
fsMgr.removeFileStore(fsInfo.getFsKey());
}
public List listFileStore() throws StarException {
// TODO:(jeff.ding)
return new ArrayList();
}
public void updateFileStore(FileStoreInfo fsInfo) throws StarException {
checkLeader();
FileStoreMgr fsMgr = fsMgrs.getFileStoreMgr(fsInfo.getFsType());
if (fsMgr == null) {
throw new StarException(ExceptionCode.INVALID_ARGUMENT,
String.format("invalid file store type %s", fsInfo.getFsType()));
}
FileStore fs = fsMgr.newFsFromProtobuf(fsInfo);
fsMgr.updateFileStore(fs);
}
public ShardManager getShardManager(String serviceId) {
return serviceManager.getShardManager(serviceId);
}
// FOR TEST
public ServiceManager getServiceManager() {
return serviceManager;
}
// FOR TEST
public WorkerManager getWorkerManager() {
return workerManager;
}
// FOR TEST
public IdGenerator getIdGenerator() {
return idGenerator;
}
public void replay(Journal journal) {
journalReplayer.replay(journal);
}
public void replayRegisterService(ServiceTemplate serviceTemplate) {
serviceManager.replayRegisterService(serviceTemplate);
}
public void replayDeregisterService(String serviceTemplateName) {
serviceManager.replayDeregisterService(serviceTemplateName);
}
public void replayBootstrapService(Service service) {
serviceManager.replayBootstrapService(service);
workerManager.createDefaultServiceWorkerGroup(service.getServiceId());
}
public void replayShutdownService(Service service) {
serviceManager.replayShutdownService(service);
}
public void replayCreateShard(String serviceId, CreateShardJournalInfo info) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay create shard, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayCreateShard(info);
}
}
public void replayDeleteShard(String serviceId, List shardIds) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay delete shard, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayDeleteShard(shardIds);
}
}
public void replayUpdateShard(String serviceId, List shards) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay update shard, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayUpdateShard(shards);
}
}
public void replayCreateShardGroup(String serviceId, List shardGroups) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay create shard group, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayCreateShardGroup(shardGroups);
}
}
public void replayDeleteShardGroup(String serviceId, DeleteShardGroupInfo info) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay delete shard group, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayDeleteShardGroup(info);
}
}
public void replayCreateMetaGroup(String serviceId, MetaGroupJournalInfo info) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay create meta group, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayCreateMetaGroup(info);
}
}
public void replayDeleteMetaGroup(String serviceId, MetaGroupJournalInfo info) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay delete meta group, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayDeleteMetaGroup(info);
}
}
public void replayUpdateMetaGroup(String serviceId, MetaGroupJournalInfo info) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay update meta group, should not happen!", serviceId);
}
ShardManager shardManager = getShardManager(serviceId);
assert shardManager != null;
shardManager.replayUpdateMetaGroup(info);
}
}
public void replayAddWorker(String serviceId, Worker worker) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay add worker, should not happen!", serviceId);
}
workerManager.replayAddWorker(serviceId, worker);
}
}
public void replayUpdateWorker(String serviceId, List workers) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay update worker, should not happen!", serviceId);
}
workerManager.replayUpdateWorker(serviceId, workers);
}
}
public void replayRemoveWorker(String serviceId, long groupId, long workerId) {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
if (!serviceManager.existService(serviceId)) {
LogUtils.fatal(LOG, "service {} not exist when replay remove worker, should not happen!", serviceId);
}
workerManager.replayRemoveWorker(serviceId, groupId, workerId);
}
}
public void replaySetId(long id) {
idGenerator.setNextId(id);
}
// WARNING: BE VERY CAREFUL ABOUT THIS FUNCTION!
// for durability purpose
// stream like dump method to decrease memory consumption
// NOTE: does not support strong consistency
public void dumpMeta(DataOutputStream out) throws IOException {
LOG.info("start dump star manager meta data to file.");
// write raw header
out.write(FILE_META_RAW_HEADER.getBytes(StandardCharsets.UTF_8));
// write header
StarManagerFileMetaHeader header = StarManagerFileMetaHeader.newBuilder()
.setGenerateTime(System.currentTimeMillis())
.setReplayJournalId(journalSystem.getReplayId())
.setNextGlobalId(idGenerator.getNextPersistentId())
.build();
byte[] hbytes = header.toByteArray();
Text.writeBytes(out, hbytes);
// write each component, DO NOT changed order
serviceManager.dumpMeta(out);
workerManager.dumpMeta(out);
// write holder, holder is used for compatibility, if there is any other
// new meta, can put it in holder
out.writeInt(0); // currently there is none
// StarManagerFileMetaHolder holder = StarManagerFileMetaHolder.newBuilder().build();
// write footer
StarManagerFileMetaFooter footer = StarManagerFileMetaFooter.newBuilder().build();
byte[] fbytes = header.toByteArray();
Text.writeBytes(out, fbytes);
LOG.info("end dump star manager meta data to file.");
}
// called by loadMeta, prepare default group for worker
public void prepareDefaultGroup() {
try (LockCloseable lock = new LockCloseable(serviceManager.readLock())) {
Set serviceIds = serviceManager.getServiceIdSet();
for (String serviceId : serviceIds) {
workerManager.createDefaultServiceWorkerGroup(serviceId);
}
}
}
// WARNING: BE VERY CAREFUL ABOUT THIS FUNCTION!
public void loadMeta(DataInputStream in) throws IOException {
LOG.info("start load star manager meta data from file.");
if (in.available() == 0) {
LOG.warn("load star manager meta data found empty stream, do nothing.");
return;
}
// read raw header
int size = FILE_META_RAW_HEADER.getBytes(StandardCharsets.UTF_8).length;
byte[] bytes = new byte[size];
in.readFully(bytes, 0, size);
String copy = new String(bytes, StandardCharsets.UTF_8);
if (!copy.equals(FILE_META_RAW_HEADER)) {
throw new IOException("verify star manager meta file raw header failed, meta is not valid.");
}
// read header
byte[] hbytes = Text.readBytes(in);
StarManagerFileMetaHeader header = StarManagerFileMetaHeader.parseFrom(hbytes);
long generateTime = header.getGenerateTime();
long replayJournalId = header.getReplayJournalId();
long nextGlobalId = header.getNextGlobalId();
journalSystem.setReplayId(replayJournalId);
idGenerator.setNextId(nextGlobalId);
// read each component, DO NOT change order
serviceManager.loadMeta(in);
prepareDefaultGroup();
workerManager.loadMeta(in);
// read holder
int holderCount = in.readInt();
for (int i = 0; i < holderCount; ++i) {
byte[] b = Text.readBytes(in);
StarManagerFileMetaHolder holder = StarManagerFileMetaHolder.parseFrom(b);
// do nothing now
}
// read footer
byte[] fbytes = Text.readBytes(in);
StarManagerFileMetaFooter footer = StarManagerFileMetaFooter.parseFrom(fbytes);
LOG.info("end load star manager meta data from file generated at {}, replay journal id {}.",
new SimpleDateFormat("MM-dd HH:mm:ss").format(new Date(generateTime)), replayJournalId);
}
// for debug purpose, dump human readable json meta
public String dump() throws IOException {
String name = "star_manager_meta";
File file = new File(name);
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
serviceManager.dump(dos);
workerManager.dump(dos);
return Config.STARMGR_IP + ":" + file.getAbsolutePath();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy