{"id":75836,"date":"2025-09-09T11:26:46","date_gmt":"2025-09-09T05:56:46","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=75836"},"modified":"2025-09-09T14:49:14","modified_gmt":"2025-09-09T09:19:14","slug":"redis-cluster-backups-and-restoration","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/redis-cluster-backups-and-restoration\/","title":{"rendered":"Redis Cluster backups and restoration"},"content":{"rendered":"<h1>Redis Cluster backups to Amazon S3 <span style=\"font-size: 1.28571rem;\">using a single bash script and cron. It\u2019s safe, slot-aware (backs up every node you run it on), and waits for BGSAVE to finish before uploading.<\/span><\/h1>\n<h1>What this setup does<\/h1>\n<ul>\n<li>Runs on each Redis node, including masters and replicas, so you get a full cluster backup.<\/li>\n<li>It triggers BGSAVE, waits for the snapshot to finish, and then uploads your persistence files to S3:\n<ul>\n<li>dump.rdb<\/li>\n<li>appendonly.aof (if AOF or RDB+AOF is enabled)<\/li>\n<\/ul>\n<\/li>\n<li>It encrypts the data at rest in S3 using SSE-S3 or SSE-KMS. It also adds retention by using an S3 lifecycle rule and performs basic integrity checks.<\/li>\n<\/ul>\n<h2>Prerequisites (once per node)<\/h2>\n<ol>\n<li><strong>Install tools<\/strong><br \/>\napt-get update &amp;&amp; apt-get install -y awscli jq<br \/>\n# or: yum install -y awscli jq<\/li>\n<li><strong>AWS credentials on the node<\/strong><br \/>\nPrefer an EC2 instance profile role; otherwise configure aws configure.<\/li>\n<li><strong>IAM policy for the instance role<\/strong><br \/>\nGrant Put\/Get\/List to your chosen bucket, plus (optional) KMS encrypt:<\/li>\n<li><strong>Decide where Redis stores data<\/strong>\n<div id=\"attachment_75824\" style=\"width: 450px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75824\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-75824\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-41.png\" alt=\"Policy\" width=\"440\" height=\"145\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-41.png 619w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-41-300x99.png 300w\" sizes=\"(max-width: 440px) 100vw, 440px\" \/><p id=\"caption-attachment-75824\" class=\"wp-caption-text\">Policy<\/p><\/div>\n<p>Check redis.conf:<br \/>\n1. dir \/var\/lib\/redis<br \/>\n2. dbfilename dump.rdb<br \/>\n3. appendonly yes|no and appendfilename appendonly.aof<\/li>\n<li><strong>S3 bucket &amp; (optional) lifecycle<\/strong><br \/>\nCreate the bucket s3:\/\/your-redis-backups\/ and add a lifecycle rule. For example, keep the data for 30 days, then move it to Glacier or delete it.<\/li>\n<\/ol>\n<h2>2) Drop-in backup script<\/h2>\n<p>Save as \/usr\/local\/bin\/redis-cluster-backup.sh and make it executable.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"attachment_75828\" style=\"width: 628px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75828\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75828\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-42.png\" alt=\"Script\" width=\"618\" height=\"765\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-42.png 618w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-42-242x300.png 242w\" sizes=\"(max-width: 618px) 100vw, 618px\" \/><p id=\"caption-attachment-75828\" class=\"wp-caption-text\">Script page -1<\/p><\/div>\n<div id=\"attachment_75827\" style=\"width: 897px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75827\" decoding=\"async\" loading=\"lazy\" class=\" wp-image-75827\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43.png\" alt=\"Script\" width=\"887\" height=\"835\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43.png 968w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43-300x283.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43-768x724.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43-624x588.png 624w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-43-24x24.png 24w\" sizes=\"(max-width: 887px) 100vw, 887px\" \/><p id=\"caption-attachment-75827\" class=\"wp-caption-text\">Script page &#8211; 2<\/p><\/div>\n<div id=\"attachment_75826\" style=\"width: 906px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75826\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75826\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44.png\" alt=\"Script\" width=\"896\" height=\"876\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44.png 896w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44-300x293.png 300w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44-768x751.png 768w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44-624x610.png 624w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44-24x24.png 24w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-44-48x48.png 48w\" sizes=\"(max-width: 896px) 100vw, 896px\" \/><p id=\"caption-attachment-75826\" class=\"wp-caption-text\">Script page &#8211; 3<\/p><\/div>\n<h2>Optional: a small env file for easy overrides:-<\/h2>\n<p>Create \/etc\/redis-backup.env (owned &amp; readable by root only):<\/p>\n<div id=\"attachment_75830\" style=\"width: 556px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75830\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75830\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-45.png\" alt=\"env file\" width=\"546\" height=\"202\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-45.png 546w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-45-300x111.png 300w\" sizes=\"(max-width: 546px) 100vw, 546px\" \/><p id=\"caption-attachment-75830\" class=\"wp-caption-text\">env file<\/p><\/div>\n<p>Then call the script with:<\/p>\n<div id=\"attachment_75832\" style=\"width: 575px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75832\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75832\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-46.png\" alt=\"Cmd\" width=\"565\" height=\"30\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-46.png 565w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-46-300x16.png 300w\" sizes=\"(max-width: 565px) 100vw, 565px\" \/><p id=\"caption-attachment-75832\" class=\"wp-caption-text\">Cmd<\/p><\/div>\n<h2>3) Scheduling with <strong>Cron<\/strong><\/h2>\n<p>Run daily at 02:15 local time or at any specific time as per your need:<\/p>\n<div id=\"attachment_75833\" style=\"width: 633px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75833\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75833\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-47.png\" alt=\"Cron\" width=\"623\" height=\"50\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-47.png 623w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-47-300x24.png 300w\" sizes=\"(max-width: 623px) 100vw, 623px\" \/><p id=\"caption-attachment-75833\" class=\"wp-caption-text\">Cron<\/p><\/div>\n<h2>5) Restore (node or cluster)<\/h2>\n<p><strong>Standalone or single node (lab\/staging)<\/strong><\/p>\n<ol>\n<li>Stop Redis.<\/li>\n<li>Replace files in dir with your backup:\n<ol>\n<li>If restoring <strong>RDB(Redis Database File)<\/strong>: put the dump.rdb(point-in-time snapshot).<\/li>\n<li>If <strong>AOF(Append Only File)<\/strong> or <strong>mixed<\/strong>: put appendonly.aof (and ensure appendonly yes).<\/li>\n<\/ol>\n<\/li>\n<li>Start Redis \u2014 it loads whichever persistence you\u2019ve enabled.<\/li>\n<\/ol>\n<p><strong>Cluster restore (same topology)<\/strong><\/p>\n<ul>\n<li>Restore each node from its own backup (masters &amp; replicas).<\/li>\n<li>Start nodes; verify with:\n<p><div id=\"attachment_75834\" style=\"width: 568px\" class=\"wp-caption alignnone\"><img aria-describedby=\"caption-attachment-75834\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-75834\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-48.png\" alt=\"Redis\" width=\"558\" height=\"32\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-48.png 558w, \/blog\/wp-ttn-blog\/uploads\/2025\/09\/image-48-300x17.png 300w\" sizes=\"(max-width: 558px) 100vw, 558px\" \/><p id=\"caption-attachment-75834\" class=\"wp-caption-text\">Redis<\/p><\/div><\/li>\n<li>Ensure slot ownership and replication match your desired layout.(If you are re-creating a cluster from scratch, use cluster create with the master\/replica mapping and then restore files before opening to traffic.)<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Redis Cluster backups to Amazon S3 using a single bash script and cron. It\u2019s safe, slot-aware (backs up every node you run it on), and waits for BGSAVE to finish before uploading. What this setup does Runs on each Redis node, including masters and replicas, so you get a full cluster backup. It triggers BGSAVE, [&hellip;]<\/p>\n","protected":false},"author":2167,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":110},"categories":[5877],"tags":[8104,8105],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75836"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/2167"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=75836"}],"version-history":[{"count":4,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75836\/revisions"}],"predecessor-version":[{"id":76128,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/75836\/revisions\/76128"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=75836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=75836"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=75836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}