From: Dhairya Parmar Date: Tue, 21 Mar 2023 12:02:37 +0000 (+0530) Subject: mds: do not evict client on laggy osds X-Git-Tag: v17.2.8~557^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=73aa1ced8ce7f19154f0fa28d0664ba1c0328216;p=ceph.git mds: do not evict client on laggy osds A client might get unresponsive/laggy due to laggy OSD(s). This change provides us a way to defer client eviction in such scenarios also adds helpers: - get_laggy_clients() - clear_laggy_clients() and call clear_laggy_clients() before calling related Server methods Fixes: https://tracker.ceph.com/issues/58023 Signed-off-by: Dhairya Parmar (cherry picked from commit 31a8d03a2ea3f65dc946c2ba0be9921a2087801f) --- diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 8d41a4678f8..c14244a3521 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -743,6 +743,7 @@ void MDSRankDispatcher::tick() // ... if (is_clientreplay() || is_active() || is_stopping()) { + server->clear_laggy_clients(); server->find_idle_sessions(); server->evict_cap_revoke_non_responders(); locker->tick(); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 6cb43c90a55..2d22e294fe4 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1123,10 +1123,12 @@ void Server::find_idle_sessions() return; } - std::vector to_evict; - bool defer_session_stale = g_conf().get_val("mds_defer_session_stale"); const auto sessions_p1 = mds->sessionmap.by_state.find(Session::STATE_OPEN); + bool defer_client_eviction = + g_conf().get_val("defer_client_eviction_on_laggy_osds") + && mds->objecter->with_osdmap([](const OSDMap &map) { + return map.any_osd_laggy(); }); if (sessions_p1 != mds->sessionmap.by_state.end() && !sessions_p1->second->empty()) { std::vector new_stale; @@ -1151,7 +1153,7 @@ void Server::find_idle_sessions() dout(20) << "evicting session " << session->info.inst << " since autoclose " "has arrived" << dendl; // evict session without marking it stale - to_evict.push_back(session); + laggy_clients.insert(session->get_client()); continue; } @@ -1180,7 +1182,7 @@ void Server::find_idle_sessions() } // do not go through stale, evict it directly. - to_evict.push_back(session); + laggy_clients.insert(session->get_client()); } else { dout(10) << "new stale session " << session->info.inst << " last renewed caps " << last_cap_renew_span << "s ago" << dendl; @@ -1196,7 +1198,7 @@ void Server::find_idle_sessions() auto m = make_message(CEPH_SESSION_STALE, session->get_push_seq()); mds->send_message_client(m, session); } else { - to_evict.push_back(session); + laggy_clients.insert(session->get_client()); } } } @@ -1215,11 +1217,21 @@ void Server::find_idle_sessions() << " and recently renewed caps " << last_cap_renew_span << "s ago" << dendl; break; } - to_evict.push_back(session); + laggy_clients.insert(session->get_client()); } } - for (auto session: to_evict) { + // don't evict client(s) if osds are laggy + if(defer_client_eviction && !laggy_clients.empty()) { + dout(5) << "Detected " << laggy_clients.size() + << " laggy clients, possibly due to laggy OSDs." + " Eviction is skipped until the OSDs return to normal." + << dendl; + return; + } + + for (auto client: laggy_clients) { + Session *session = mds->sessionmap.get_session(entity_name_t::CLIENT(client.v)); if (session->is_importing()) { dout(10) << "skipping session " << session->info.inst << ", it's being imported" << dendl; continue; @@ -1246,6 +1258,20 @@ void Server::evict_cap_revoke_non_responders() { } auto&& to_evict = mds->locker->get_late_revoking_clients(cap_revoke_eviction_timeout); + // don't evict client(s) if osds are laggy + bool defer_client_eviction = + g_conf().get_val("defer_client_eviction_on_laggy_osds") + && mds->objecter->with_osdmap([](const OSDMap &map) { + return map.any_osd_laggy(); }) + && to_evict.size(); + if(defer_client_eviction) { + laggy_clients.insert(to_evict.begin(), to_evict.end()); + dout(0) << "Detected " << to_evict.size() + << " unresponsive clients, possibly due to laggy OSDs." + " Eviction is skipped until the OSDs return to normal." + << dendl; + return; + } for (auto const &client: to_evict) { mds->clog->warn() << "client id " << client << " has not responded to" diff --git a/src/mds/Server.h b/src/mds/Server.h index 346feb27c7b..afd7c342d50 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -333,6 +333,13 @@ public: std::set client_reclaim_gather; + std::set get_laggy_clients() const { + return laggy_clients; + } + void clear_laggy_clients() { + laggy_clients.clear(); + } + private: friend class MDSContinuation; friend class ServerContext; @@ -521,6 +528,9 @@ private: double caps_throttle_retry_request_timeout; size_t alternate_name_max = g_conf().get_val("mds_alternate_name_max"); + + // record laggy clients due to laggy OSDs + std::set laggy_clients; }; static inline constexpr auto operator|(Server::RecallFlags a, Server::RecallFlags b) {