[CP][Bugfix][OBKV]fix session pool hold too much memory when login frequently
This commit is contained in:
parent
68d387893f
commit
b7b06563ac
@ -33,7 +33,7 @@ int ObTableApiSessPoolMgr::mtl_init(ObTableApiSessPoolMgr *&mgr)
|
||||
|
||||
/*
|
||||
start tableapi retired session task
|
||||
- 60 second interval
|
||||
- 5 second interval
|
||||
- repeated
|
||||
*/
|
||||
int ObTableApiSessPoolMgr::start()
|
||||
@ -45,7 +45,7 @@ int ObTableApiSessPoolMgr::start()
|
||||
LOG_WARN("table api session pool mgr isn't inited", K(ret));
|
||||
} else if (OB_FAIL(TG_SCHEDULE(MTL(omt::ObSharedTimer*)->get_tg_id(),
|
||||
elimination_task_,
|
||||
ELIMINATE_SESSION_DELAY/* 60s */,
|
||||
ELIMINATE_SESSION_DELAY/* 5s */,
|
||||
true/* repeat */))) {
|
||||
LOG_WARN("failed to schedule tableapi retired session task", K(ret));
|
||||
} else {
|
||||
@ -377,7 +377,7 @@ int ObTableApiSessPool::move_node_to_retired_list(ObTableApiSessNode *node)
|
||||
1. remove session val in free_list.
|
||||
2. remove session node from retired_nodes_ when node is empty.
|
||||
3. free node memory.
|
||||
4. delete 1000 session nodes per times
|
||||
4. delete 2000 session nodes per times
|
||||
*/
|
||||
int ObTableApiSessPool::evict_retired_sess()
|
||||
{
|
||||
@ -387,7 +387,7 @@ int ObTableApiSessPool::evict_retired_sess()
|
||||
ObLockGuard<ObSpinLock> guard(retired_nodes_lock_); // lock retired_nodes_
|
||||
|
||||
DLIST_FOREACH_REMOVESAFE_X(node, retired_nodes_, delete_count < BACKCROUND_TASK_DELETE_SESS_NUM) {
|
||||
if (cur_time - node->get_last_active_ts() < SESS_RETIRE_TIME) {
|
||||
if (cur_time - node->get_last_active_ts() < SESS_UPDATE_TIME_INTERVAL) {
|
||||
// do nothing, this node maybe is from ObTableApiSessNodeReplaceOp, some threads maybe is using it.
|
||||
// we remove it next retire task.
|
||||
} else if (OB_FAIL(node->remove_unused_sess())) {
|
||||
@ -545,23 +545,31 @@ int ObTableApiSessPool::create_and_add_node_safe(ObTableApiCredential &credentia
|
||||
/*
|
||||
1. only call in login
|
||||
2. move old to retired list when node exist, create new node otherwise.
|
||||
3. if the update interval is less than 5 seconds, ignore this update.
|
||||
*/
|
||||
int ObTableApiSessPool::update_sess(ObTableApiCredential &credential)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
ObTableApiSessNode *node = nullptr;
|
||||
const uint64_t key = credential.hash_val_;
|
||||
int64_t cur_time = ObTimeUtility::current_time();
|
||||
|
||||
if (OB_FAIL(get_sess_node(key, node))) {
|
||||
if (OB_HASH_NOT_EXIST == ret) { // not exist, create
|
||||
if (OB_FAIL(create_and_add_node_safe(credential))) {
|
||||
LOG_WARN("fail to create and add node", K(ret), K(credential));
|
||||
} else {
|
||||
ATOMIC_STORE(&last_update_ts_, cur_time);
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("fail to get session node", K(ret), K(key));
|
||||
}
|
||||
} else if (cur_time - last_update_ts_ < SESS_UPDATE_TIME_INTERVAL) {
|
||||
// if the update interval is less than 5 seconds, ignore this update.
|
||||
} else if (OB_FAIL(replace_sess_node_safe(credential))) { // exist, create and replace old node
|
||||
LOG_WARN("fail to replace session node", K(ret), K(credential));
|
||||
} else {
|
||||
ATOMIC_STORE(&last_update_ts_, cur_time);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
int create_session_pool_safe();
|
||||
int create_session_pool_unsafe();
|
||||
private:
|
||||
static const int64_t ELIMINATE_SESSION_DELAY = 60 * 1000 * 1000; // 60s
|
||||
static const int64_t ELIMINATE_SESSION_DELAY = 5 * 1000 * 1000; // 5s
|
||||
bool is_inited_;
|
||||
common::ObArenaAllocator allocator_;
|
||||
ObTableApiSessPool *pool_;
|
||||
@ -87,13 +87,15 @@ class ObTableApiSessPool final
|
||||
public:
|
||||
// key is ObTableApiCredential.hash_val_
|
||||
typedef common::hash::ObHashMap<uint64_t, ObTableApiSessNode*> CacheKeyNodeMap;
|
||||
static const int64_t SESS_POOL_DEFAULT_BUCKET_NUM = 10; // 取决于客户端登录的用户数量
|
||||
static const int64_t SESS_RETIRE_TIME = 300 * 1000000; // 超过300s未被访问的session会被标记淘汰
|
||||
static const int64_t BACKCROUND_TASK_DELETE_SESS_NUM = 1000; // 后台任务每次删除淘汰的session node数量
|
||||
static const int64_t SESS_POOL_DEFAULT_BUCKET_NUM = 10; // default user number
|
||||
static const int64_t SESS_RETIRE_TIME = 300 * 1000 * 1000; // marked as retired more than 300 seconds are not accessed
|
||||
static const int64_t BACKCROUND_TASK_DELETE_SESS_NUM = 2000; // number of eliminated session nodes in background task per time
|
||||
static const int64_t SESS_UPDATE_TIME_INTERVAL = 5 * 1000 * 1000; // the update interval cannot exceed 5 seconds
|
||||
public:
|
||||
explicit ObTableApiSessPool()
|
||||
: allocator_("TbSessPool", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()),
|
||||
is_inited_(false)
|
||||
is_inited_(false),
|
||||
last_update_ts_(0)
|
||||
{}
|
||||
~ObTableApiSessPool() { destroy(); };
|
||||
TO_STRING_KV(K_(is_inited),
|
||||
@ -120,6 +122,7 @@ private:
|
||||
// 前台login时、后台淘汰时都会操作retired_nodes_,因此需要加锁
|
||||
common::ObDList<ObTableApiSessNode> retired_nodes_;
|
||||
ObSpinLock retired_nodes_lock_; // for lock retired_nodes_
|
||||
int64_t last_update_ts_;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObTableApiSessPool);
|
||||
};
|
||||
|
@ -170,8 +170,7 @@ TEST_F(TestTableSessPool, mgr_update_session)
|
||||
ASSERT_NE(nullptr, mgr->pool_);
|
||||
ASSERT_TRUE(mgr->pool_->is_inited_);
|
||||
ASSERT_EQ(1, mgr->pool_->key_node_map_.size());
|
||||
ASSERT_EQ(1, mgr->pool_->retired_nodes_.size_);
|
||||
ASSERT_EQ(node, mgr->pool_->retired_nodes_.get_last());
|
||||
ASSERT_EQ(0, mgr->pool_->retired_nodes_.size_);
|
||||
ASSERT_EQ(OB_SUCCESS, mgr->pool_->get_sess_node(new_cred->hash_val_, node));
|
||||
ASSERT_NE(nullptr, node);
|
||||
ASSERT_TRUE(node->sess_lists_.free_list_.is_empty());
|
||||
@ -184,7 +183,7 @@ TEST_F(TestTableSessPool, mgr_update_session)
|
||||
ASSERT_NE(nullptr, mgr->pool_);
|
||||
ASSERT_TRUE(mgr->pool_->is_inited_);
|
||||
ASSERT_EQ(2, mgr->pool_->key_node_map_.size());
|
||||
ASSERT_EQ(1, mgr->pool_->retired_nodes_.size_);
|
||||
ASSERT_EQ(0, mgr->pool_->retired_nodes_.size_);
|
||||
ASSERT_EQ(OB_SUCCESS, mgr->pool_->get_sess_node(new_cred->hash_val_, node));
|
||||
ASSERT_NE(nullptr, node);
|
||||
ASSERT_TRUE(node->sess_lists_.free_list_.is_empty());
|
||||
|
Loading…
x
Reference in New Issue
Block a user