Skip to content

Reduce Redis blocking replay pressure - #1140

Merged
bootjp merged 1 commit into
mainfrom
feature/redis-blocking-secondary-replay
Jul 22, 2026
Merged

Reduce Redis blocking replay pressure#1140
bootjp merged 1 commit into
mainfrom
feature/redis-blocking-secondary-replay

Conversation

@bootjp

@bootjp bootjp commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Author: bootjp

Summary

  • stop replaying read-only XREAD BLOCK calls to the secondary backend
  • keep bounded replay for mutating blocking commands such as BZPOP/XREADGROUP
  • add coverage for blocking replay behavior

Risk

  • changes secondary replay behavior for XREAD BLOCK only; mutating blocking commands continue to replay to preserve secondary consumption state

Tests

  • go test ./proxy -run 'TestDualWriter_Blocking|TestBlockingCommandTimeout|TestClassifyCommand' -count=1\n- go test ./proxy -count=1\n- go test ./cmd/redis-proxy -count=1\n- golangci-lint run ./proxy ./cmd/redis-proxy --timeout=5m

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

BZPOPMINBZPOPMAX の結果を ZREM としてセカンダリへ非同期リプレイする処理を追加し、XREAD などのブロッキング読み取りはリプレイしないよう変更した。対応するデュアルライターのテストも追加した。

Changes

ブロッキング操作のリプレイ

Layer / File(s) Summary
リプレイコマンド生成
proxy/blocking.go
BZPOPMINBZPOPMAX のレスポンスからキーとメンバーを抽出し、ZREM の再実行データを生成する。
Blocking への統合と検証
proxy/dualwrite.go, proxy/proxy_test.go
DualWriter.Blocking が生成可能なリプレイだけをセカンダリへ非同期投入し、BZPOPMINZREM 変換と XREAD のリプレイなしをテストする。

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Redis のブロッキング処理のセカンダリ再生負荷を下げる変更内容を端的に表しており、主旨と一致しています。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bootjp

bootjp commented Jul 22, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8603f83157

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread proxy/blocking.go Outdated

func secondaryBlockingReplay(cmd string, resp any) (string, []any, bool) {
switch strings.ToUpper(cmd) {
case "BZPOPMIN", "BZPOPMAX":

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Replay all mutating blocking commands

ClassifyCommand still routes mutating blocking commands such as BLPOP/BRPOP/BRPOPLPUSH/BLMOVE/BLMPOP and XREADGROUP ... BLOCK into Blocking, but this helper now returns ok only for BZPOPMIN/BZPOPMAX. Redis documents BLPOP as removing the returned element (https://redis.io/docs/latest/commands/blpop/) and XREADGROUP as @write with delivered messages tracked in the PEL (https://redis.io/docs/latest/commands/xreadgroup/), so in dual-write modes a successful primary call for these commands now queues no secondary mutation and can leave consumed jobs or consumer-group state behind on the secondary after failover/migration. Please either keep replaying these write-like blocking commands or translate them deterministically as well.

Useful? React with 👍 / 👎.

Comment thread proxy/blocking.go Outdated
if !ok {
return "", nil, false
}
return "ZREM", []any{"ZREM", key, member}, true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve ordering for BZPOP removals

When a producer ZADD is followed by a consumer BZPOPMIN on the primary before the secondary has applied the ZADD, this replayed ZREM can run first and remove 0 rows; dispatchAsyncQueue starts queued writes in separate goroutines (proxy/async_queue.go:74-76), so an earlier enqueued ZADD is not guaranteed to reach the secondary before this new removal. If the ZADD then applies later, the item that was already popped on the primary is resurrected on the secondary after failover/migration. The previous bounded blocking replay would wait for the secondary item instead of no-oping, so this deterministic replay needs ordering with prior writes or a retry/conditional path when the removal observes no member.

Useful? React with 👍 / 👎.

@bootjp

bootjp commented Jul 22, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@bootjp
bootjp force-pushed the feature/redis-blocking-secondary-replay branch from 8603f83 to da952d6 Compare July 22, 2026 13:06
@bootjp

bootjp commented Jul 22, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
proxy/proxy_test.go (1)

639-665: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

BZPOPMAX も同じ再生契約で検証してください。

このテストは BZPOPMIN のみを検証しています。BZPOPMAX についても、返却された key/member が ZREM に変換されるケースを追加してください。両者はセットアップと期待値が同じなので、表駆動テストにまとめると契約を明確に維持できます。

As per coding guidelines, “Unit tests must be co-located with packages in *_test.go files; prefer table-driven test cases.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proxy/proxy_test.go` around lines 639 - 665, The test currently covers only
BZPOPMIN replay behavior; extend it to verify the same contract for BZPOPMAX.
Refactor TestDualWriter_Blocking_ReplaysBZPopMinAsZRem into a table-driven test
covering both commands, using the returned key/member to assert the secondary
call is ZREM with the expected arguments.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@proxy/proxy_test.go`:
- Around line 639-665: The test currently covers only BZPOPMIN replay behavior;
extend it to verify the same contract for BZPOPMAX. Refactor
TestDualWriter_Blocking_ReplaysBZPopMinAsZRem into a table-driven test covering
both commands, using the returned key/member to assert the secondary call is
ZREM with the expected arguments.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b272418a-0d33-4c28-b027-dc9e9a5681ec

📥 Commits

Reviewing files that changed from the base of the PR and between 9c5d497 and 8603f83.

📒 Files selected for processing (3)
  • proxy/blocking.go
  • proxy/dualwrite.go
  • proxy/proxy_test.go

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: da952d66e4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bootjp
bootjp merged commit 43eb009 into main Jul 22, 2026
11 checks passed
@bootjp
bootjp deleted the feature/redis-blocking-secondary-replay branch July 22, 2026 13:20
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.

1 participant