Apache nifi 同一处理器的不同实例之间的状态映射键

Apache nifi 同一处理器的不同实例之间的状态映射键,apache-nifi,Apache Nifi,Nifi 1.2.0 在自定义处理器中,LSN用于从SQL Server db表获取数据 以下是用于以下目的的代码片段: 存储键值对 final StateManager stateManager = context.getStateManager(); try { StateMap stateMap = stateManager.getState(Scope.CLUSTER); final Map<String, String> newStateMapProperties = ne

Nifi 1.2.0

在自定义处理器中,LSN用于从SQL Server db表获取数据

以下是用于以下目的的代码片段:

存储键值对

final StateManager stateManager = context.getStateManager();
try {
StateMap stateMap = stateManager.getState(Scope.CLUSTER);
final Map<String, String> newStateMapProperties = new HashMap<>();

String lsnUsedDuringLastLoadStr = Base64.getEncoder().encodeToString(lsnUsedDuringLastLoad);
//Just a constant String used as key
newStateMapProperties.put(ProcessorConstants.LAST_MAX_LSN, lsnUsedDuringLastLoadStr);


if (stateMap.getVersion() == -1) {
stateManager.setState(newStateMapProperties, Scope.CLUSTER);
} else {
stateManager.replace(stateMap, newStateMapProperties, Scope.CLUSTER);
}
}
final StateManager stateManager = context.getStateManager();
final StateMap stateMap;
final Map<String, String> stateMapProperties;
byte[] lastMaxLSN = null;
try {
stateMap = stateManager.getState(Scope.CLUSTER);
stateMapProperties = new HashMap<>(stateMap.toMap());

lastMaxLSN = (stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN) == null
|| stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN).isEmpty()) ? null
: Base64.getDecoder()
.decode(stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN).getBytes());
}
final StateManager StateManager=context.getStateManager();
试一试{
StateMap StateMap=stateManager.getState(Scope.CLUSTER);
final Map newStateMapProperties=new HashMap();
字符串lsnUsedDuringLastLoadStr=Base64.getEncoder().encodeToString(lsnUsedDuringLastLoad);
//只是一个用作键的常量字符串
newStateMapProperties.put(ProcessorConstants.LAST_MAX_LSN,lsnUsedDuringLastLoadStr);
if(stateMap.getVersion()=-1){
stateManager.setState(newStateMapProperties,Scope.CLUSTER);
}否则{
replace(stateMap、newStateMapProperties、Scope.CLUSTER);
}
}
检索键值对

final StateManager stateManager = context.getStateManager();
try {
StateMap stateMap = stateManager.getState(Scope.CLUSTER);
final Map<String, String> newStateMapProperties = new HashMap<>();

String lsnUsedDuringLastLoadStr = Base64.getEncoder().encodeToString(lsnUsedDuringLastLoad);
//Just a constant String used as key
newStateMapProperties.put(ProcessorConstants.LAST_MAX_LSN, lsnUsedDuringLastLoadStr);


if (stateMap.getVersion() == -1) {
stateManager.setState(newStateMapProperties, Scope.CLUSTER);
} else {
stateManager.replace(stateMap, newStateMapProperties, Scope.CLUSTER);
}
}
final StateManager stateManager = context.getStateManager();
final StateMap stateMap;
final Map<String, String> stateMapProperties;
byte[] lastMaxLSN = null;
try {
stateMap = stateManager.getState(Scope.CLUSTER);
stateMapProperties = new HashMap<>(stateMap.toMap());

lastMaxLSN = (stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN) == null
|| stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN).isEmpty()) ? null
: Base64.getDecoder()
.decode(stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN).getBytes());
}
final StateManager StateManager=context.getStateManager();
最终状态图状态图;
最终地图状态映射属性;
字节[]lastMaxLSN=null;
试一试{
stateMap=stateManager.getState(Scope.CLUSTER);
stateMapProperties=newHashMap(stateMap.toMap());
lastMaxLSN=(stateMapProperties.get(ProcessorConstants.LAST\u MAX\u LSN)=null
||stateMapProperties.get(ProcessorConstants.LAST\u MAX\u LSN.isEmpty())为空
:Base64.getDecoder()
.decode(stateMapProperties.get(ProcessorConstants.LAST_MAX_LSN.getBytes());
}
当此处理器的单个实例运行时,LSN被正确地存储和检索,并且从SQL Server表获取数据的逻辑工作正常

根据NiFi文件。关于国家管理:

存储和检索状态状态使用StateManager的 getState、setState、replace和clear方法。所有这些方法 要求提供一个范围。应当指出,国家 与本地作用域一起存储的状态与状态完全不同 与群集作用域一起存储。如果处理器使用 使用Scope.CLUSTER作用域的My key的键,然后尝试 使用Scope.LOCAL范围检索值,即检索到的值 将为null(除非使用相同的键存储了值 Scope.CLUSTER范围)。每个处理器的状态都存储在 与其他处理器的状态隔离

当此处理器的两个实例正在运行时,只有一个能够获取数据。这导致了以下问题:

StateMap是一个“全局映射”吗?它必须在同一处理器的实例和不同处理器的实例之间具有唯一的键?简单地说,每当处理器在StateMap中放置键时,该键在NiFi处理器(以及使用状态API的其他服务,如果有的话)之间应该是唯一的?如果是,有人能建议我在我的案例中应该使用什么唯一的密钥吗


注意:我快速浏览了标准的MySQL CDC处理器代码类(CaptureChangeMySQL.java),它有一个类似的逻辑来存储和检索状态,但我是否忽略了什么?

处理器的状态图存储在组件的id下面,因此,如果您有两个相同类型处理器的实例(这意味着您可以在画布上看到两个处理器),您将有如下结果:

/components/1111-1111-1111-1111 -> serialized state map
/components/2222-2222-2222-2222 -> serialized state map
假设1111-1111-1111-1111是处理器1的UUID,2222-2222-2222是处理器2的UUID。因此,状态映射中的键不必在所有实例中都是唯一的,因为它们的作用域是根据组件id确定的

在集群中,每个组件的组件id在所有节点上都是相同的。因此,如果您有一个3节点集群,并且处理器1的id为1111-1111-1111-1111,那么每个节点上都有一个具有该id的处理器


如果该处理器计划在所有节点上运行并存储群集状态,那么该处理器的所有三个实例都将在群集状态提供程序(ZooKeeper)中更新相同的状态映射。

那么,我相信,无论是相同处理器的n个实例还是不同处理器的n个实例,键值对是“隔离的”。在这种情况下,您能猜出我提到的两个处理器实例中可能出现的错误吗?