{"id":29482593,"url":"https://github.com/mingrammer/keyflare","last_synced_at":"2025-08-10T14:37:00.996Z","repository":{"id":301820025,"uuid":"981191259","full_name":"mingrammer/keyflare","owner":"mingrammer","description":"Lightweight client-side hot key detector for distributed cache systems","archived":false,"fork":false,"pushed_at":"2025-07-02T10:43:15.000Z","size":897,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-15T04:28:06.058Z","etag":null,"topics":["distributed-cache","hotkey","memcached","redis"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mingrammer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-10T14:47:11.000Z","updated_at":"2025-07-02T10:43:18.000Z","dependencies_parsed_at":"2025-06-29T03:30:00.882Z","dependency_job_id":"3ea7040f-e378-4b0f-9f34-a826226540ab","html_url":"https://github.com/mingrammer/keyflare","commit_stats":null,"previous_names":["mingrammer/keyflare"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mingrammer/keyflare","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingrammer%2Fkeyflare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingrammer%2Fkeyflare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingrammer%2Fkeyflare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingrammer%2Fkeyflare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mingrammer","download_url":"https://codeload.github.com/mingrammer/keyflare/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mingrammer%2Fkeyflare/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269737070,"owners_count":24467153,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-cache","hotkey","memcached","redis"],"created_at":"2025-07-15T02:01:15.616Z","updated_at":"2025-08-10T14:37:00.947Z","avatar_url":"https://github.com/mingrammer.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# KeyFlare\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"images/logo-min.png\" alt=\"KeyFlare Logo\" width=\"200\"/\u003e\n\u003c/p\u003e\n\n**KeyFlare** is a client-side hot key detection engine designed to identify and mitigate hot key problems in caching systems in real-time.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/mingrammer/keyflare.svg)](https://pkg.go.dev/github.com/mingrammer/keyflare)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Configuration](#configuration)\n- [Monitoring](#monitoring)\n- [How It Works](#how-it-works)\n- [License](#license)\n\nIn large-scale, sharded Redis/Memcached cluster, hot keys can cause serious bottlenecks on specific nodes. Traditional server-side detection or telemetry-based methods often require complex infra changes or deep integration.\n\nKeyflare takes a simple yet effective approach:\n\n## Features\n\n- **Real-time Hot Key Detection**: Uses Count-Min Sketch and Space-Saving algorithms for efficient hot key identification\n- **Memory-Efficient**: Unlike traditional full-tracking approaches, KeyFlare uses probabilistic algorithms that provide excellent accuracy with minimal memory overhead\n- **Policy-Based Mitigation**: Automatic application of mitigation strategies (local caching, key splitting) when hot keys are detected\n- **Non-Intrusive Integration**: Easy integration with existing cache clients without code changes\n- **Comprehensive Monitoring**: Prometheus metrics and REST API for hot key insights\n- **Multi-Client Support**: Works with Redis (go-redis and rueidis), Memcached (gomemcache).\n\n## Installation\n\nInstall the core library:\n\n```bash\ngo get github.com/mingrammer/keyflare\n```\n\nInstall client wrappers as needed:\n\n```bash\n# For Redis (go-redis)\ngo get github.com/mingrammer/keyflare/pkg/redis\n\n# For Redis (rueidis)\ngo get github.com/mingrammer/keyflare/pkg/rueidis\n\n# For Memcached\ngo get github.com/mingrammer/keyflare/pkg/memcached\n```\n\n## Quick Start\n\n### 1. Initialize KeyFlare\n\n```go\nimport \"github.com/mingrammer/keyflare\"\n\n// Initialize with local cache policy\nerr := keyflare.New(\n    keyflare.WithPolicyOptions(keyflare.PolicyOptions{\n        Type: keyflare.LocalCache,\n        Parameters: keyflare.LocalCacheParams{\n            TTL:          300,\n            Jitter:       0.2,\n            Capacity:     1000,\n            RefreshAhead: 0.8,\n        },\n        WhitelistKeys: []string{\n            \"user:popular\",\n            \"config:global\",\n        },\n    }),\n)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Start the detection engine\nerr = keyflare.Start()\nif err != nil {\n    log.Fatal(err)\n}\ndefer keyflare.Stop()\n```\n\n### 2. Wrap Your Cache Client\n\n#### Redis (go-redis) Example\n\n```go\nimport (\n    \"github.com/redis/go-redis/v9\"\n    redisWrapper \"github.com/mingrammer/keyflare/pkg/redis\"\n)\n\n// Create Redis Cluster client (required)\nrdb := redis.NewClusterClient(\u0026redis.ClusterOptions{\n    Addrs: []string{\"localhost:7000\", \"localhost:7001\", \"localhost:7002\"},\n})\n\n// Wrap with KeyFlare\nclient, err := redisWrapper.Wrap(rdb)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Use exactly like the original client\nerr = client.Set(ctx, \"my-key\", \"my-value\", time.Minute).Err()\nval, err := client.Get(ctx, \"my-key\").Result()\n```\n\n#### Redis (rueidis) Example\n\n```go\nimport (\n    \"github.com/redis/rueidis\"\n    rueidisWrapper \"github.com/mingrammer/keyflare/pkg/rueidis\"\n)\n\n// Create Rueidis client\nclient, err := rueidis.NewClient(rueidis.ClientOption{\n    InitAddress: []string{\"localhost:6379\"},\n})\nif err != nil {\n    log.Fatal(err)\n}\n\n// Wrap with KeyFlare\nwrappedClient, err := rueidisWrapper.Wrap(client)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Use with command builder pattern\ncmd := wrappedClient.B().Get().Key(\"my-key\").Build()\nresult := wrappedClient.Do(ctx, cmd)\n```\n\n#### Memcached Example\n\n```go\nimport (\n    \"github.com/bradfitz/gomemcache/memcache\"\n    memcachedWrapper \"github.com/mingrammer/keyflare/pkg/memcached\"\n)\n\n// Create Memcached client\nmc := memcache.New(\"localhost:11211\")\n\n// Wrap with KeyFlare\nclient, err := memcachedWrapper.Wrap(mc)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Use exactly like the original client\nerr = client.Set(\u0026memcache.Item{Key: \"my-key\", Value: []byte(\"my-value\")})\nitem, err := client.Get(\"my-key\")\n```\n\n\u003e **📚 Complete Examples:** For comprehensive integration examples with monitoring and policy demonstrations, see the [examples/](examples/) directory.\n\n## Configuration\n\n### Custom Detector Settings\n\n```go\nerr := keyflare.New(\n    keyflare.WithDetectorOptions(keyflare.DetectorOptions{\n        ErrorRate:     0.001,  // Acceptable error rate for probabilistic algorithms\n        TopK:          100,    // Number of top hot keys to track\n        DecayFactor:   0.98,   // Decay rate for aging data\n        DecayInterval: 60,     // Decay interval in seconds\n        HotThreshold:  1000,   // Threshold for hot key detection (0 means automatic)\n    }),\n)\n```\n\n### Policy Configuration\n\nPolicies are applied via whitelist - only specified keys can be mitigated.\n\n#### Local Cache Policy\n\n```go\nerr := keyflare.New(\n    keyflare.WithPolicyOptions(keyflare.PolicyOptions{\n        Type: keyflare.LocalCache,\n        Parameters: keyflare.LocalCacheParams{\n            TTL:          300,   // Cache TTL in seconds\n            Jitter:       0.2,   // TTL randomization factor\n            Capacity:     1000,  // Max cached items\n            RefreshAhead: 0.8,   // Refresh threshold\n        },\n        WhitelistKeys: []string{\n            \"user:popular\",\n            \"config:global\",\n            \"leaderboard:top\",\n        },\n    }),\n)\n```\n\n#### Key Splitting Policy\n\n```go\nerr := keyflare.New(\n    keyflare.WithPolicyOptions(keyflare.PolicyOptions{\n        Type: keyflare.KeySplitting,\n        Parameters: keyflare.KeySplittingParams{\n            Shards: 10,  // Number of shards to split keys into\n        },\n        WhitelistKeys: []string{\n            \"counter:global\",\n            \"analytics:realtime\",\n        },\n    }),\n)\n```\n\n## Monitoring\n\n### Prometheus Metrics\n\nKeyFlare exposes metrics at `http://localhost:9121/metrics`:\n\n- `keyflare_key_access_total`: Total key access count\n- `keyflare_policy_application_total`: Policy application statistics\n- `keyflare_hot_keys`: Current hot key counts\n- `keyflare_top_k_keys_count`: Number of keys in top-K list\n\n### Hot Keys API\n\nGet real-time hot key information:\n\n```bash\n# Get top 20 hot keys\ncurl \"http://localhost:9121/hot-keys?limit=20\"\n\n# Get hot keys with time series data\ncurl \"http://localhost:9121/hot-keys?include_timeseries=true\u0026timeseries_points=100\"\n```\n\nResponse format:\n\n```json\n{\n  \"timestamp\": \"2025-01-15T10:30:00Z\",\n  \"top_k\": 100,\n  \"total_keys\": 45,\n  \"keys\": [\n    {\n      \"key\": \"user:12345\",\n      \"count\": 15420,\n      \"rank\": 1,\n      \"first_seen\": \"2025-01-15T09:00:00Z\",\n      \"last_seen\": \"2025-01-15T10:29:59Z\",\n      \"trend\": \"rising\"\n    }\n  ]\n}\n```\n\n## How It Works\n\n### 1. Detection Phase\n\nWhen a key is accessed, KeyFlare:\n\n- Updates the Count-Min Sketch (CMS) with the key\n- Adds/updates the key in the Space-Saving structure\n- Applies time-based decay to prevent stale hot keys\n\n### 2. Classification Phase\n\nKeys are classified as \"hot\" if they:\n\n- Exceed a configured count threshold, OR\n- Appear in the top-K most frequent keys\n\n### 3. Mitigation Phase\n\nHot keys trigger automatic mitigation:\n\n- **Local Cache**: Frequently accessed data is cached locally\n- **Key Splitting**: Hot keys are split across multiple cache entries\n\n### 4. Monitoring Phase\n\nReal-time insights are provided through:\n\n- Prometheus metrics for alerting and dashboards\n- REST API for programmatic access\n- Time-series data for trend analysis\n\n## License\n\nKeyFlare is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingrammer%2Fkeyflare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmingrammer%2Fkeyflare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmingrammer%2Fkeyflare/lists"}