Skip to content

Commit a8b522e

Browse files
committed
add big key detection
1 parent 09424b2 commit a8b522e

37 files changed

Lines changed: 687 additions & 49 deletions

conf/pika.conf

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ default-slot-num : 1024
494494
# The value option is [yes | no]
495495
# enable-blob-garbage-collection : no
496496

497-
# the cutoff that the GC logic uses to determine which blob files should be considered old.
497+
# the cutoff that the GC logic uses to determine which blob files should be considered "old".
498498
# This parameter can be tuned to adjust the trade-off between write amplification and space amplification.
499499
# blob-garbage-collection-age-cutoff : 0.25
500500

@@ -527,6 +527,23 @@ max-rsync-parallel-num : 4
527527
# The synchronization mode of Pika primary/secondary replication is determined by ReplicationID. ReplicationID in one replication_cluster are the same
528528
# replication-id :
529529

530+
# The maximum number of big keys to output in 'info' and log output.
531+
# This controls how many big key entries are shown at most for each type.
532+
# Default: 10
533+
BIGKEYS_SHOW_LIMIT = 10
534+
535+
# The threshold for member count to trigger big key detection
536+
# Default: 10000
537+
bigkeys_member_threshold : 10000
538+
539+
# The threshold for key and value length (in bytes)
540+
# to trigger big key detection (for string type).
541+
# Default: 1048576 (1MB)
542+
bigkeys_key_value_length_threshold : 1048576
543+
544+
# The interval (in minutes) for outputting big key statistics to the log.
545+
# Default: 1
546+
bigkeys_log_interval : 1
530547
###################
531548
## Cache Settings
532549
###################
@@ -671,3 +688,9 @@ dont-compact-sst-created-in-seconds : 20
671688
# According to the number of sst files in rocksdb,
672689
# compact every `compact-every-num-of-files` file.
673690
best-delete-min-ratio : 10
691+
692+
# Bigkeys related
693+
bigkeys-show-limit : 10
694+
bigkeys-member-threshold : 10000
695+
bigkeys-key-value-length-threshold : 1048576
696+
bigkeys-log-interval : 1

include/pika_admin.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,9 @@ class InfoCmd : public Cmd {
267267
kInfoAll,
268268
kInfoDebug,
269269
kInfoCommandStats,
270-
kInfoCache
270+
kInfoCache,
271+
kInfoBigKeys
272+
271273
};
272274
InfoCmd(const std::string& name, int arity, uint32_t flag) : Cmd(name, arity, flag) {}
273275
void Do() override;
@@ -295,6 +297,7 @@ class InfoCmd : public Cmd {
295297
const static std::string kDebugSection;
296298
const static std::string kCommandStatsSection;
297299
const static std::string kCacheSection;
300+
const static std::string kBigKeysSection;
298301

299302
void DoInitial() override;
300303
void Clear() override {
@@ -304,6 +307,7 @@ class InfoCmd : public Cmd {
304307
}
305308

306309
void InfoServer(std::string& info);
310+
void InfoBigKeys(std::string& info);
307311
void InfoClients(std::string& info);
308312
void InfoStats(std::string& info);
309313
void InfoExecCount(std::string& info);

include/pika_conf.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ class PikaConf : public pstd::BaseConf {
160160
std::shared_lock l(rwlock_);
161161
return binlog_writer_num_;
162162
}
163+
//big keys
164+
int bigkeys_show_limit() {
165+
std::shared_lock l(rwlock_);
166+
return bigkeys_show_limit_;
167+
}
168+
int bigkeys_member_threshold() {
169+
std::shared_lock l(rwlock_);
170+
return bigkeys_member_threshold_;
171+
}
172+
int bigkeys_key_value_length_threshold() {
173+
std::shared_lock l(rwlock_);
174+
return bigkeys_key_value_length_threshold_;
175+
}
176+
int bigkeys_log_interval() {
177+
std::shared_lock l(rwlock_);
178+
return bigkeys_log_interval_;
179+
}
163180
bool slotmigrate() {
164181
std::shared_lock l(rwlock_);
165182
return slotmigrate_;
@@ -729,7 +746,23 @@ class PikaConf : public pstd::BaseConf {
729746
log_net_activities_.store(false);
730747
}
731748
}
732-
749+
//big keys
750+
void SetBigkeysShowLimit(const int value) {
751+
std::lock_guard l(rwlock_);
752+
bigkeys_show_limit_ = value;
753+
}
754+
void SetBigkeysKeyValueLengthThreshold(const int value) {
755+
std::lock_guard l(rwlock_);
756+
bigkeys_key_value_length_threshold_ = value;
757+
}
758+
void SetBigkeysMemberCountThreshold(const int value) {
759+
std::lock_guard l(rwlock_);
760+
bigkeys_member_threshold_ = value;
761+
}
762+
void SetBigkeysLogInterval(const int value) {
763+
std::lock_guard l(rwlock_);
764+
bigkeys_log_interval_ = value;
765+
}
733766
// Rsync Rate limiting configuration
734767
void SetThrottleBytesPerSecond(const int value) {
735768
std::lock_guard l(rwlock_);
@@ -895,6 +928,11 @@ class PikaConf : public pstd::BaseConf {
895928
int thread_pool_size_ = 0;
896929
int slow_cmd_thread_pool_size_ = 0;
897930
int admin_thread_pool_size_ = 0;
931+
//big keys
932+
int bigkeys_show_limit_ = 10;
933+
int bigkeys_member_threshold_ = 10000;
934+
int bigkeys_key_value_length_threshold_ = 1048576;
935+
int bigkeys_log_interval_ = 60;
898936
std::unordered_set<std::string> slow_cmd_set_;
899937
// Because the exporter of Pika_exporter implements Auth authentication
900938
// with the Exporter of Pika, and the Exporter authenticates the Auth when

include/pika_db.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ class DB : public std::enable_shared_from_this<DB>, public pstd::noncopyable {
128128

129129
void SetCompactRangeOptions(const bool is_canceled);
130130

131+
// Update big keys configuration
132+
void UpdateStorageBigKeysConfig(int log_interval, uint64_t member_threshold, uint64_t key_value_length_threshold, size_t show_limit);
133+
131134
std::shared_ptr<pstd::lock::LockMgr> LockMgr();
132135
/*
133136
* Cache used

include/pika_define.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212

1313
#include "net/include/redis_cli.h"
1414

15+
/*
16+
* Big keys related
17+
*/
18+
#define BIGKEYS_SHOW_LIMIT 10
19+
#define BIGKEYS_MEMBER_THRESHOLD 10000
20+
#define BIGKEYS_KEY_VALUE_LENGTH_THRESHOLD 1048576
21+
#define BIGKEYS_LOG_INTERVAL 1
1522
/*
1623
* TTL type
1724
*/

include/pika_server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class PikaServer : public pstd::noncopyable {
145145
void DBSetMaxCacheStatisticKeys(uint32_t max_cache_statistic_keys);
146146
void DBSetSmallCompactionThreshold(uint32_t small_compaction_threshold);
147147
void DBSetSmallCompactionDurationThreshold(uint32_t small_compaction_duration_threshold);
148+
void UpdateDBBigKeysConfig();
148149
bool GetDBBinlogOffset(const std::string& db_name, BinlogOffset* boffset);
149150
pstd::Status DoSameThingEveryDB(const TaskType& type);
150151

src/net/include/net_define.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ enum EventStatus {
4848
kNone = 0,
4949
kReadable = 0x1,
5050
kWritable = 0x1 << 1,
51-
kErrorEvent = 0x1 << 2,
51+
kPeerClose = 0x1 << 2,
52+
kErrorEvent = 0x1 << 3,
5253
};
5354

5455
enum ConnStatus {

src/net/src/net_epoll.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include "net/include/net_define.h"
1515
#include "pstd/include/xdebug.h"
1616

17+
#ifndef EPOLLRDHUP
18+
#define EPOLLRDHUP 0x2000
19+
#endif
20+
1721
namespace net {
1822

1923
NetMultiplexer* CreateNetMultiplexer(int limit) { return new NetEpoll(limit); }
@@ -45,7 +49,7 @@ int NetEpoll::NetAddEvent(int fd, int mask) {
4549
}
4650
if (mask & kWritable) {
4751
ee.events |= EPOLLOUT;
48-
}
52+
}
4953

5054
return epoll_ctl(multiplexer_, EPOLL_CTL_ADD, fd, &ee);
5155
}
@@ -62,6 +66,10 @@ int NetEpoll::NetModEvent(int fd, int old_mask, int mask) {
6266
if ((old_mask | mask) & kWritable) {
6367
ee.events |= EPOLLOUT;
6468
}
69+
70+
if ((old_mask | mask) & kPeerClose) {
71+
ee.events |= EPOLLRDHUP;
72+
}
6573
return epoll_ctl(multiplexer_, EPOLL_CTL_MOD, fd, &ee);
6674
}
6775

@@ -93,6 +101,10 @@ int NetEpoll::NetPoll(int timeout) {
93101
ev.mask |= kWritable;
94102
}
95103

104+
if (events_[i].events & EPOLLRDHUP) {
105+
ev.mask |= kPeerClose;
106+
}
107+
96108
if (events_[i].events & (EPOLLERR | EPOLLHUP)) {
97109
ev.mask |= kErrorEvent;
98110
}

src/net/src/worker_thread.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ void* WorkerThread::ThreadMain() {
189189
ReadStatus read_status = in_conn->GetRequest();
190190
in_conn->set_last_interaction(now);
191191
if (read_status == kReadAll) {
192-
net_multiplexer_->NetModEvent(pfe->fd, 0, 0);
192+
net_multiplexer_->NetModEvent(pfe->fd, 0, kPeerClose);
193193
// Wait for the conn complete asynchronous task and
194194
// Mod Event to kWritable
195195
} else if (read_status == kReadHalf) {
@@ -199,8 +199,15 @@ void* WorkerThread::ThreadMain() {
199199
}
200200
}
201201

202+
if ((should_close == 0) && ((pfe->mask & kPeerClose) != 0)) {
203+
should_close = 1;
204+
}
205+
202206
if (((pfe->mask & kErrorEvent) != 0) || (should_close != 0)) {
203207
net_multiplexer_->NetDelEvent(pfe->fd, 0);
208+
// TODO: in_conn may live longer than fd.
209+
// eg. in_conn are being transferred to net_pubsub
210+
// while peer client closing this connection
204211
CloseFd(in_conn);
205212
in_conn = nullptr;
206213
{

src/pika.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ int main(int argc, char* argv[]) {
211211
g_pika_rm = std::make_unique<PikaReplicaManager>();
212212
g_network_statistic = std::make_unique<net::NetworkStatistic>();
213213
g_pika_server->InitDBStruct();
214+
g_pika_server->UpdateDBBigKeysConfig();
214215
//the cmd table of g_pika_cmd_table_manager must be inited before calling PikaServer::InitStatistic(CmdTable* )
215216
g_pika_server->InitStatistic(g_pika_cmd_table_manager->GetCmdTable());
216217
auto status = g_pika_server->InitAcl();

0 commit comments

Comments
 (0)