feat(redis): fuzzy key search keyspace-aware scan budget
This commit is contained in:
3 files changed
+39
-5
No files matched your search
@@ -0,0 +1,15 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { redisFuzzySearchScanBudget, REDIS_FUZZY_SEARCH_SCAN_COUNT_MAX, REDIS_KEY_SEARCH_SCAN_COUNT_BUDGET, REDIS_SCAN_PAGE_SIZE_DEFAULT, REDIS_SCAN_PAGE_SIZE_OPTIONS } from "@/lib/redis/redisKeyPattern";
|
||||
|
||||
describe("Redis key search settings", () => {
|
||||
it("keeps the default scan count conservative for initial loading", () => {
|
||||
expect(REDIS_SCAN_PAGE_SIZE_DEFAULT).toBe(1000);
|
||||
expect(REDIS_SCAN_PAGE_SIZE_OPTIONS).toContain(2000);
|
||||
});
|
||||
|
||||
it("covers the reported keyspace while retaining a large-instance cap", () => {
|
||||
expect(redisFuzzySearchScanBudget(0)).toBe(REDIS_KEY_SEARCH_SCAN_COUNT_BUDGET);
|
||||
expect(redisFuzzySearchScanBudget(378543)).toBe(378543);
|
||||
expect(redisFuzzySearchScanBudget(REDIS_FUZZY_SEARCH_SCAN_COUNT_MAX + 1)).toBe(REDIS_FUZZY_SEARCH_SCAN_COUNT_MAX);
|
||||
});
|
||||
});
|
||||
@@ -21,9 +21,20 @@ export function redisGroupSubtreePattern(pathSegments: readonly string[], separa
|
||||
return `${prefix}${separator}*`;
|
||||
}
|
||||
|
||||
// Fuzzy key search has to walk the Redis keyspace because MATCH has no index.
|
||||
// Start conservatively, then use DBSIZE to cover ordinary databases while
|
||||
// retaining a hard upper bound for unusually large instances.
|
||||
export const REDIS_KEY_SEARCH_SCAN_COUNT_BUDGET = 50_000;
|
||||
export const REDIS_FUZZY_SEARCH_SCAN_COUNT_MAX = 1_000_000;
|
||||
|
||||
export function redisFuzzySearchScanBudget(totalKeys: number): number {
|
||||
const normalizedTotalKeys = Number.isFinite(totalKeys) ? Math.max(0, Math.floor(totalKeys)) : 0;
|
||||
return Math.min(Math.max(REDIS_KEY_SEARCH_SCAN_COUNT_BUDGET, normalizedTotalKeys), REDIS_FUZZY_SEARCH_SCAN_COUNT_MAX);
|
||||
}
|
||||
|
||||
// Redis scan page size (COUNT parameter per SCAN round-trip) — shared defaults
|
||||
// and validation bounds used by the connection form and key browser.
|
||||
export const REDIS_SCAN_PAGE_SIZE_DEFAULT = 1000;
|
||||
export const REDIS_SCAN_PAGE_SIZE_MIN = 200;
|
||||
export const REDIS_SCAN_PAGE_SIZE_MAX = 10_000;
|
||||
export const REDIS_SCAN_PAGE_SIZE_OPTIONS = [200, 1000, 5000, 10_000] as const;
|
||||
export const REDIS_SCAN_PAGE_SIZE_OPTIONS = [200, 1000, 2000, 5000, 10_000] as const;
|
||||
Reference in new issue
Block a user