import org.apache.flink.api.common.time.Time;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.contrib.streaming.state.RocksDBStateBackend;
import org.apache.flink.runtime.state.StateBackend;
import org.apache.flink.runtime.state.filesystem.FsStateBackend;
import org.apache.flink.streaming.api.CheckpointingMode;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.environment.CheckpointConfig;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.TableConfig;
import org.apache.flink.table.api.java.BatchTableEnvironment;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.util.TernaryBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FlinkEnvironment {
private static final Logger LOG = LoggerFactory.getLogger(FlinkEnvironment.class);
private Config config;
private StreamExecutionEnvironment environment;
private StreamTableEnvironment tableEnvironment;
private ExecutionEnvironment batchEnvironment;
private BatchTableEnvironment batchTableEnvironment;
private boolean isStreaming;
private String jobName = "******";
public void setConfig(Config config) {
this.config = config;
}
public Config getConfig() {
return config;
}
public CheckResult checkConfig() {
return checkRestartStrategy(config);
}
public static CheckResult checkRestartStrategy(Config config){
if (config.hasPath(ConfigKeyName.RESTART_STRATEGY)) {
String restartStrategy = config.getString(ConfigKeyName.RESTART_STRATEGY);
switch (restartStrategy.toLowerCase()) {
case "fixed-delay":
if (!(config.hasPath(ConfigKeyName.RESTART_ATTEMPTS)
&& config.hasPath(ConfigKeyName.RESTART_DELAY_BETWEEN_ATTEMPTS))) {
return new CheckResult(false, String.format("fixed-delay restart strategy must set [%s],[%s]"
, ConfigKeyName.RESTART_ATTEMPTS, ConfigKeyName.RESTART_DELAY_BETWEEN_ATTEMPTS));
}
break;
case "failure-rate":
if (!(config.hasPath(ConfigKeyName.RESTART_FAILURE_INTERVAL)
&& config.hasPath(ConfigKeyName.RESTART_FAILURE_RATE)
&& config.hasPath(ConfigKeyName.RESTART_DELAY_INTERVAL))) {
return new CheckResult(false, String.format("failure-rate restart strategy must set [%s],[%s],[%s]"
, ConfigKeyName.RESTART_FAILURE_INTERVAL, ConfigKeyName.RESTART_FAILURE_RATE, ConfigKeyName.RESTART_DELAY_INTERVAL));
}
break;
default:
return new CheckResult(true, "");
}
}
return new CheckResult(true,"");
}
public void prepare(Boolean isStreaming) {
this.isStreaming = isStreaming;
if (isStreaming) {
createStreamEnvironment();
createStreamTableEnvironment();
} else {
createBatchTableEnvironment();
createExecutionEnvironment();
}
if (config.hasPath("job.name")){
jobName = config.getString("job.name");
}
}
public String getJobName() {
return jobName;
}
public boolean isStreaming() {
return isStreaming;
}
public StreamExecutionEnvironment getStreamExecutionEnvironment() {
return environment;
}
public StreamTableEnvironment getStreamTableEnvironment() {
return tableEnvironment;
}
private void createStreamTableEnvironment() {
tableEnvironment = StreamTableEnvironment.create(getStreamExecutionEnvironment());
TableConfig config = tableEnvironment.getConfig();
if (this.config.hasPath(ConfigKeyName.MAX_STATE_RETENTION_TIME) && this.config.hasPath(ConfigKeyName.MIN_STATE_RETENTION_TIME)){
long max = this.config.getLong(ConfigKeyName.MAX_STATE_RETENTION_TIME);
long min = this.config.getLong(ConfigKeyName.MIN_STATE_RETENTION_TIME);
config.setIdleStateRetentionTime(Time.seconds(min),Time.seconds(max));
}
}
private void createStreamEnvironment() {
environment = StreamExecutionEnvironment.getExecutionEnvironment();
setTimeCharacteristic();
setCheckpoint();
EnvironmentUtil.setRestartStrategy(config,environment.getConfig());
if (config.hasPath(ConfigKeyName.BUFFER_TIMEOUT_MILLIS)) {
long timeout = config.getLong(ConfigKeyName.BUFFER_TIMEOUT_MILLIS);
environment.setBufferTimeout(timeout);
}
if (config.hasPath(ConfigKeyName.PARALLELISM)) {
int parallelism = config.getInt(ConfigKeyName.PARALLELISM);
environment.setParallelism(parallelism);
}
if (config.hasPath(ConfigKeyName.MAX_PARALLELISM)) {
int max = config.getInt(ConfigKeyName.MAX_PARALLELISM);
environment.setMaxParallelism(max);
}
}
public ExecutionEnvironment getBatchEnvironment() {
return batchEnvironment;
}
public BatchTableEnvironment getBatchTableEnvironment() {
return batchTableEnvironment;
}
private void createExecutionEnvironment() {
batchEnvironment = ExecutionEnvironment.getExecutionEnvironment();
if (config.hasPath(ConfigKeyName.PARALLELISM)) {
int parallelism = config.getInt(ConfigKeyName.PARALLELISM);
batchEnvironment.setParallelism(parallelism);
}
EnvironmentUtil.setRestartStrategy(config, batchEnvironment.getConfig());
}
private void createBatchTableEnvironment() {
batchTableEnvironment = BatchTableEnvironment.create(batchEnvironment);
}
private void setTimeCharacteristic() {
if (config.hasPath(ConfigKeyName.TIME_CHARACTERISTIC)) {
String timeType = config.getString(ConfigKeyName.TIME_CHARACTERISTIC);
switch (timeType.toLowerCase()) {
case "event-time":
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
break;
case "ingestion-time":
environment.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);
break;
case "processing-time":
environment.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);
break;
default:
LOG.warn("set time-characteristic failed, unknown time-characteristic [{}],only support event-time,ingestion-time,processing-time", timeType);
break;
}
}
}
private void setCheckpoint() {
if (config.hasPath(ConfigKeyName.CHECKPOINT_INTERVAL)) {
CheckpointConfig checkpointConfig = environment.getCheckpointConfig();
long interval = config.getLong(ConfigKeyName.CHECKPOINT_INTERVAL);
environment.enableCheckpointing(interval);
if (config.hasPath(ConfigKeyName.CHECKPOINT_MODE)) {
String mode = config.getString(ConfigKeyName.CHECKPOINT_MODE);
switch (mode.toLowerCase()) {
case "exactly-once":
checkpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
break;
case "at-least-once":
checkpointConfig.setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE);
break;
default:
LOG.warn("set checkpoint.mode failed, unknown checkpoint.mode [{}],only support exactly-once,at-least-once", mode);
break;
}
}
if (config.hasPath(ConfigKeyName.CHECKPOINT_TIMEOUT)) {
long timeout = config.getLong(ConfigKeyName.CHECKPOINT_TIMEOUT);
checkpointConfig.setCheckpointTimeout(timeout);
}
if (config.hasPath(ConfigKeyName.CHECKPOINT_DATA_URI)) {
String uri = config.getString(ConfigKeyName.CHECKPOINT_DATA_URI);
StateBackend fsStateBackend = new FsStateBackend(uri);
if (config.hasPath(ConfigKeyName.STATE_BACKEND)){
String stateBackend = config.getString(ConfigKeyName.STATE_BACKEND);
if ("rocksdb".equals(stateBackend.toLowerCase())){
StateBackend rocksDBStateBackend = new RocksDBStateBackend(fsStateBackend, TernaryBoolean.TRUE);
environment.setStateBackend(rocksDBStateBackend);
}
}else {
environment.setStateBackend(fsStateBackend);
}
}
if (config.hasPath(ConfigKeyName.MAX_CONCURRENT_CHECKPOINTS)) {
int max = config.getInt(ConfigKeyName.MAX_CONCURRENT_CHECKPOINTS);
checkpointConfig.setMaxConcurrentCheckpoints(max);
}
if (config.hasPath(ConfigKeyName.CHECKPOINT_CLEANUP_MODE)) {
boolean cleanup = config.getBoolean(ConfigKeyName.CHECKPOINT_CLEANUP_MODE);
if (cleanup) {
checkpointConfig.enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.DELETE_ON_CANCELLATION);
} else {
checkpointConfig.enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
}
}
if (config.hasPath(ConfigKeyName.MIN_PAUSE_BETWEEN_CHECKPOINTS)) {
long minPause = config.getLong(ConfigKeyName.MIN_PAUSE_BETWEEN_CHECKPOINTS);
checkpointConfig.setMinPauseBetweenCheckpoints(minPause);
}
if (config.hasPath(ConfigKeyName.FAIL_ON_CHECKPOINTING_ERRORS)) {
int failNum = config.getInt(ConfigKeyName.FAIL_ON_CHECKPOINTING_ERRORS);
checkpointConfig.setTolerableCheckpointFailureNumber(failNum);
}
}
}
}