Skip to content

Commit

Permalink
feat(server): introduce oom_deny_commands flag (#3718)
Browse files Browse the repository at this point in the history
* server: introduce oom_deny_commands flag

Signed-off-by: adi_holden <[email protected]>
  • Loading branch information
adiholden authored Sep 22, 2024
1 parent 69db21d commit 5cf9178
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/facade/command_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ class CommandId {
restricted_ = restricted;
}

void SetFlag(uint32_t flag) {
opt_mask_ |= flag;
}

static uint32_t OptCount(uint32_t mask);

// PUBLISH/SUBSCRIBE/UNSUBSCRIBE variant
Expand Down
10 changes: 10 additions & 0 deletions src/server/command_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ ABSL_FLAG(vector<string>, rename_command, {},
ABSL_FLAG(vector<string>, restricted_commands, {},
"Commands restricted to connections on the admin port");

ABSL_FLAG(vector<string>, oom_deny_commands, {},
"Additinal commands that will be marked as denyoom");
namespace dfly {

using namespace facade;
Expand Down Expand Up @@ -108,6 +110,10 @@ CommandRegistry::CommandRegistry() {
for (string name : GetFlag(FLAGS_restricted_commands)) {
restricted_cmds_.emplace(AsciiStrToUpper(name));
}

for (string name : GetFlag(FLAGS_oom_deny_commands)) {
oomdeny_cmds_.emplace(AsciiStrToUpper(name));
}
}

void CommandRegistry::Init(unsigned int thread_count) {
Expand All @@ -133,6 +139,10 @@ CommandRegistry& CommandRegistry::operator<<(CommandId cmd) {
cmd.SetRestricted(true);
}

if (oomdeny_cmds_.find(k) != oomdeny_cmds_.end()) {
cmd.SetFlag(CO::DENYOOM);
}

cmd.SetFamily(family_of_commands_.size() - 1);
if (!is_sub_command || absl::StartsWith(cmd.name(), "ACL")) {
cmd.SetBitIndex(1ULL << bit_index_);
Expand Down
1 change: 1 addition & 0 deletions src/server/command_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ class CommandRegistry {
absl::flat_hash_map<std::string, CommandId> cmd_map_;
absl::flat_hash_map<std::string, std::string> cmd_rename_map_;
absl::flat_hash_set<std::string> restricted_cmds_;
absl::flat_hash_set<std::string> oomdeny_cmds_;

FamiliesVec family_of_commands_;
size_t bit_index_;
Expand Down
26 changes: 26 additions & 0 deletions tests/dragonfly/generic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,29 @@ async def test_reply_guard_oom(df_factory, df_seeder_factory):

info = await c_master.info("stats")
assert info["evicted_keys"] > 0, "Weak testcase: policy based eviction was not triggered."


@pytest.mark.asyncio
async def test_denyoom_commands(df_factory):
df_server = df_factory.create(
proactor_threads=1, maxmemory="256mb", oom_deny_commands="get", oom_deny_ratio=0.7
)
df_server.start()
client = df_server.client()
await client.execute_command("DEBUG POPULATE 7000 size 44000")

min_deny = 250 * 1024 * 1024 # 250mb
info = await client.info("memory")
print(f'Used memory {info["used_memory"]}, rss {info["used_memory_rss"]}')
assert info["used_memory"] > min_deny, "Weak testcase: too little used memory"

# reject set due to oom
with pytest.raises(redis.exceptions.ResponseError):
await client.execute_command("set x y")

# reject get because it is set in oom_deny_commands
with pytest.raises(redis.exceptions.ResponseError):
await client.execute_command("get x")

# mget should not be rejected
await client.execute_command("mget x")

0 comments on commit 5cf9178

Please sign in to comment.