Numeric NodeId vs. String NodeId

Unified Architecture topics related to OPC UA Specification, compliant behavior and any technical issues of OPC UA, like Security, Information Model, Companion Specs DI, PLCopen, ADI, ...

Moderator: Support Team

Post Reply
kurt
Sr. Member
Sr. Member
Posts: 13
Joined: 17 Apr 2012, 09:01

Numeric NodeId vs. String NodeId

Post by kurt »

Hi support team,

we are unsure about the decision between numeric node ids or string node ids.

For performance reasons we decided to use numeric ids. However because in our UA server implementation the numeric ids are recalculated on each run it is possible that a node id might change after a server restart for logically the same node.

Is this implementation correct or should we use string ids instead, holding the logical name of the node?

Best regards
Kurt

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re:Numeric NodeId vs. String NodeId

Post by Support Team »

Hi Kurt,

The first and most important rule is that NodeIds are not allowed to change on server restart if the node is logically still the same. This will be a major problem for most real OPC UA clients since they will persist the NodeIds during configuration and will reuse them later on. This is typical for HMI clients.

Numeric NodeIds are used for static nodes that do not change e.g. for type systems, generated code or nodes baked into a firmware of an embedded device. The UaModeler is using numeric NodeIds for the generated code.

String NodeIds are used for dynamic systems since it is normally easy to recalculate the same NodeId at every server start based on names in the hierarchy.

GUID NodeIds are used if it must be ensured that they are globally unique.

OPC UA provides the services RegisterNodes and UnregisterNodes to optimize access to nodes. A server should return numeric NodeIds as the registered NodeIds to optimize access. The C++ and .NET SDK are doing this automatically. There is nothing you need to implement for this feature in a C++ or .NET SDK based server.

Best Regards
Unified Automation Support Team
Best regards
Unified Automation Support Team

zanettea
Jr. Member
Jr. Member
Posts: 1
Joined: 23 Feb 2015, 11:07

Re: Numeric NodeId vs. String NodeId

Post by zanettea »

Dear support team,
I am experiencing a performance issue related to (String) NodeIds in particularly creating alarm nodes.

Indeed internally the alarm nodes provide a lot of instance-declared properties (class UaVariableAttributesInstanceDeclaration).
The implentation of nodeId method for these objects does not provide any caching/reference counting since the nodeId is recomputed every time the function is called as a brand new string:

Code: Select all

#if USE_MEMORY_OPTIMIZED_PARENT_POINTER
    return UaNodeId(UaString("%1.%2").arg(m_pParentNode->nodeId().toString()).arg(m_pVariable->browseName().toString()), m_pParentNode->nodeId().namespaceIndex());
#else // USE_MEMORY_OPTIMIZED_PARENT_POINTER
    return m_nodeId;
#endif // USE_MEMORY_OPTIMIZED_PARENT_POINTER
So when it comes to add a new node to the nodemanager and the hash table of nodes needs to be looked up I can observe a storm of calls to the above very ineffient nodeId() implementation and the net result is an unacceptable loading time (up to minutes in our embedded target for 2000 alarms).

Is it safe to unset the define USE_MEMORY_OPTIMIZED_PARENT_POINTER ? What kind of side effects can I expect? Is there any other cleaner solution?

Best Regards,
Arrigo

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Numeric NodeId vs. String NodeId

Post by Support Team »

Hello zanettea,

This is just a way to optimise memory consumption for InstanceDeclarationNodes by storing the parent pointer instead of the NodeId and generate the NodeId on the fly whenever it is needed. You can savely change the setting to OPCUA_CONFIG_NO.
Best regards
Unified Automation Support Team

fabian727
Jr. Member
Jr. Member
Posts: 3
Joined: 22 Jun 2018, 10:06

Re: Numeric NodeId vs. String NodeId

Post by fabian727 »

Numeric NodeIds are used for static nodes that do not change e.g. for type systems, generated code or nodes baked into a firmware of an embedded device. The UaModeler is using numeric NodeIds for the generated code.

String NodeIds are used for dynamic systems since it is normally easy to recalculate the same NodeId at every server start based on names in the hierarchy.

GUID NodeIds are used if it must be ensured that they are globally unique.
In which specification is written down, that I have to use StringIds (and I am not allowed to use NumercIds) for dynamic Nodes and numeric NodeIds for static? I only found the line saying that IDs are not allowed to change for static Nodes.

for GUID:
Is there a way to copy from uint32 and uint16 to the GUID NodeId and not with the UAString. This is one more unneeded step. (I am using the newest UA SDK Cpp)

Thanks,

Fabian

User avatar
Support Team
Hero Member
Hero Member
Posts: 3064
Joined: 18 Mar 2011, 15:09

Re: Numeric NodeId vs. String NodeId

Post by Support Team »

The above text are recommendations and guidelines, not rules.

OPC UA Part 3 (5.2.2 NodeId) states:
A Server shall persist the NodeId of a Node, that is, it shall not generate new NodeIds when rebooting.

This implies that you need to be able to use the exact same NodeId during the lifetime of a Node in a system. If you can ensure this for numeric identifiers in dynamic systems, you can use numeric identifiers.
Best regards
Unified Automation Support Team

daniel.barral
Jr. Member
Jr. Member
Posts: 1
Joined: 16 Nov 2021, 11:04

Re: Numeric NodeId vs. String NodeId

Post by daniel.barral »

Hi support Team,

I have a question with regards zanetta's post about USE_MEMORY_OPTIMIZED_PARENT_POINTER
in post https://forum.unified-automation.com/viewtopic.php?p=4096#p4096 above

We are experiencing similar problems in our embedded target using C++ SDK 1.5.6.361:

- The creation of 2000 alarms nodes of type derived from OpcUa::OffNormalAlarmType takes 10x longer than required to create 2000 variable nodes of type derived from OpcUa::AnalogItemType.

- When we increase the number of alarm nodes to 4000, the time required to create them far exceeds 5 minutes, and the target experiences memory fragmentation issues which render it unusable.

Inspecting SDK sources, I find two defines

In src/uaserver/uaservercpp/coremodule/opcua_basevariabletype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_YES

And in src/uaserver/uaservercpp/coremodule/opcua_baseobjecttype.cpp
#define USE_MEMORY_OPTIMIZED_PARENT_POINTER OPCUA_CONFIG_NO

Setting to OPCUA_CONFIG_YES in opcua_baseobjecttype.cpp breaks build, because the code now uses a pointer to parent node which, as opposed to BaseVariableType, is not an argument in ctor.

I wonder:

- Do newer versions of the SDK enable changing this setting?

- If enabled, might it make our memory fragmentation problem less severe?

Regards,
Daniel Barral

Post Reply