Nifi 1.2.0。
在自定义处理器中,LSN用于从SQL Server数据库表中获取数据。
以下是用于以下代码的代码段:
存储键值对
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());
}
当此处理器的单个实例正在运行时,LSN将被正确存储和检索,并且从SQL Server表中获取数据的逻辑可以正常工作。
根据NiFi文件。关于国家管理:
使用StateManager存储和检索状态 getState,setState,replace和clear方法。所有这些方法 要求提供范围。应该指出的是国家 与Local范围一起存储的内容与state完全不同 与Cluster范围一起存储。如果处理器存储了一个值 使用Scope.CLUSTER范围的My Key键,然后尝试 使用Scope.LOCAL范围检索值,检索值 将为null(除非使用相同的密钥存储值 Scope.CLUSTER范围)。每个处理器的状态都存储在 与其他处理器的状态隔离。
当此处理器的两个实例正在运行时,只有一个能够获取数据。这导致了以下问题:
StateMap是一个'全局映射',它必须在同一个处理器的实例上以及不同处理器的实例中具有唯一键吗?简单来说,只要处理器将密钥置于statemap,密钥在NiFi处理器(以及使用State API的其他服务,如果有的话)中应该是唯一的?如果是的话,任何人都可以建议我在我的案例中使用哪种独特的密钥吗?
注意:我快速浏览了标准的MySQL CDC处理器代码类(CaptureChangeMySQL.java),它有一个类似的逻辑来存储和检索状态但是我忽略了什么?
答案 0 :(得分:1)
处理器的StateMap存储在组件的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-22222-2222是处理器2的UUID。因此StateMap中的键不必在所有实例中是唯一的因为它们的范围是每个组件ID。
在群集中,每个组件的组件ID在所有节点上都相同。因此,如果您有一个3节点集群且处理器1具有id 1111-1111-1111-1111,则每个节点上都有一个具有该id的处理器。
如果该处理器被安排在所有节点上运行并存储集群状态,那么处理器的所有三个实例将在集群状态提供程序(ZooKeeper)中更新相同的StateMap。