{"id":29085769,"url":"https://github.com/yotpoltd/resec","last_synced_at":"2025-06-27T23:06:02.812Z","repository":{"id":28454589,"uuid":"115317512","full_name":"YotpoLtd/resec","owner":"YotpoLtd","description":"ReSeC- Redis Service Consul","archived":false,"fork":false,"pushed_at":"2021-03-21T08:24:52.000Z","size":7835,"stargazers_count":83,"open_issues_count":4,"forks_count":28,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-06-27T23:06:01.764Z","etag":null,"topics":["consul","consul-locks","failover","golang","ha","health-check","high-availability","redis","redis-sentinel","sentinel"],"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/YotpoLtd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-25T07:38:11.000Z","updated_at":"2025-03-05T20:20:09.000Z","dependencies_parsed_at":"2022-08-07T13:15:53.400Z","dependency_job_id":null,"html_url":"https://github.com/YotpoLtd/resec","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/YotpoLtd/resec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YotpoLtd%2Fresec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YotpoLtd%2Fresec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YotpoLtd%2Fresec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YotpoLtd%2Fresec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YotpoLtd","download_url":"https://codeload.github.com/YotpoLtd/resec/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YotpoLtd%2Fresec/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262347483,"owners_count":23296895,"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","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":["consul","consul-locks","failover","golang","ha","health-check","high-availability","redis","redis-sentinel","sentinel"],"created_at":"2025-06-27T23:06:02.026Z","updated_at":"2025-06-27T23:06:02.785Z","avatar_url":"https://github.com/YotpoLtd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gitter](https://badges.gitter.im/redis-service-consul/Lobby.svg)](https://gitter.im/redis-service-consul/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge) [![Go Report Card](https://goreportcard.com/badge/github.com/YotpoLtd/resec)](https://goreportcard.com/report/github.com/YotpoLtd/resec) [![Build Status](https://travis-ci.org/YotpoLtd/resec.svg?branch=master)](https://travis-ci.org/YotpoLtd/resec)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://s.gravatar.com/avatar/96b073f48aae741171d137f21c849d84?s=160\" alt=\"Resec - Consul based highly available Redis replication agent\" /\u003e\n\u003c/p\u003e\n\n# Resec - Consul based highly available Redis replication agent\n\n## Description\n\nResec is a successor to [Redis Sentinel](https://redis.io/topics/sentinel) and [redishappy](https://github.com/mdevilliers/redishappy) for handling high availability failover for Redis.\n\nIt avoids Redis Sentinel problems of remembering all the sentinels and all the redis servers that ever appeared in the replication cluster.\n\nResec master election is based on [Consul Locks](https://www.consul.io/docs/commands/lock.html) to provide single redis master instance.\n\nResec continuously monitors the status of redis instance and if it's alive, It starts 2 following processes:\n* Monitor service of *master* for changes\n    * if lock is not acquired, on every change of master it runs *SLAVE OF `Master.Address`*\n* Trying to acquire lock to became master itself\n    * once lock acquired it stops watching for master service changes\n    * promotes redis to be *SLAVE OF NO ONE*\n\n### Services and health checks\nResec registers service with [TTL](https://www.consul.io/docs/agent/checkshtml#TTL) health check with TTL twice as big as `HEALTHCHECK_INTERVAL` and updates consul every `HEALTHCHECK_INTERVAL` to maintain service in passing state\n\nThere are 2 options to work with services:\n* Use `CONSUL_SERVICE_NAME` for tag based master/slave discovery\n  * `MASTER_TAGS` must be provided for ability to watch master instance for changes.\n* Use `CONSUL_SERVICE_PREFIX` for service name only based discovery\n  * services in consul will look like `CONSUL_SERVICE_PREFIX`-`Replication.Role`\n\n* If `ANNOUNCE_ADDR` is set it will be used for registration in consul, if it's not provided `REDIS_ADDR` will be used for registration in consul.\n  * If `REDIS_ADDR` is localhost, only port will be announced to the consul.\n\n### Redis Health\n* If redis becomes unhealthy resec will stop the leader election. As soon as redis will become healthy again, resec will start the operation from the beginning.\n\n## Usage\n\n### Environment variables\n\nEnvironment Variables |  Default       | Description\n----------------------| ---------------| -------------------------------------------------\nANNOUNCE_ADDR         |                | IP:Port of Redis to be announced, by default service will be registered wi\nCONSUL_SERVICE_NAME   |                | Consul service name for tag based service discovery\nCONSUL_SERVICE_PREFIX | redis          | Name Prefix, will be followed by \"-(master/slave)\", ignored if CONSUL_SERVICE_NAME is used\nCONSUL_LOCK_KEY       | resec/.lock    | KV lock location, should be overriden if multiple instances running in the same consul DC\nCONSUL_LOCK_SESSION_NAME       | resec | Lock session Name to distinguish multiple resec masters on one host\nCONSUL_LOCK_MONITOR_RETRIES | 3        | Number of retries of lock receives 500 Error from Consul\nCONSUL_LOCK_MONITOR_RETRY_INTERVAL | 1s | Retry interval if lock receives 500 Error from Consul\nCONSUL_DEREGISTER_SERVICE_AFTER | 72h  |\nCONSUL_LOCK_TTL       | 15s            |\nMASTER_TAGS           |                | Comma separated list of tags to be added to master instance. The first tag (index 0) is used to configure the role of the Redis/resec task, and *must* be different from index 0 in `SLAVE_TAGS`.\nSLAVE_TAGS            |                | Comma separated list of tags to be added to slave instance. The first tag (index 0) is used to configure the role of the Redis/resec task, and *must* be different from index 0 in `MASTER_TAGS`.\nHEALTHCHECK_INTERVAL  | 5s             |\nHEALTHCHECK_TIMEOUT   | 2s             |\nREDIS_ADDR            | 127.0.0.1:6379 |\nREDIS_PASSWORD        |                |\nLOG_LEVEL             | INFO           | Options are \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\"\n\n##### Environment variables to configure communication with consul are similar to [Consul CLI](https://www.consul.io/docs/commands/index.html#environment-variables)\n\n### Permissions\n\nResec requires permissions for Consul in order to function correctly.\nThe Consul ACL token is passed as the environment variable `CONSUL_HTTP_TOKEN` .\n\n#### Consul ACL Token Permissions\n\nIf the Consul cluster being used is running ACLs; the following ACL policy will allow Replicator the required access to perform all functions based on its default configuration:\n\n```hcl\nkey \"resec/\" {\n  policy = \"write\"\n}\nsession \"\" {\n  policy = \"write\"\n}\nservice \"\" {\n  policy = \"write\"\n}\n```\n\n### Run the application\n\n* with nomad:\n```hcl\njob \"resec\" {\n  datacenters = [\"dc1\"]\n  type        = \"service\"\n\n  update {\n    max_parallel = 1\n    stagger      = \"10s\"\n  }\n\n  group \"cache\" {\n    count = 3\n\n    task \"redis\" {\n      driver = \"docker\"\n      config {\n        image = \"redis:alpine\"\n        command = \"redis-server\"\n        args = [\n          \"/local/redis.conf\"\n        ]\n        port_map {\n          db = 6379\n        }\n      }\n      // Let Redis know how much memory he can use not to be killed by OOM\n      template {\n        data = \u003c\u003cEORC\nmaxmemory {{ env \"NOMAD_MEMORY_LIMIT\" | parseInt | subtract 16 }}mb\nEORC\n        destination   = \"local/redis.conf\"\n      }\n\n      resources {\n        cpu    = 500\n        memory = 256\n        network {\n          mbits = 10\n          port \"db\" {}\n        }\n      }\n    }\n\n    task \"resec\" {\n      driver = \"docker\"\n      config {\n        image = \"yotpo/resec\"\n      }\n\n      env {\n        CONSUL_HTTP_ADDR = \"http://${attr.unique.network.ip-address}:8500\"\n        REDIS_ADDR = \"${NOMAD_ADDR_redis_db}\"\n      }\n\n      resources {\n        cpu    = 100\n        memory = 64\n        network {\n          mbits = 10\n        }\n      }\n    }\n  }\n}\n```\n\n* with docker-compose.yml:\n\n```yaml\nresec:\n  image: yotpo/resec\n  environment:\n    - CONSUL_HTTP_ADDR=1.2.3.4:8500\n    - REDIS_ADDR=redis:6379\n  container_name: resec\n```\n\n* with SystemD:\n```\n[Unit]\nDescription=resec - redis ha replication daemon\nRequires=network-online.target\nAfter=network-online.target\n\n[Service]\nEnvironmentFile=-/etc/default/resec\nExecStart=/usr/local/bin/resec\nKillSignal=SIGQUIT\nRestart=on-failure\nRestartSec=5s\n\n[Install]\nWantedBy=multi-user.target\n\n```\n\n## Copyright and license\n\nCode released under the [MIT license](https://github.com/YotpoLtd/ReSeC/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyotpoltd%2Fresec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyotpoltd%2Fresec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyotpoltd%2Fresec/lists"}