Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance[MQBSTAT]: lookup for per-appId metrics O(n) -> O(1) #389

Merged
merged 5 commits into from
Aug 13, 2024

Conversation

678098
Copy link
Collaborator

@678098 678098 commented Aug 5, 2024

Previously, we used a bsl::list<ManagedPtr<mwcst::StatContext> > for 2 roles:

  • Store managed pointers to subcontexts associated with appIds
  • Lookup to subcontexts for each specific appId

The problem is that the list assumes linear search, which might be too slow if we have a decent number of appIds.

However, due to the interfaces of ManagedPtr (on Solaris), we cannot just use a container which might reallocate its elements on resize. So instead we keep&update 2 collections together: bsl::list to hold ManagedPointers and bsl::unordered_map for fast lookup to raw pointers to the needed StatContexts

Full list of changes:

  • mqbstat::QueueStatsDomain: hold managed pointers in bsl::list<StatSubContextMp> d_subContextsHolder, lookup to subcontexts with bsl::unordered_map<bsl::string, mwcst::StatContext*> d_subContextsLookup
  • mqbstat::QueueStatsDomain: pass allocator in constructor
  • mqbstat::QueueStatsDomain: improve logging when no subcontext found
  • mqbc::ClusterDataIdentity: add safety check to prevent possible nullptr dereference
  • mqbmock::Cluster: add safety checks to find cluster misconfiguration early
  • mqbstat_queuestats.t.cpp: add UT to check per-appId subcontexts and metrics

@678098 678098 requested a review from a team as a code owner August 5, 2024 21:40
@678098 678098 force-pushed the 240803_rm_list_search branch from 2a9f237 to 98af0da Compare August 6, 2024 02:23
@@ -53,6 +53,8 @@ mqbc::ClusterDataIdentity clusterIdentity(const bslstl::StringRef& name,
// Create client identity
bmqp_ctrlmsg::ClientIdentity identity(allocator);
if (!isRemote) {
BSLS_ASSERT_SAFE(netCluster->selfNode());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the line 65 below, netCluster->selfNode() is dereferenced without checks, which might lead to segfault. This might be achieved by using mock domain/cluster objects.

@@ -156,6 +156,10 @@ void Cluster::_initializeNetcluster()
: k_LEADER_NODE_ID + 1;
dynamic_cast<mqbnet::MockCluster*>(d_netCluster_mp.get())
->_setSelfNodeId(selfNodeId);

if (d_isClusterMember) {
BSLS_ASSERT_OPT(0 != d_netCluster_mp->selfNode());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another early safety check for the same problem with dereferencing selfNode with mocks.

@@ -231,7 +235,12 @@ Cluster::Cluster(bdlbb::BlobBufferFactory* bufferFactory,
, d_processor()
{
// PRECONDITIONS
BSLS_ASSERT_OPT(isClusterMember || !isLeader);
if (isClusterMember) {
BSLS_ASSERT_OPT(!clusterNodeDefs.empty());
Copy link
Collaborator Author

@678098 678098 Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Early safety check. Providing an empty clusterNodeDefs makes it certain that selfNode will be nullptr.

BALL_LOGTHROTTLE_WARN(k_MAX_INSTANT_MESSAGES, k_NS_PER_MESSAGE)
<< "[THROTTLED] No built sub contexts";
<< "[THROTTLED] No built sub contexts for domain: "
<< d_statContext_mp->name() << ", appId: " << appId;
Copy link
Collaborator Author

@678098 678098 Aug 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New log line looks like
06AUG2024_02:21:59.442 10822:8281000960 WARN /blazingmq/src/groups/mqb/mqbstat/mqbstat_queuestats.cpp:602 MQBSTAT.QUEUESTATS [THROTTLED] No matching StatContext for domain: bmq://mock-domain/abc, appId: bar

Signed-off-by: Evgeny Malygin <[email protected]>
@kaikulimu
Copy link
Collaborator

However, due to the interfaces of ManagedPtr (on Solaris), we cannot just use a container which might reallocate its elements on resize.

Do you have source to this statement? It is quite inconvenient to have to use two data structures.

Copy link
Collaborator

@kaikulimu kaikulimu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments

src/groups/mqb/mqbstat/mqbstat_queuestats.cpp Outdated Show resolved Hide resolved
Signed-off-by: Evgeny Malygin <[email protected]>
@678098 678098 force-pushed the 240803_rm_list_search branch from 7eb93fc to f13b4cb Compare August 12, 2024 17:13
@678098
Copy link
Collaborator Author

678098 commented Aug 12, 2024

Do you have source to this statement? It is quite inconvenient to have to use two data structures.

@kaikulimu ManagedPtr docs
https://bloomberg.github.io/bde-resources/doxygen/bde_api_prod/bslma__managedptr_8h_source.html

However, like 'bsl::auto_ptr' it has unusual "copy-semantics" that transfer ownership of the managed object, rather than making a copy. It should be noted that this signature does not satisfy the requirements for an element-type stored in any of the standard library containers.

So ManagedPtr doesn't satisfy the CopyConstructible requirements https://en.cppreference.com/w/cpp/named_req/CopyConstructible

On SunOS, trying to build a bsl::unordered_map<bsl::string, bslma::ManagedPtr<...> > will cause compilation errors, so as with other container types which rely on reallocating its elements.

2024-08-07 13:57:33 | "/opt/bb/include/bslstl_pair.h", line 2528: Error: Could not find a match for BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>::ManagedPtr<MANAGED_TYPE>(const BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>) needed in void bsl::Pair_Second<BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>>::Pair_Second<BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>>(const BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>&, BloombergLP::bslma::Allocator*, bsl::integral_constant<int, 0>).
2024-08-07 13:57:33 | "/opt/bb/include/bslstl_pair.h", line 2792: Where: While instantiating "void bsl::Pair_Second<BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>>::Pair_Second<BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>>(const BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>&, BloombergLP::bslma::Allocator*, bsl::integral_constant<int, 0>)".
2024-08-07 13:57:33 | "/opt/bb/include/bslstl_pair.h", line 2792: Where: Instantiated from bsl::pair<const bsl::basic_string<char, std::char_traits<char>, bsl::allocator<char>>, BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>>::pair(const bsl::basic_string<char, std::char_traits<char>, bsl::allocator<char>>&, const BloombergLP::bslma::ManagedPtr<BloombergLP::mwcst::StatContext>&, BloombergLP::bslma::Allocator*).
2024-08-07 13:57:33 | "/opt/bb/include/bslma_constructionutil_cpp03.h", line 9370: Where: Instantiated from static void bsl::allocator_traits<bsl::allocator<long double>>::construct<bsl::pair<const bsl::basic_string<char, std::char_traits<char>, bsl::allocator<char>>,

The first message could be simplified:
Error: Could not find a match for ManagedPtr<StatContext>::ManagedPtr<MANAGED_TYPE>(const ManagedPtr<StatContext>)

If you check the ManagedPtr interfaces, there are no constructors accepting other ManagedPtrs qualified as const
https://bloomberg.github.io/bde-resources/doxygen/bde_api_prod/classbslma_1_1ManagedPtr.html

Copy link
Collaborator

@kaikulimu kaikulimu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@678098 678098 merged commit a6a6cef into bloomberg:main Aug 13, 2024
29 checks passed
@678098 678098 deleted the 240803_rm_list_search branch August 13, 2024 00:29
alexander-e1off pushed a commit to alexander-e1off/blazingmq that referenced this pull request Oct 24, 2024
alexander-e1off pushed a commit to alexander-e1off/blazingmq that referenced this pull request Oct 24, 2024
alexander-e1off pushed a commit to alexander-e1off/blazingmq that referenced this pull request Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants