Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@fcostaoliveira
Copy link
Collaborator

@fcostaoliveira fcostaoliveira commented Jan 2, 2026

This PR introduces first-class support for driving memtier_benchmark workloads from Redis MONITOR output files.

It adds:

  • --monitor-input=FILE to load commands captured via redis-cli MONITOR
  • --monitor-pattern={S|R} to control runtime command selection (Sequential by default, or Random)
  • A new __monitor_c*__ placeholder family for --command:
    • __monitor_c1__, __monitor_c2__, … to replay a specific command from the monitor file
    • __monitor_c@__ to select commands at runtime (sequential or random)

This enables replaying real traffic and mixing captured workloads with synthetic commands using --command-ratio, while remaining compatible with both standalone and Redis Cluster deployments.

User-facing behavior

Replay a specific captured command on every request:

memtier_benchmark --monitor-input=monitor.txt --command=__monitor_c1__

Runtime-selected replay (sequential by default, random with --monitor-pattern=R):

memtier_benchmark --monitor-input=monitor.txt --command=__monitor_c@__ --monitor-pattern=R

Documentation

  • Adds a new Using monitor input files section to the README
  • Includes concrete usage examples
  • Documents how to capture MONITOR output using redis-cli
  • Links to the official Redis CLI MONITOR documentation

Note

Medium Risk
Adds new CLI surface and alters arbitrary-command request generation to dynamically load/expand commands from files, which can affect workload behavior and runtime stability/perf. Also introduces extra debug logging in the Redis protocol parser and adjusts URI cleanup, so regressions would show up at runtime rather than compile time.

Overview
Adds first-class support for driving --command workloads from Redis MONITOR output via --monitor-input, including __monitor_cN__ placeholders (expanded at startup) and __monitor_c@__ (expanded per-request, sequential by default or random with --monitor-pattern).

Implements a monitor_command_list file loader and integrates it into startup parsing/validation, plus runtime selection/formatting in client::create_arbitrary_request (with cluster-mode single-key checks preserved).

Also makes log_level globally visible and adds optional raw RESP response dumping in redis_protocol::parse_response when debug is enabled, updates README documentation, and adds new integration tests covering specific, random, sequential, and mixed monitor-driven workloads.

Written by Cursor Bugbot for commit fe67267. This will update automatically on new commits. Configure here.

@fcostaoliveira fcostaoliveira self-assigned this Jan 28, 2026
@fcostaoliveira
Copy link
Collaborator Author

cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 6 potential issues.

}
fprintf(stderr, "\n");
}
}
Copy link

Choose a reason for hiding this comment

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

Debug code dumps raw responses to stderr

High Severity

Debug code that dumps raw response bytes to stderr was left in parse_response(). This code runs for every Redis response when debug mode is enabled (-D), printing up to 512 bytes of raw response data with a "RAW RESPONSE" prefix. The comment explicitly says "Debug: dump raw response buffer" indicating this was for development. Other debug output in this file uses benchmark_debug_log, but this uses direct fprintf(stderr, ...). This would produce extremely verbose output overwhelming users who enable debug mode.

Fix in Cursor Fix in Web

} else {
fprintf(stderr, "error: failed to parse arbitrary command.\n");
return -1;
}
Copy link

Choose a reason for hiding this comment

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

Monitor placeholders without --monitor-input not validated

Medium Severity

Using monitor placeholders like __monitor_c1__ without --monitor-input causes the literal placeholder string to be sent to Redis instead of producing an error. When parsing --command, monitor placeholders are recognized but only expanded when cfg.monitor_input is set. Without it, the placeholder passes through to format_arbitrary_command unchanged, resulting in Redis receiving an invalid command like __monitor_c1__.

Additional Locations (1)

Fix in Cursor Fix in Web

unsigned long long key_index;
get_key_response res = get_key_for_conn(command_index, conn_id, &key_index);
assert(res == available_for_conn);
cmd_size += m_connections[conn_id]->send_arbitrary_command(arg, m_obj_gen->get_key(), m_obj_gen->get_key_len());
Copy link

Choose a reason for hiding this comment

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

Key prefix/suffix handling missing in monitor command path

Medium Severity

The new monitor command handling path for key_type arguments doesn't check has_key_affixes, unlike the original code path at lines 351-386. When a monitor command contains a key argument with prefix/suffix like user:__key__:profile, the prefix and suffix are lost, sending only the generated key. The original path properly combines data_prefix, the generated key, and data_suffix.

Fix in Cursor Fix in Web

}
size_t random_index = rand() % commands.size();
return commands[random_index];
}
Copy link

Choose a reason for hiding this comment

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

Unused function overload get_random_command() without parameter

Low Severity

The get_random_command() overload without the out_index parameter is declared and implemented but never called anywhere in the codebase. Only the overloaded version get_random_command(size_t* out_index) is used in client.cpp. This dead code should be removed to reduce maintenance burden.

Additional Locations (1)

Fix in Cursor Fix in Web

key_type = 1,
data_type = 2,
undefined_type = 3
monitor_type = 3,
Copy link

Choose a reason for hiding this comment

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

Unused monitor_type enum value defined but never referenced

Low Severity

The monitor_type enum value is defined in command_arg_type but is never used anywhere in the codebase. Only monitor_random_type is actually used. This unused enum value adds confusion about the intended design and should be removed if not needed.

Fix in Cursor Fix in Web

command_arg_type type;
std::string data;
// For monitor_type, stores the index (1-based)
size_t monitor_index;
Copy link

Choose a reason for hiding this comment

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

Unused monitor_index field only written never read

Low Severity

The monitor_index field in command_arg struct is added and initialized to 0 in the constructor, and assigned to 0 in memtier_benchmark.cpp, but it is never read anywhere. This is a dead store that adds unnecessary complexity to the data structure without providing any functionality.

Fix in Cursor Fix in Web

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